diff --git a/src/buffer/find.rs b/src/buffer/find.rs index 3a6f6ba..af8c5dc 100644 --- a/src/buffer/find.rs +++ b/src/buffer/find.rs @@ -16,7 +16,7 @@ impl Buffer { } for row in 0..self.get_line_count() { - let line = self.get_line(row).clone(); + let line = self.get_line(row).unwrap().clone(); if text.len() <= line.len() { let column_end = line.len() - text.len() + 1; for column in 0..column_end { diff --git a/src/buffer/helper.rs b/src/buffer/helper.rs index 655f160..62ed9dd 100644 --- a/src/buffer/helper.rs +++ b/src/buffer/helper.rs @@ -3,31 +3,26 @@ use std::cmp::min; use crate::buffer::{Buffer, BufferMode}; impl Buffer { - pub fn get_line_visible_text(&self, row: usize) -> Option { - if self.get_line_count() <= row { - return None; - } - - let line = self.get_line(row); - + pub fn get_line_visible_text(&self, row: usize) -> Result { + let line = self.get_line(row)?; let start_index = self.scroll.x; if line.len() <= start_index { - return Some(String::new()); + return Ok(String::new()); } let end_index = min(line.len(), self.scroll.x + (self.text_area.width as usize)); - Some(line[start_index..end_index].to_string()) + Ok(line[start_index..end_index].to_string()) } - pub fn get_line_max_cursor_x(&self, row: usize) -> usize { - let line_length = self.get_line(row).len(); + pub fn get_line_max_cursor_x(&self, row: usize) -> Result { + let line_length = self.get_line(row)?.len(); if line_length == 0 { - 0 + Ok(0) } else if let BufferMode::Insert = self.mode { - line_length + Ok(line_length) } else { - line_length - 1 + Ok(line_length - 1) } } } diff --git a/src/buffer/mode.rs b/src/buffer/mode.rs index c520495..3bd7ea3 100644 --- a/src/buffer/mode.rs +++ b/src/buffer/mode.rs @@ -38,7 +38,6 @@ impl Buffer { pub fn enter_insert_mode_end(&mut self) { self.enter_insert_mode(); self.move_last_column(); - self.move_right(); } pub fn enter_visual_mode(&mut self) { diff --git a/src/buffer/movement.rs b/src/buffer/movement.rs index d022919..799b6cd 100644 --- a/src/buffer/movement.rs +++ b/src/buffer/movement.rs @@ -10,7 +10,7 @@ use crate::{ impl Buffer { pub fn move_cursor(&mut self, row: usize, column: usize) { self.cursor.y = min(row, self.get_line_count() - 1); - self.cursor.x = min(column, self.get_line_max_cursor_x(self.cursor.y)); + self.cursor.x = min(column, self.get_line_max_cursor_x(self.cursor.y).unwrap()); if self.cursor.x < self.scroll.x { self.scroll.x = self.cursor.x @@ -58,7 +58,7 @@ impl Buffer { } pub fn move_last_column(&mut self) { - self.move_cursor(self.cursor.y, self.get_line_max_cursor_x(self.cursor.y)); + self.move_cursor(self.cursor.y, self.get_line_max_cursor_x(self.cursor.y).unwrap()); } pub fn move_previous_word(&mut self) { diff --git a/src/buffer/operations.rs b/src/buffer/operations.rs index da301f1..7e5aa6a 100644 --- a/src/buffer/operations.rs +++ b/src/buffer/operations.rs @@ -2,61 +2,79 @@ use crate::buffer::Buffer; impl Buffer { pub fn insert_char(&mut self, ch: char) { - self.insert_char_to(self.cursor.y, self.cursor.x, ch); + let row = self.cursor.y; + let column = self.cursor.x; + self.insert_char_to(row, column, ch).unwrap(); } - pub fn insert_char_to(&mut self, row: usize, column: usize, ch: char) { - let line = self.get_line_mut(row); + pub fn insert_char_to(&mut self, row: usize, column: usize, ch: char) -> Result<(), String> { + let line = self.get_line_mut(row)?; + + if column > line.len() { + return Err(format!( + "Can not insert char at {} (line: {})", + column, + row + 1 + )); + } + line.insert(column, ch); self.move_cursor(row, column + 1); + + Ok(()) } pub fn delete_char(&mut self) { - self.delete_char_from(self.cursor.y, self.cursor.x); + self.delete_char_from(self.cursor.y, self.cursor.x).unwrap(); } - pub fn delete_char_from(&mut self, row: usize, column: usize) { - let line = self.get_line_mut(row); - if line.len() == 0 { - return; - } else if line.len() == column { + pub fn delete_char_from(&mut self, row: usize, column: usize) -> Result<(), String> { + let line = self.get_line_mut(row)?; + if line.len() == column { if row + 1 < self.get_line_count() { - self.join_lines(row, row + 1); + self.join_lines(row, row + 1).unwrap(); } + } else if column > line.len() { + return Err(format!("No column at {} (line: {})", column, row + 1)); } else { line.remove(column); self.move_cursor(row, column); self.set_size(self.area.clone()); } + + Ok(()) } - pub fn delete_char_before(&mut self, row: usize, column: usize) { + pub fn delete_char_before(&mut self, row: usize, column: usize) -> Result<(), String> { if row == 0 && column == 0 { - return; + return Ok(()); } if column == 0 { self.move_up(); self.move_last_column(); - self.join_lines(row - 1, row); + self.join_lines(row - 1, row)?; } else { self.move_left(); self.delete_char(); } + + Ok(()) } pub fn delete_char_before_cursor(&mut self) { - self.delete_char_before(self.cursor.y, self.cursor.x); + self.delete_char_before(self.cursor.y, self.cursor.x) + .unwrap(); } - pub fn insert_line(&mut self, row: usize) { + fn insert_line(&mut self, row: usize) { self.lines.insert(row, String::new()); self.set_size(self.area.clone()); } pub fn open_new_line_previous(&mut self) { - let row = self.cursor.y + 1; + let row = self.cursor.y; self.insert_line(row); self.move_cursor(row, 0); } @@ -67,8 +85,11 @@ impl Buffer { self.move_cursor(row, 0); } - pub fn split_line(&mut self, row: usize, column: usize) { - let line = self.get_line(row); + pub fn split_line(&mut self, row: usize, column: usize) -> Result<(), String> { + let line = self.get_line(row)?; + if column > line.len() { + return Err(format!("No column at {} (line: {})", column, row + 1)); + } let (left, right) = line.split_at(column); let left_string = left.to_string(); @@ -79,23 +100,27 @@ impl Buffer { self.move_cursor(row + 1, 0); self.set_size(self.area.clone()); + + Ok(()) } pub fn split_line_cursor(&mut self) { - self.split_line(self.cursor.y, self.cursor.x); + self.split_line(self.cursor.y, self.cursor.x).unwrap(); } - pub fn join_lines(&mut self, row1: usize, row2: usize) { - let line2 = self.get_line(row2).clone(); - let line1 = self.get_line_mut(row1); + pub fn join_lines(&mut self, row1: usize, row2: usize) -> Result<(), String> { + let line2 = self.get_line(row2)?.clone(); + let line1 = self.get_line_mut(row1)?; line1.push_str(&line2); self.lines.remove(row2); self.set_size(self.area.clone()); + + Ok(()) } pub fn join_lines_cursor(&mut self) { if self.cursor.y < self.get_line_count() - 1 { - self.join_lines(self.cursor.y, self.cursor.y + 1); + self.join_lines(self.cursor.y, self.cursor.y + 1).unwrap(); } } } diff --git a/src/buffer/text.rs b/src/buffer/text.rs index f3bd656..d8b97c6 100644 --- a/src/buffer/text.rs +++ b/src/buffer/text.rs @@ -1,24 +1,30 @@ use crate::buffer::Buffer; impl Buffer { - pub fn get_line(&self, row: usize) -> &String { - self.lines.get(row).unwrap() + pub fn get_line(&self, row: usize) -> Result<&String, String> { + match self.lines.get(row) { + Some(line) => Ok(line), + None => Err(format!("No line at {}", row)), + } } - pub fn get_line_mut(&mut self, row: usize) -> &mut String { - self.lines.get_mut(row).unwrap() + pub fn get_line_mut(&mut self, row: usize) -> Result<&mut String, String> { + match self.lines.get_mut(row) { + Some(line) => Ok(line), + None => Err(format!("No line at {}", row)), + } } pub fn get_current_line(&self) -> &String { - self.get_line(self.cursor.y) + self.get_line(self.cursor.y).unwrap() } pub fn get_current_line_mut(&mut self) -> &mut String { - self.get_line_mut(self.cursor.y) + self.get_line_mut(self.cursor.y).unwrap() } - pub fn get_line_text_length(&self, row: usize) -> usize { - self.get_line(row).len() + pub fn get_line_text_length(&self, row: usize) -> Result { + Ok(self.get_line(row)?.len()) } pub fn get_current_line_text_length(&self) -> usize { @@ -26,7 +32,7 @@ impl Buffer { } pub fn get_line_last_char_index(&self, row: usize) -> Option { - match self.get_line_text_length(row) { + match self.get_line_text_length(row).unwrap() { 0 => None, length => Some(length - 1), } diff --git a/src/commands/find_file.rs b/src/commands/find_file.rs index 51ca6ed..91bbe26 100644 --- a/src/commands/find_file.rs +++ b/src/commands/find_file.rs @@ -75,7 +75,7 @@ impl FindFileCommand { textbox_popup.actions_insert.insert("enter", |editor| { let buffer = editor.get_active_buffer(); let popup = buffer.popups.get(buffer.popups.len() - 2).unwrap(); - let filename = popup.get_line(popup.cursor.y); + let filename = popup.get_current_line(); editor.input.text = format!("e {}", filename).to_string(); let buffer = editor.get_active_buffer_mut(); diff --git a/src/screen/print_buffer.rs b/src/screen/print_buffer.rs index e40e14d..f9a0a3a 100644 --- a/src/screen/print_buffer.rs +++ b/src/screen/print_buffer.rs @@ -88,7 +88,7 @@ impl Screen { for y in 0..buffer.area.height { let row_index = buffer.scroll.y + y as usize; match buffer.get_line_visible_text(row_index) { - Some(text) => { + Ok(text) => { // TODO: Move this and print in separate functions if buffer.options.show_info_column { self.print_text( @@ -109,7 +109,7 @@ impl Screen { Style::new(T.text_fg, T.text_bg), ); } - None => { + Err(_) => { if buffer.options.show_info_column { self.print_text( buffer.area.y + y,