diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 79b62e23..2563880b 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -1091,27 +1091,18 @@ fn extend_next_long_word_end(cx: &mut Context) { extend_word_impl(cx, movement::move_next_long_word_end) } -fn will_find_char( - cx: &mut Context, - search_fn: F, - inclusive: bool, - extend: bool, - pseudo_pending: &str, -) where +fn will_find_char(cx: &mut Context, search_fn: F, inclusive: bool, extend: bool) +where F: Fn(RopeSlice, char, usize, usize, bool) -> Option + 'static, { // TODO: count is reset to 1 before next key so we move it into the closure here. // Would be nice to carry over. let count = cx.count(); - cx.editor.pseudo_pending = Some(pseudo_pending.to_string()); - // need to wait for next key // TODO: should this be done by grapheme rather than char? For example, // we can't properly handle the line-ending CRLF case here in terms of char. cx.on_next_key(move |cx, event| { - cx.editor.pseudo_pending = None; - let ch = match event { KeyEvent { code: KeyCode::Enter, @@ -1214,35 +1205,35 @@ fn find_prev_char_impl( } fn find_till_char(cx: &mut Context) { - will_find_char(cx, find_next_char_impl, false, false, "t") + will_find_char(cx, find_next_char_impl, false, false) } fn find_next_char(cx: &mut Context) { - will_find_char(cx, find_next_char_impl, true, false, "f") + will_find_char(cx, find_next_char_impl, true, false) } fn extend_till_char(cx: &mut Context) { - will_find_char(cx, find_next_char_impl, false, true, "t") + will_find_char(cx, find_next_char_impl, false, true) } fn extend_next_char(cx: &mut Context) { - will_find_char(cx, find_next_char_impl, true, true, "f") + will_find_char(cx, find_next_char_impl, true, true) } fn till_prev_char(cx: &mut Context) { - will_find_char(cx, find_prev_char_impl, false, false, "T") + will_find_char(cx, find_prev_char_impl, false, false) } fn find_prev_char(cx: &mut Context) { - will_find_char(cx, find_prev_char_impl, true, false, "F") + will_find_char(cx, find_prev_char_impl, true, false) } fn extend_till_prev_char(cx: &mut Context) { - will_find_char(cx, find_prev_char_impl, false, true, "T") + will_find_char(cx, find_prev_char_impl, false, true) } fn extend_prev_char(cx: &mut Context) { - will_find_char(cx, find_prev_char_impl, true, true, "F") + will_find_char(cx, find_prev_char_impl, true, true) } fn repeat_last_motion(cx: &mut Context) { @@ -4392,7 +4383,6 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { cx.on_next_key(move |cx, event| { cx.editor.autoinfo = None; - cx.editor.pseudo_pending = None; if let Some(ch) = event.char() { let textobject = move |editor: &mut Editor| { let (view, doc) = current!(editor); @@ -4441,33 +4431,31 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { } }); - if let Some((title, abbrev)) = match objtype { - textobject::TextObject::Inside => Some(("Match inside", "mi")), - textobject::TextObject::Around => Some(("Match around", "ma")), + let title = match objtype { + textobject::TextObject::Inside => "Match inside", + textobject::TextObject::Around => "Match around", _ => return, - } { - let help_text = [ - ("w", "Word"), - ("W", "WORD"), - ("p", "Paragraph"), - ("c", "Class (tree-sitter)"), - ("f", "Function (tree-sitter)"), - ("a", "Argument/parameter (tree-sitter)"), - ("o", "Comment (tree-sitter)"), - ("t", "Test (tree-sitter)"), - ("m", "Closest surrounding pair to cursor"), - (" ", "... or any character acting as a pair"), - ]; - - cx.editor.autoinfo = Some(Info::new( - title, - help_text - .into_iter() - .map(|(col1, col2)| (col1.to_string(), col2.to_string())) - .collect(), - )); - cx.editor.pseudo_pending = Some(abbrev.to_string()); }; + let help_text = [ + ("w", "Word"), + ("W", "WORD"), + ("p", "Paragraph"), + ("c", "Class (tree-sitter)"), + ("f", "Function (tree-sitter)"), + ("a", "Argument/parameter (tree-sitter)"), + ("o", "Comment (tree-sitter)"), + ("t", "Test (tree-sitter)"), + ("m", "Closest surrounding pair to cursor"), + (" ", "... or any character acting as a pair"), + ]; + + cx.editor.autoinfo = Some(Info::new( + title, + help_text + .into_iter() + .map(|(col1, col2)| (col1.to_string(), col2.to_string())) + .collect(), + )); } fn surround_add(cx: &mut Context) { diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index e5dc3c95..97639ff2 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -33,6 +33,7 @@ use super::statusline; pub struct EditorView { pub keymaps: Keymaps, on_next_key: Option>, + pseudo_pending: Vec, last_insert: (commands::MappableCommand, Vec), pub(crate) completion: Option, spinners: ProgressSpinners, @@ -56,6 +57,7 @@ impl EditorView { Self { keymaps, on_next_key: None, + pseudo_pending: Vec::new(), last_insert: (commands::MappableCommand::normal_mode, Vec::new()), completion: None, spinners: ProgressSpinners::default(), @@ -839,6 +841,7 @@ impl EditorView { event: KeyEvent, ) -> Option { let mut last_mode = mode; + self.pseudo_pending.extend(self.keymaps.pending()); let key_result = self.keymaps.get(mode, event); cxt.editor.autoinfo = self.keymaps.sticky().map(|node| node.infobox()); @@ -1316,6 +1319,11 @@ impl Component for EditorView { } self.on_next_key = cx.on_next_key_callback.take(); + match self.on_next_key { + Some(_) => self.pseudo_pending.push(key), + None => self.pseudo_pending.clear(), + } + // appease borrowck let callback = cx.callback.take(); @@ -1416,8 +1424,8 @@ impl Component for EditorView { for key in self.keymaps.pending() { disp.push_str(&key.key_sequence_format()); } - if let Some(pseudo_pending) = &cx.editor.pseudo_pending { - disp.push_str(pseudo_pending.as_str()) + for key in &self.pseudo_pending { + disp.push_str(&key.key_sequence_format()); } let style = cx.editor.theme.get("ui.text"); let macro_width = if cx.editor.macro_recording.is_some() { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 89759439..d09d0ac3 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -677,7 +677,6 @@ pub struct Editor { pub idle_timer: Pin>, pub last_motion: Option, - pub pseudo_pending: Option, pub last_completion: Option, @@ -758,7 +757,6 @@ impl Editor { idle_timer: Box::pin(sleep(conf.idle_timeout)), last_motion: None, last_completion: None, - pseudo_pending: None, config, auto_pairs, exit_code: 0,