Implemented Change Word
continuous-integration/drone/push Build is passing Details

Change word forward and backward were implemented in the editor_data
and bound in the editor to "cw" and "cb" respectively.

Scan word forward and scan word backward now utilize a shared function
that gets the scan position. This is now also used for delete word
forward/backward, so they can share logic

Updated keybinds in README
This commit is contained in:
Joe Bellus 2022-10-17 01:57:56 -04:00
parent e239573903
commit 3b6f7cdbf4
3 changed files with 62 additions and 16 deletions

View File

@ -32,6 +32,9 @@ In normal mode the cursor is a block and functional keybinds can be used for mov
| w | Scan forward a word | | w | Scan forward a word |
| v | Mark selection | | v | Mark selection |
| x | Delete current character or selection | | x | Delete current character or selection |
| dd | Delete the current line |
| cw | Change word forward |
| cb | Change word backward |
** Insert mode ** Insert mode
In insert mode the cursor is a line and text can be edited. To return to normal mode use the ESC key. In insert mode the cursor is a line and text can be edited. To return to normal mode use the ESC key.

View File

@ -104,37 +104,63 @@ impl EditorData {
self.deselect(); self.deselect();
} }
pub fn word_scan_forward(&mut self) { pub fn get_word_scan_forward_position(&mut self, skip_first: bool) -> usize {
while self.cursor_pos < self.content.len_chars() { if self.cursor_pos < self.content.len_chars() {
self.cursor_pos += 1; for (idx, ch) in self
if !self .content
.current_char() .chars_at(self.cursor_pos)
.map(|c| c.is_alphanumeric()) .skip(if skip_first { 1 } else { 0 })
.unwrap_or(false) .enumerate()
{ {
break; if !ch.is_alphanumeric() {
return (idx + self.cursor_pos + 2).min(self.content.len_chars());
}
} }
self.deselect(); self.content.len_chars()
} else {
self.content.len_chars()
} }
} }
pub fn word_scan_backward(&mut self) { pub fn get_word_scan_backward_position(&mut self, skip_first: bool) -> usize {
if self.cursor_pos > 0 { let mut pos = self.cursor_pos;
self.cursor_pos -= 1; if pos > 0 && skip_first {
pos -= 1;
} }
while self.cursor_pos > 0 { while pos > 0 {
if !self if !self
.content .content
.get_char(self.cursor_pos - 1) .get_char(pos - 1)
.map(|c| c.is_alphanumeric()) .map(|c| c.is_alphanumeric())
.unwrap_or(false) .unwrap_or(false)
{ {
break; break;
} else { } else {
self.cursor_pos -= 1; pos -= 1;
} }
self.deselect();
} }
pos
}
pub fn delete_word_forward(&mut self) {
let end = self.get_word_scan_forward_position(false);
self.content.remove(self.cursor_pos..end);
}
pub fn delete_word_backward(&mut self) {
let start = self.get_word_scan_backward_position(true);
self.content.remove(start..self.cursor_pos);
self.cursor_pos = start;
}
pub fn word_scan_forward(&mut self) {
self.cursor_pos = self.get_word_scan_forward_position(true);
self.deselect();
}
pub fn word_scan_backward(&mut self) {
self.cursor_pos = self.get_word_scan_backward_position(true);
self.deselect();
} }
pub fn delete_char_forward(&mut self) { pub fn delete_char_forward(&mut self) {
@ -265,6 +291,11 @@ impl EditorData {
self.deselect(); self.deselect();
} }
pub fn insert_mode(&mut self) {
self.mode = EditMode::Insert;
self.deselect();
}
pub fn select_all(&mut self) { pub fn select_all(&mut self) {
self.selection_pos = Some(0); self.selection_pos = Some(0);
self.cursor_pos = self.content.len_chars(); self.cursor_pos = self.content.len_chars();

View File

@ -36,6 +36,8 @@ mod keymap {
pub const WORD_FORWARD: &str = "w"; pub const WORD_FORWARD: &str = "w";
pub const WORD_BACK: &str = "b"; pub const WORD_BACK: &str = "b";
pub const SELECT_MODE: &str = "v"; pub const SELECT_MODE: &str = "v";
pub const CHANGE_WORD_FORWARD: &str = "cw";
pub const CHANGE_WORD_BACKWARD: &str = "cb";
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct KeyList { pub struct KeyList {
@ -63,6 +65,8 @@ mod keymap {
WORD_FORWARD, WORD_FORWARD,
WORD_BACK, WORD_BACK,
SELECT_MODE, SELECT_MODE,
CHANGE_WORD_FORWARD,
CHANGE_WORD_BACKWARD,
], ],
} }
} }
@ -360,6 +364,14 @@ impl Widget<EditorData> for AbacusEditor {
Some(keymap::SELECT_MODE) => { Some(keymap::SELECT_MODE) => {
data.selection_pos = Some(data.cursor_pos); data.selection_pos = Some(data.cursor_pos);
} }
Some(keymap::CHANGE_WORD_FORWARD) => {
data.delete_word_forward();
data.insert_mode();
}
Some(keymap::CHANGE_WORD_BACKWARD) => {
data.delete_word_backward();
data.insert_mode();
}
_ => {} _ => {}
} }
} }