From 6db33b83d8669ec46eb352265fc0cd0500c92b8e Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 29 Jul 2024 09:22:25 -0600 Subject: [PATCH] vim: Fix >... (#15404) Co-Authored-By: @Alextopher Release Notes: - vim: Fixed a hang when repeating an aborted operation ([#15399](https://github.com/zed-industries/zed/issues/15399)). --- crates/vim/src/test.rs | 12 ++++++++++ crates/vim/src/vim.rs | 24 +++++-------------- .../test_record_replay_recursion.json | 6 +++++ 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 crates/vim/test_data/test_record_replay_recursion.json diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index 40bda6ca2d..dc447708c6 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -1448,3 +1448,15 @@ async fn test_visual_indent_count(cx: &mut gpui::TestAppContext) { cx.simulate_keystrokes("shift-v 2 <"); cx.assert_state(" ˇhi", Mode::Normal); } + +#[gpui::test] +async fn test_record_replay_recursion(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + + cx.set_shared_state("ˇhello world").await; + cx.simulate_shared_keystrokes(">").await; + cx.simulate_shared_keystrokes(".").await; + cx.simulate_shared_keystrokes(".").await; + cx.simulate_shared_keystrokes(".").await; + cx.shared_state().await.assert_eq("ˇhello world"); // takes a _long_ time +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 5f5dff6062..cac66dde0f 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -189,25 +189,13 @@ fn observe_keystrokes(keystroke_event: &KeystrokeEvent, cx: &mut WindowContext) return; } - Vim::update(cx, |vim, cx| match vim.active_operator() { - Some( - Operator::FindForward { .. } - | Operator::FindBackward { .. } - | Operator::Replace - | Operator::Digraph { .. } - | Operator::AddSurrounds { .. } - | Operator::ChangeSurrounds { .. } - | Operator::DeleteSurrounds - | Operator::Mark - | Operator::Jump { .. } - | Operator::Register - | Operator::RecordRegister - | Operator::ReplayRegister, - ) => {} - Some(_) => { - vim.clear_operator(cx); + Vim::update(cx, |vim, cx| { + if let Some(operator) = vim.active_operator() { + if !operator.is_waiting(vim.state().mode) { + vim.clear_operator(cx); + vim.stop_recording_immediately(Box::new(ClearOperators)) + } } - _ => {} }); } diff --git a/crates/vim/test_data/test_record_replay_recursion.json b/crates/vim/test_data/test_record_replay_recursion.json new file mode 100644 index 0000000000..d02817db57 --- /dev/null +++ b/crates/vim/test_data/test_record_replay_recursion.json @@ -0,0 +1,6 @@ +{"Put":{"state":"ˇhello world"}} +{"Key":">"} +{"Key":"."} +{"Key":"."} +{"Key":"."} +{"Get":{"state":"ˇhello world","mode":"Normal"}}