Fix some cases of broken repeat in vim

Conrad Irwin created

Change summary

crates/vim/src/editor_events.rs                   |  7 +++----
crates/vim/src/normal/repeat.rs                   | 13 +++++++++++++
crates/vim/src/test/neovim_backed_test_context.rs |  2 ++
crates/vim/test_data/test_repeat_over_blur.json   | 11 +++++++++++
4 files changed, 29 insertions(+), 4 deletions(-)

Detailed changes

crates/vim/src/editor_events.rs 🔗

@@ -1,6 +1,6 @@
-use crate::Vim;
+use crate::{insert::NormalBefore, Vim};
 use editor::{Editor, EditorEvent};
-use gpui::{AppContext, Entity, EntityId, View, ViewContext, WindowContext};
+use gpui::{Action, AppContext, Entity, EntityId, View, ViewContext, WindowContext};
 
 pub fn init(cx: &mut AppContext) {
     cx.observe_new_views(|_, cx: &mut ViewContext<Editor>| {
@@ -34,8 +34,7 @@ fn focused(editor: View<Editor>, cx: &mut WindowContext) {
 
 fn blurred(editor: View<Editor>, cx: &mut WindowContext) {
     Vim::update(cx, |vim, cx| {
-        vim.workspace_state.recording = false;
-        vim.workspace_state.recorded_actions.clear();
+        vim.stop_recording_immediately(NormalBefore.boxed_clone());
         if let Some(previous_editor) = vim.active_editor.clone() {
             if previous_editor
                 .upgrade()

crates/vim/src/normal/repeat.rs 🔗

@@ -493,4 +493,17 @@ mod test {
         cx.simulate_keystrokes(["escape"]);
         cx.assert_state("ˇjhello\n", Mode::Normal);
     }
+
+    #[gpui::test]
+    async fn test_repeat_over_blur(cx: &mut gpui::TestAppContext) {
+        let mut cx = NeovimBackedTestContext::new(cx).await;
+
+        cx.set_shared_state("ˇhello hello hello\n").await;
+        cx.simulate_shared_keystrokes(["c", "f", "o", "x", "escape"])
+            .await;
+        cx.assert_shared_state("ˇx hello hello\n").await;
+        cx.simulate_shared_keystrokes([":", "escape"]).await;
+        cx.simulate_shared_keystrokes(["."]).await;
+        cx.assert_shared_state("ˇx hello\n").await;
+    }
 }

crates/vim/src/test/neovim_backed_test_context.rs 🔗

@@ -62,6 +62,8 @@ pub struct NeovimBackedTestContext {
 
 impl NeovimBackedTestContext {
     pub async fn new(cx: &mut gpui::TestAppContext) -> NeovimBackedTestContext {
+        #[cfg(feature = "neovim")]
+        cx.executor().allow_parking();
         // rust stores the name of the test on the current thread.
         // We use this to automatically name a file that will store
         // the neovim connection's requests/responses so that we can

crates/vim/test_data/test_repeat_over_blur.json 🔗

@@ -0,0 +1,11 @@
+{"Put":{"state":"ˇhello hello hello\n"}}
+{"Key":"c"}
+{"Key":"f"}
+{"Key":"o"}
+{"Key":"x"}
+{"Key":"escape"}
+{"Get":{"state":"ˇx hello hello\n","mode":"Normal"}}
+{"Key":":"}
+{"Key":"escape"}
+{"Key":"."}
+{"Get":{"state":"ˇx hello\n","mode":"Normal"}}