From 431d2ab65640cf1724d72e5e63442a3ae69f570f Mon Sep 17 00:00:00 2001 From: Stefan Holderbach Date: Sat, 5 Nov 2022 23:07:57 +0100 Subject: [PATCH] Fix the additional moves of normal mode `hjkl` (#510) * Fix the additional moves of normal mode `hjkl` Fixes nushell/nushell#6991 Allows using `l` to complete the history hint in normal mode Support menu navigation with `hjkl` in vi normal mode Adjusts tests * Fix clippy Parameter only used in recursion --- src/edit_mode/vi/motion.rs | 21 +++++++++++++++++---- src/edit_mode/vi/parser.rs | 38 +++++++++++++++++++++++++------------- src/engine.rs | 10 +++------- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/edit_mode/vi/motion.rs b/src/edit_mode/vi/motion.rs index 09ee9b2..90822a5 100644 --- a/src/edit_mode/vi/motion.rs +++ b/src/edit_mode/vi/motion.rs @@ -143,10 +143,23 @@ pub enum Motion { impl Motion { pub fn to_reedline(&self, vi_state: &mut Vi) -> Vec { match self { - Motion::Left => vec![ReedlineOption::Event(ReedlineEvent::Left)], - Motion::Right => vec![ReedlineOption::Event(ReedlineEvent::Right)], - Motion::Up => vec![ReedlineOption::Event(ReedlineEvent::Up)], - Motion::Down => vec![ReedlineOption::Event(ReedlineEvent::Down)], + Motion::Left => vec![ReedlineOption::Event(ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuLeft, + ReedlineEvent::Left, + ]))], + Motion::Right => vec![ReedlineOption::Event(ReedlineEvent::UntilFound(vec![ + ReedlineEvent::HistoryHintComplete, + ReedlineEvent::MenuRight, + ReedlineEvent::Right, + ]))], + Motion::Up => vec![ReedlineOption::Event(ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuUp, + ReedlineEvent::Up, + ]))], + Motion::Down => vec![ReedlineOption::Event(ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuDown, + ReedlineEvent::Down, + ]))], Motion::NextWord => vec![ReedlineOption::Edit(EditCommand::MoveWordRightStart)], Motion::NextBigWord => vec![ReedlineOption::Edit(EditCommand::MoveBigWordRightStart)], Motion::NextWordEnd => vec![ReedlineOption::Edit(EditCommand::MoveWordRightEnd)], diff --git a/src/edit_mode/vi/parser.rs b/src/edit_mode/vi/parser.rs index d533dca..f243e53 100644 --- a/src/edit_mode/vi/parser.rs +++ b/src/edit_mode/vi/parser.rs @@ -406,24 +406,36 @@ mod tests { } #[rstest] - #[case(&['2', 'k'], ReedlineEvent::Multiple(vec![ReedlineEvent::Up, ReedlineEvent::Up]))] - #[case(&['k'], ReedlineEvent::Multiple(vec![ReedlineEvent::Up]))] + #[case(&['2', 'k'], ReedlineEvent::Multiple(vec![ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuUp, + ReedlineEvent::Up, + ]), ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuUp, + ReedlineEvent::Up, + ])]))] + #[case(&['k'], ReedlineEvent::Multiple(vec![ReedlineEvent::UntilFound(vec![ + ReedlineEvent::MenuUp, + ReedlineEvent::Up, + ])]))] #[case(&['w'], ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![EditCommand::MoveWordRightStart])]))] #[case(&['W'], ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![EditCommand::MoveBigWordRightStart])]))] - #[case(&['2', 'j'], ReedlineEvent::Multiple(vec![ReedlineEvent::Down, ReedlineEvent::Down]))] - #[case(&['j'], ReedlineEvent::Multiple(vec![ReedlineEvent::Down]))] #[case(&['2', 'l'], ReedlineEvent::Multiple(vec![ - ReedlineEvent::Right, - ReedlineEvent::Right - ]))] - #[case(&['l'], ReedlineEvent::Multiple(vec![ReedlineEvent::Right]))] - #[case(&['2', 'h'], ReedlineEvent::Multiple(vec![ - ReedlineEvent::Left, - ReedlineEvent::Left, - ]))] - #[case(&['h'], ReedlineEvent::Multiple(vec![ReedlineEvent::Left]))] + ReedlineEvent::UntilFound(vec![ + ReedlineEvent::HistoryHintComplete, + ReedlineEvent::MenuRight, + ReedlineEvent::Right, + ]),ReedlineEvent::UntilFound(vec![ + ReedlineEvent::HistoryHintComplete, + ReedlineEvent::MenuRight, + ReedlineEvent::Right, + ]) ]))] + #[case(&['l'], ReedlineEvent::Multiple(vec![ReedlineEvent::UntilFound(vec![ + ReedlineEvent::HistoryHintComplete, + ReedlineEvent::MenuRight, + ReedlineEvent::Right, + ])]))] #[case(&['0'], ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![EditCommand::MoveToLineStart])]))] #[case(&['$'], ReedlineEvent::Multiple(vec![ReedlineEvent::Edit(vec![EditCommand::MoveToLineEnd])]))] #[case(&['i'], ReedlineEvent::Multiple(vec![ReedlineEvent::Repaint]))] diff --git a/src/engine.rs b/src/engine.rs index dd143f0..8ead6f3 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -581,21 +581,17 @@ impl Reedline { fn handle_event(&mut self, prompt: &dyn Prompt, event: ReedlineEvent) -> Result { if self.input_mode == InputMode::HistorySearch { - self.handle_history_search_event(prompt, event) + self.handle_history_search_event(event) } else { self.handle_editor_event(prompt, event) } } - fn handle_history_search_event( - &mut self, - prompt: &dyn Prompt, - event: ReedlineEvent, - ) -> io::Result { + fn handle_history_search_event(&mut self, event: ReedlineEvent) -> io::Result { match event { ReedlineEvent::UntilFound(events) => { for event in events { - match self.handle_history_search_event(prompt, event)? { + match self.handle_history_search_event(event)? { EventStatus::Inapplicable => { // Try again with the next event handler }