From 26409facdf48741c240873887bcdb22a666c0d56 Mon Sep 17 00:00:00 2001 From: x Date: Fri, 6 Oct 2023 04:48:04 +0330 Subject: [PATCH 1/4] Make sure pending key list is empty when count handling This will allow using numbers as second key event. --- helix-term/src/ui/editor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index dd6fff087bee..d5a9e7b1f132 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -886,7 +886,9 @@ impl EditorView { fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEvent) { match (event, cxt.editor.count) { // count handling - (key!(i @ '0'), Some(_)) | (key!(i @ '1'..='9'), _) => { + (key!(i @ '0'), Some(_)) | (key!(i @ '1'..='9'), _) + if self.keymaps.pending().is_empty() => + { let i = i.to_digit(10).unwrap() as usize; cxt.editor.count = std::num::NonZeroUsize::new(cxt.editor.count.map_or(i, |c| c.get() * 10 + i)); From cd0d555aa6eebb1db3f8f6668178e7e09dcbf428 Mon Sep 17 00:00:00 2001 From: x Date: Fri, 6 Oct 2023 05:25:30 +0330 Subject: [PATCH 2/4] count handling; add an exception for 'g' --- helix-term/src/ui/editor.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index d5a9e7b1f132..7192f97b7d25 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -887,7 +887,12 @@ impl EditorView { match (event, cxt.editor.count) { // count handling (key!(i @ '0'), Some(_)) | (key!(i @ '1'..='9'), _) - if self.keymaps.pending().is_empty() => + if self.keymaps.pending().is_empty() + || self.keymaps.pending().last() + == Some(&KeyEvent { + code: KeyCode::Char('g'), + modifiers: KeyModifiers::NONE, + }) => { let i = i.to_digit(10).unwrap() as usize; cxt.editor.count = From c3fcec8737649a07b8c744dc4b1242e36f41631d Mon Sep 17 00:00:00 2001 From: x Date: Mon, 16 Oct 2023 17:21:32 +0330 Subject: [PATCH 3/4] Lookup the key event before considering a number as count --- helix-term/src/keymap.rs | 8 ++++++++ helix-term/src/ui/editor.rs | 7 +------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index 598be55b5ff4..d1c96ee4b86f 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -303,6 +303,14 @@ impl Keymaps { self.sticky.as_ref() } + pub fn key_exists(&self, mode: Mode, key: KeyEvent) -> bool { + let keymaps = &*self.map(); + let keymap = &keymaps[&mode]; + let mut ks = self.pending().to_vec(); + ks.push(key); + keymap.search(&ks).is_some() + } + /// Lookup `key` in the keymap to try and find a command to execute. Escape /// key cancels pending keystrokes. If there are no pending keystrokes but a /// sticky node is in use, it will be cleared. diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 7192f97b7d25..58b7db502f05 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -887,12 +887,7 @@ impl EditorView { match (event, cxt.editor.count) { // count handling (key!(i @ '0'), Some(_)) | (key!(i @ '1'..='9'), _) - if self.keymaps.pending().is_empty() - || self.keymaps.pending().last() - == Some(&KeyEvent { - code: KeyCode::Char('g'), - modifiers: KeyModifiers::NONE, - }) => + if !self.keymaps.key_exists(mode, event) => { let i = i.to_digit(10).unwrap() as usize; cxt.editor.count = From c0395ba66401da9b125e480d0e38a0d7e4967ae6 Mon Sep 17 00:00:00 2001 From: x Date: Wed, 14 Feb 2024 04:44:07 +0330 Subject: [PATCH 4/4] Avoid the allocation of another vec for the pending keys --- helix-term/src/keymap.rs | 9 +++++---- helix-term/src/ui/editor.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs index d1c96ee4b86f..4b2b8b62847d 100644 --- a/helix-term/src/keymap.rs +++ b/helix-term/src/keymap.rs @@ -303,12 +303,13 @@ impl Keymaps { self.sticky.as_ref() } - pub fn key_exists(&self, mode: Mode, key: KeyEvent) -> bool { + pub fn contains_key(&self, mode: Mode, key: KeyEvent) -> bool { let keymaps = &*self.map(); let keymap = &keymaps[&mode]; - let mut ks = self.pending().to_vec(); - ks.push(key); - keymap.search(&ks).is_some() + keymap + .search(self.pending()) + .and_then(KeyTrie::node) + .is_some_and(|node| node.contains_key(&key)) } /// Lookup `key` in the keymap to try and find a command to execute. Escape diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 58b7db502f05..1c272a2a28fa 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -887,7 +887,7 @@ impl EditorView { match (event, cxt.editor.count) { // count handling (key!(i @ '0'), Some(_)) | (key!(i @ '1'..='9'), _) - if !self.keymaps.key_exists(mode, event) => + if !self.keymaps.contains_key(mode, event) => { let i = i.to_digit(10).unwrap() as usize; cxt.editor.count =