From f5b2c03f5aafb84fc781f8acef9f9d965d7e8d7e Mon Sep 17 00:00:00 2001 From: ynqa Date: Tue, 26 Mar 2024 07:43:40 +0900 Subject: [PATCH] rename to work_break_chars --- src/core/text_editor.rs | 54 +++++++++++++++++++--------------- src/core/text_editor/render.rs | 6 ++-- src/preset/query_selector.rs | 2 +- src/preset/readline.rs | 10 ++++--- src/preset/readline/keymap.rs | 16 ++++++---- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/core/text_editor.rs b/src/core/text_editor.rs index 47e14e38..0293c28b 100644 --- a/src/core/text_editor.rs +++ b/src/core/text_editor.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use crate::{ core::cursor::Cursor, grapheme::{Grapheme, Graphemes}, @@ -117,8 +119,8 @@ impl TextEditor { } } - /// Finds the nearest previous index of any character in `items` from the cursor position. - fn find_previous_nearest_index(&self, items: &[char]) -> usize { + /// Finds the nearest previous index of any character in `word_break_chars` from the cursor position. + fn find_previous_nearest_index(&self, word_break_chars: &HashSet) -> usize { let current_position = self.position(); self.text() .chars() @@ -126,32 +128,32 @@ impl TextEditor { .enumerate() .filter(|&(i, _)| i < current_position.saturating_sub(1)) .rev() - .find(|&(_, c)| items.contains(c)) + .find(|&(_, c)| word_break_chars.contains(c)) .map(|(i, _)| i + 1) .unwrap_or(0) } - /// Erases the text from the current cursor position to the nearest previous character in `items`. - pub fn erase_to_previous_nearest(&mut self, items: &[char]) { - let pos = self.find_previous_nearest_index(items); + /// Erases the text from the current cursor position to the nearest previous character in `word_break_chars`. + pub fn erase_to_previous_nearest(&mut self, word_break_chars: &HashSet) { + let pos = self.find_previous_nearest_index(word_break_chars); self.erase_to_position(pos); } - /// Moves the cursor to the nearest previous character in `items`. - pub fn move_to_previous_nearest(&mut self, items: &[char]) { - let pos = self.find_previous_nearest_index(items); + /// Moves the cursor to the nearest previous character in `word_break_chars`. + pub fn move_to_previous_nearest(&mut self, word_break_chars: &HashSet) { + let pos = self.find_previous_nearest_index(word_break_chars); self.0.move_to(pos); } - /// Finds the nearest next index of any character in `items` from the cursor position. - fn find_next_nearest_index(&self, items: &[char]) -> usize { + /// Finds the nearest next index of any character in `word_break_chars` from the cursor position. + fn find_next_nearest_index(&self, word_break_chars: &HashSet) -> usize { let current_position = self.position(); self.text() .chars() .iter() .enumerate() .filter(|&(i, _)| i > current_position) - .find(|&(_, c)| items.contains(c)) + .find(|&(_, c)| word_break_chars.contains(c)) .map(|(i, _)| { if i < self.0.contents().len() - 1 { i + 1 @@ -162,15 +164,15 @@ impl TextEditor { .unwrap_or(self.0.contents().len() - 1) } - /// Erases the text from the current cursor position to the nearest next character in `items`. - pub fn erase_to_next_nearest(&mut self, items: &[char]) { - let pos = self.find_next_nearest_index(items); + /// Erases the text from the current cursor position to the nearest next character in `word_break_chars`. + pub fn erase_to_next_nearest(&mut self, word_break_chars: &HashSet) { + let pos = self.find_next_nearest_index(word_break_chars); self.erase_to_position(pos); } - /// Moves the cursor to the nearest next character in `items`. - pub fn move_to_next_nearest(&mut self, items: &[char]) { - let pos = self.find_next_nearest_index(items); + /// Moves the cursor to the nearest next character in `word_break_chars`. + pub fn move_to_next_nearest(&mut self, word_break_chars: &HashSet) { + let pos = self.find_next_nearest_index(word_break_chars); self.0.move_to(pos); } @@ -269,38 +271,42 @@ mod test { } mod find_previous_nearest_index { + use std::collections::HashSet; + use crate::text_editor::test::new_with_position; #[test] fn test() { let mut txt = new_with_position(String::from("koko momo jojo "), 11); // indicate `o`. - assert_eq!(10, txt.find_previous_nearest_index(&[' '])); + assert_eq!(10, txt.find_previous_nearest_index(&HashSet::from([' ']))); txt.0.move_to(10); - assert_eq!(5, txt.find_previous_nearest_index(&[' '])); + assert_eq!(5, txt.find_previous_nearest_index(&HashSet::from([' ']))); } #[test] fn test_with_no_target() { let txt = new_with_position(String::from("koko momo jojo "), 7); // indicate `m`. - assert_eq!(0, txt.find_previous_nearest_index(&['z'])); + assert_eq!(0, txt.find_previous_nearest_index(&HashSet::from(['z']))); } } mod find_next_nearest_index { + use std::collections::HashSet; + use crate::text_editor::test::new_with_position; #[test] fn test() { let mut txt = new_with_position(String::from("koko momo jojo "), 7); // indicate `m`. - assert_eq!(10, txt.find_next_nearest_index(&[' '])); + assert_eq!(10, txt.find_next_nearest_index(&HashSet::from([' ']))); txt.0.move_to(10); - assert_eq!(14, txt.find_next_nearest_index(&[' '])); + assert_eq!(14, txt.find_next_nearest_index(&HashSet::from([' ']))); } #[test] fn test_with_no_target() { let txt = new_with_position(String::from("koko momo jojo "), 7); // indicate `m`. - assert_eq!(14, txt.find_next_nearest_index(&['z'])); + assert_eq!(14, txt.find_next_nearest_index(&HashSet::from(['z']))); } } diff --git a/src/core/text_editor/render.rs b/src/core/text_editor/render.rs index fe4274a1..c5b30ffa 100644 --- a/src/core/text_editor/render.rs +++ b/src/core/text_editor/render.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use crate::{ crossterm::style::ContentStyle, grapheme::{matrixify, StyledGraphemes}, @@ -36,8 +38,8 @@ pub struct Renderer { /// Current edit mode, determining whether input inserts or overwrites existing text. pub edit_mode: Mode, - /// Characters to be considered for nearest navigation. - pub nearest_characters: Vec, + /// Characters to be for word break. + pub word_break_chars: HashSet, /// Number of lines available for rendering. pub lines: Option, } diff --git a/src/preset/query_selector.rs b/src/preset/query_selector.rs index 441e96ba..84b5db2e 100644 --- a/src/preset/query_selector.rs +++ b/src/preset/query_selector.rs @@ -71,7 +71,7 @@ impl QuerySelector { active_char_style: StyleBuilder::new().bgc(Color::DarkCyan).build(), inactive_char_style: StyleBuilder::new().build(), edit_mode: Default::default(), - nearest_characters: Default::default(), + word_break_chars: Default::default(), lines: Default::default(), }, listbox_renderer: listbox::Renderer { diff --git a/src/preset/readline.rs b/src/preset/readline.rs index bc74b241..071c372a 100644 --- a/src/preset/readline.rs +++ b/src/preset/readline.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use crate::{ crossterm::{ event::Event, @@ -58,7 +60,7 @@ impl Default for Readline { active_char_style: StyleBuilder::new().bgc(Color::DarkCyan).build(), inactive_char_style: StyleBuilder::new().build(), edit_mode: Default::default(), - nearest_characters: vec![' '], + word_break_chars: HashSet::from([' ']), lines: Default::default(), }, suggest: Default::default(), @@ -145,9 +147,9 @@ impl Readline { self } - /// Sets the characters to be considered for nearest navigation. - pub fn nearest_characters(mut self, characters: Vec) -> Self { - self.text_editor_renderer.nearest_characters = characters; + /// Sets the characters to be for word break. + pub fn word_break_chars(mut self, characters: HashSet) -> Self { + self.text_editor_renderer.word_break_chars = characters; self } diff --git a/src/preset/readline/keymap.rs b/src/preset/readline/keymap.rs index c45f309b..189c1c66 100644 --- a/src/preset/readline/keymap.rs +++ b/src/preset/readline/keymap.rs @@ -8,7 +8,7 @@ use crate::{ /// /// | Key | Action /// | :--------------------- | :------------------------------------------- -/// | Enter | Exit the editor +/// | Enter | Exit the editor if input is valid, otherwise show error message /// | Ctrl + C | Interrupt the current operation /// | | Move the cursor one character to the left /// | | Move the cursor one character to the right @@ -18,7 +18,11 @@ use crate::{ /// | | Recall the next entry from history /// | Backspace | Delete the character before the cursor /// | Ctrl + U | Delete all characters in the current line -/// | TAB | Autocomplete the current input based on available suggestions +/// | Tab | Autocomplete the current input based on available suggestions +/// | Alt + B | Move the cursor to the previous nearest character within set (default: whitespace) +/// | Alt + F | Move the cursor to the next nearest character within set (default: whitespace) +/// | Ctrl + W | Erase to the previous nearest character within set (default: whitespace) +/// | Alt + D | Erase to the next nearest character within set (default: whitespace) pub fn default( event: &Event, renderer: &mut preset::readline::render::Renderer, @@ -127,7 +131,7 @@ pub fn default( state: KeyEventState::NONE, }) => text_editor_after_mut .texteditor - .move_to_previous_nearest(&text_editor_after_mut.nearest_characters), + .move_to_previous_nearest(&text_editor_after_mut.word_break_chars), Event::Key(KeyEvent { code: KeyCode::Char('f'), @@ -136,7 +140,7 @@ pub fn default( state: KeyEventState::NONE, }) => text_editor_after_mut .texteditor - .move_to_next_nearest(&text_editor_after_mut.nearest_characters), + .move_to_next_nearest(&text_editor_after_mut.word_break_chars), // Erase char(s). Event::Key(KeyEvent { @@ -160,7 +164,7 @@ pub fn default( state: KeyEventState::NONE, }) => text_editor_after_mut .texteditor - .erase_to_previous_nearest(&text_editor_after_mut.nearest_characters), + .erase_to_previous_nearest(&text_editor_after_mut.word_break_chars), Event::Key(KeyEvent { code: KeyCode::Char('d'), @@ -169,7 +173,7 @@ pub fn default( state: KeyEventState::NONE, }) => text_editor_after_mut .texteditor - .erase_to_next_nearest(&text_editor_after_mut.nearest_characters), + .erase_to_next_nearest(&text_editor_after_mut.word_break_chars), // Choose history Event::Key(KeyEvent {