diff --git a/src/buffer/clipboard.rs b/src/buffer/clipboard.rs index cad4572..c92061e 100644 --- a/src/buffer/clipboard.rs +++ b/src/buffer/clipboard.rs @@ -45,7 +45,7 @@ impl Buffer { is_first = false; } else { self.split_line_at_after_cursor(); - let _ = self.insert_str_to(self.cursor.y, 0, line); + self.insert_str_at_cursor(line); } } } diff --git a/src/buffer/operations.rs b/src/buffer/operations.rs index 618a1b2..c839bb5 100644 --- a/src/buffer/operations.rs +++ b/src/buffer/operations.rs @@ -45,24 +45,35 @@ impl Buffer { )); } line.insert_str(column, text); - self.move_cursor(row, column + text.len().checked_sub(1).unwrap_or(0)); Ok(()) } pub fn insert_str_at_cursor(&mut self, text: &str) { - self.insert_str_to(self.cursor.y, self.cursor.x, text) - .unwrap() + let row = self.cursor.y; + let column = self.cursor.x; + self.insert_str_to(row, column, text).unwrap(); + self.move_cursor(row, column + text.len().checked_sub(1).unwrap_or(0)); } pub fn insert_str_at_after_cursor(&mut self, text: &str) { if self.get_current_line_text_length() == 0 { self.insert_str_at_cursor(text); } else { - self.insert_str_to(self.cursor.y, self.cursor.x + 1, text) - .unwrap(); + let row = self.cursor.y; + let column = self.cursor.x; + self.insert_str_to(row, column + 1, text).unwrap(); + self.move_cursor(row, column + text.len()); } } + pub fn insert_whitespace_at_cursor(&mut self) { + let row = self.cursor.y; + let column = self.cursor.x; + let text = self.options.get_whitespace_chars(); + self.insert_str_to(row, column, &text).unwrap(); + self.move_cursor(self.cursor.y, column + text.len()); + } + pub fn delete_char_from(&mut self, row: usize, column: usize) -> Result<(), String> { let line = self.get_line_mut(row)?; if line.len() == column { diff --git a/src/buffer/options.rs b/src/buffer/options.rs index c66d329..6a6100e 100644 --- a/src/buffer/options.rs +++ b/src/buffer/options.rs @@ -1,9 +1,16 @@ use std::collections::HashMap; +pub enum TabMode { + Space, + Tab, +} + pub struct BufferOptions { pub show_info_column: bool, pub show_border: bool, pub chars: HashMap, + pub tab_mode: TabMode, + pub tabstop: u8, } impl Default for BufferOptions { @@ -12,8 +19,25 @@ impl Default for BufferOptions { show_info_column: true, show_border: false, chars: HashMap::new(), + tab_mode: TabMode::Space, + tabstop: 4, }; options.chars.insert(' ', '•'); options } } + +impl BufferOptions { + pub fn get_whitespace_chars(&self) -> String { + let mut chars = String::new(); + match self.tab_mode { + TabMode::Space => { + for _ in 0..self.tabstop { + chars.push(' '); + } + } + TabMode::Tab => chars.push('\t'), + } + chars + } +} diff --git a/src/buffer/text.rs b/src/buffer/text.rs index 7994755..d174bc9 100644 --- a/src/buffer/text.rs +++ b/src/buffer/text.rs @@ -65,7 +65,7 @@ impl Buffer { let mut result: Vec = Vec::new(); let mut reader = TextReader::new(&self.lines); - let _ = reader.set_cursor(from); + reader.set_cursor(from).unwrap(); while reader.get_cursor() <= to { let mut line = String::new(); diff --git a/src/editor.rs b/src/editor.rs index 41aa9c2..769d423 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -112,7 +112,10 @@ impl Editor { BufferMode::Insert => match buffer.actions_insert.get(&key.to_string().as_str()) { Some(action) => action(self), None => { - if !key.ctrl && !key.win && !key.alt && key.code.len() == 1 { + if key.to_string() == "tab" { + self.get_active_buffer_or_popup_mut() + .insert_whitespace_at_cursor(); + } else if !key.ctrl && !key.win && !key.alt && key.code.len() == 1 { let ch = key.code.chars().nth(0).unwrap(); buffer.insert_char_at_cursor(ch); }