diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fd8e8fb21b47..d8b21e086cf5 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -830,17 +830,26 @@ impl EditorView { last_mode = current_mode; }; - match &key_result { + match key_result { KeymapResult::Matched(command) => { - execute_command(command); + execute_command(&command); } KeymapResult::Pending(node) => cxt.editor.autoinfo = Some(node.infobox()), KeymapResult::MatchedSequence(commands) => { for command in commands { - execute_command(command); + execute_command(&command); } } - KeymapResult::NotFound | KeymapResult::Cancelled(_) => return Some(key_result), + KeymapResult::NotFound => return Some(key_result), + KeymapResult::Cancelled(mut pending) => { + if !matches!( + self.handle_keymap_event(mode, cxt, event), + Some(KeymapResult::NotFound) + ) { + pending.pop(); + } + return Some(KeymapResult::Cancelled(pending)); + } } None } diff --git a/helix-term/tests/test/movement.rs b/helix-term/tests/test/movement.rs index 9a48cdbcb9fb..46ae3c48efeb 100644 --- a/helix-term/tests/test/movement.rs +++ b/helix-term/tests/test/movement.rs @@ -410,6 +410,23 @@ async fn cursor_position_append_eof() -> anyhow::Result<()> { Ok(()) } +#[tokio::test(flavor = "multi_thread")] +async fn repeated_key_movement() -> anyhow::Result<()> { + test(( + "#[|f]#oo", + "]]", + helpers::platform_line("#[|f]#oo\n"), + )) + .await?; + test(( + "#[|f]#oo\n\nbar", + "]]p", + helpers::platform_line("#[foo\n|]#\nbar"), + )) + .await?; + Ok(()) +} + #[tokio::test(flavor = "multi_thread")] async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> { test_with_config(