impl super::CodeEditor {
pub fn cursor_position(&self) -> (usize, usize) {
self.cursor
}
pub fn set_cursor(&mut self, line: usize, col: usize) {
let line = line.min(self.lines.len().saturating_sub(1));
let col = col.min(self.line_len(line));
self.cursor = (line, col);
self.ensure_cursor_visible();
}
pub fn line_count(&self) -> usize {
self.lines.len()
}
pub(super) fn line_len(&self, line: usize) -> usize {
self.lines.get(line).map(|l| l.len()).unwrap_or(0)
}
pub fn move_left(&mut self) {
if self.cursor.1 > 0 {
self.cursor.1 -= 1;
} else if self.cursor.0 > 0 {
self.cursor.0 -= 1;
self.cursor.1 = self.line_len(self.cursor.0);
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_right(&mut self) {
let line_len = self.line_len(self.cursor.0);
if self.cursor.1 < line_len {
self.cursor.1 += 1;
} else if self.cursor.0 + 1 < self.lines.len() {
self.cursor.0 += 1;
self.cursor.1 = 0;
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_up(&mut self) {
if self.cursor.0 > 0 {
self.cursor.0 -= 1;
self.cursor.1 = self.cursor.1.min(self.line_len(self.cursor.0));
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_down(&mut self) {
if self.cursor.0 + 1 < self.lines.len() {
self.cursor.0 += 1;
self.cursor.1 = self.cursor.1.min(self.line_len(self.cursor.0));
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_home(&mut self) {
let line = &self.lines[self.cursor.0];
let first_non_ws = line.chars().position(|c| !c.is_whitespace()).unwrap_or(0);
if self.cursor.1 == first_non_ws || self.cursor.1 == 0 {
self.cursor.1 = if self.cursor.1 == 0 { first_non_ws } else { 0 };
} else {
self.cursor.1 = first_non_ws;
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_end(&mut self) {
self.cursor.1 = self.line_len(self.cursor.0);
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_document_start(&mut self) {
self.cursor = (0, 0);
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_document_end(&mut self) {
let last_line = self.lines.len().saturating_sub(1);
self.cursor = (last_line, self.line_len(last_line));
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_word_left(&mut self) {
if self.cursor.1 == 0 {
if self.cursor.0 > 0 {
self.cursor.0 -= 1;
self.cursor.1 = self.line_len(self.cursor.0);
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
return;
}
let line = &self.lines[self.cursor.0];
let chars: Vec<char> = line.chars().collect();
let mut col = self.cursor.1.min(chars.len());
while col > 0 && chars[col - 1].is_whitespace() {
col -= 1;
}
while col > 0 && !chars[col - 1].is_whitespace() {
col -= 1;
}
self.cursor.1 = col;
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn move_word_right(&mut self) {
let line = &self.lines[self.cursor.0];
let chars: Vec<char> = line.chars().collect();
let mut col = self.cursor.1;
if col >= chars.len() {
if self.cursor.0 + 1 < self.lines.len() {
self.cursor.0 += 1;
self.cursor.1 = 0;
}
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
return;
}
while col < chars.len() && !chars[col].is_whitespace() {
col += 1;
}
while col < chars.len() && chars[col].is_whitespace() {
col += 1;
}
self.cursor.1 = col;
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn page_up(&mut self, page_size: usize) {
self.cursor.0 = self.cursor.0.saturating_sub(page_size);
self.cursor.1 = self.cursor.1.min(self.line_len(self.cursor.0));
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub fn page_down(&mut self, page_size: usize) {
self.cursor.0 = (self.cursor.0 + page_size).min(self.lines.len().saturating_sub(1));
self.cursor.1 = self.cursor.1.min(self.line_len(self.cursor.0));
if self.anchor.is_none() {
self.clear_selection();
}
self.ensure_cursor_visible();
}
pub(super) fn ensure_cursor_visible(&mut self) {
if self.cursor.0 < self.scroll.0 {
self.scroll.0 = self.cursor.0;
}
}
}