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 |
| v | Mark selection |
| x | Delete current character or selection |
| dd | Delete the current line |
| cw | Change word forward |
| cb | Change word backward |
** Insert mode
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();
}
pub fn word_scan_forward(&mut self) {
while self.cursor_pos < self.content.len_chars() {
self.cursor_pos += 1;
if !self
.current_char()
.map(|c| c.is_alphanumeric())
.unwrap_or(false)
pub fn get_word_scan_forward_position(&mut self, skip_first: bool) -> usize {
if self.cursor_pos < self.content.len_chars() {
for (idx, ch) in self
.content
.chars_at(self.cursor_pos)
.skip(if skip_first { 1 } else { 0 })
.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) {
if self.cursor_pos > 0 {
self.cursor_pos -= 1;
pub fn get_word_scan_backward_position(&mut self, skip_first: bool) -> usize {
let mut pos = self.cursor_pos;
if pos > 0 && skip_first {
pos -= 1;
}
while self.cursor_pos > 0 {
while pos > 0 {
if !self
.content
.get_char(self.cursor_pos - 1)
.get_char(pos - 1)
.map(|c| c.is_alphanumeric())
.unwrap_or(false)
{
break;
} 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) {
@ -265,6 +291,11 @@ impl EditorData {
self.deselect();
}
pub fn insert_mode(&mut self) {
self.mode = EditMode::Insert;
self.deselect();
}
pub fn select_all(&mut self) {
self.selection_pos = Some(0);
self.cursor_pos = self.content.len_chars();

View File

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