Fix enter in search

Conrad Irwin created

Change summary

assets/keymaps/vim.json         |  2 +-
crates/vim/src/editor_events.rs |  4 ++--
crates/vim/src/normal/search.rs | 15 +++++++++++++++
crates/vim/src/state.rs         |  1 +
crates/vim/src/vim.rs           | 21 ++++++++++++++++-----
5 files changed, 35 insertions(+), 8 deletions(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -426,7 +426,7 @@
     }
   },
   {
-    "context": "BufferSearchBar",
+    "context": "BufferSearchBar > VimEnabled",
     "bindings": {
       "enter": "vim::SearchSubmit",
       "escape": "buffer_search::Dismiss"

crates/vim/src/editor_events.rs 🔗

@@ -13,7 +13,7 @@ fn focused(EditorFocused(editor): &EditorFocused, cx: &mut AppContext) {
         cx.update_window(previously_active_editor.window_id(), |cx| {
             Vim::update(cx, |vim, cx| {
                 vim.update_active_editor(cx, |previously_active_editor, cx| {
-                    Vim::unhook_vim_settings(previously_active_editor, cx);
+                    vim.unhook_vim_settings(previously_active_editor, cx)
                 });
             });
         });
@@ -35,7 +35,7 @@ fn blurred(EditorBlurred(editor): &EditorBlurred, cx: &mut AppContext) {
                 }
             }
 
-            editor.update(cx, |editor, cx| Vim::unhook_vim_settings(editor, cx))
+            editor.update(cx, |editor, cx| vim.unhook_vim_settings(editor, cx))
         });
     });
 }

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

@@ -282,4 +282,19 @@ mod test {
         cx.simulate_keystrokes(["enter"]);
         cx.assert_state("aa\nˇbb\ndd\ncc\nbb\n", Mode::Normal);
     }
+
+    #[gpui::test]
+    async fn test_non_vim_search(
+        cx: &mut gpui::TestAppContext,
+        deterministic: Arc<gpui::executor::Deterministic>,
+    ) {
+        let mut cx = VimTestContext::new(cx, false).await;
+        cx.set_state("ˇone one one one", Mode::Normal);
+        cx.simulate_keystrokes(["cmd-f"]);
+        deterministic.run_until_parked();
+
+        cx.assert_editor_state("«oneˇ» one one one");
+        cx.simulate_keystrokes(["enter"]);
+        cx.assert_editor_state("one «oneˇ» one one");
+    }
 }

crates/vim/src/state.rs 🔗

@@ -91,6 +91,7 @@ impl VimState {
 
     pub fn keymap_context_layer(&self) -> KeymapContext {
         let mut context = KeymapContext::default();
+        context.add_identifier("VimEnabled");
         context.add_key(
             "vim_mode",
             match self.mode {

crates/vim/src/vim.rs 🔗

@@ -14,8 +14,8 @@ use anyhow::Result;
 use collections::CommandPaletteFilter;
 use editor::{Bias, Editor, EditorMode, Event};
 use gpui::{
-    actions, impl_actions, AppContext, Subscription, ViewContext, ViewHandle, WeakViewHandle,
-    WindowContext,
+    actions, impl_actions, keymap_matcher::KeymapContext, AppContext, Subscription, ViewContext,
+    ViewHandle, WeakViewHandle, WindowContext,
 };
 use language::CursorShape;
 use motion::Motion;
@@ -304,17 +304,28 @@ impl Vim {
                 // Note: set_collapse_matches is not in unhook_vim_settings, as that method is called on blur,
                 // but we need collapse_matches to persist when the search bar is focused.
                 editor.set_collapse_matches(false);
-                Self::unhook_vim_settings(editor, cx);
+                self.unhook_vim_settings(editor, cx);
             }
         });
     }
 
-    fn unhook_vim_settings(editor: &mut Editor, cx: &mut ViewContext<Editor>) {
+    fn unhook_vim_settings(&self, editor: &mut Editor, cx: &mut ViewContext<Editor>) {
         editor.set_cursor_shape(CursorShape::Bar, cx);
         editor.set_clip_at_line_ends(false, cx);
         editor.set_input_enabled(true);
         editor.selections.line_mode = false;
-        editor.remove_keymap_context_layer::<Self>(cx);
+
+        // we set the VimEnabled context on all editors so that we
+        // can distinguish between vim mode and non-vim mode in the BufferSearchBar.
+        // This is a bit of a hack, but currently the search crate does not depend on vim,
+        // and it seems nice to keep it that way.
+        if self.enabled {
+            let mut context = KeymapContext::default();
+            context.add_identifier("VimEnabled");
+            editor.set_keymap_context_layer::<Self>(context, cx)
+        } else {
+            editor.remove_keymap_context_layer::<Self>(cx);
+        }
     }
 }