Use `editor::AcceptEditPrediction` in vim keymap (#24596)

Michael Sloan and Conrad created

* Overrides the action handler to switch to insert mode after jumps.

* Returns `vim::Tab` to its behavior from before #24418

Release Notes:

- N/A

Co-authored-by: Conrad <conrad@zed.dev>

Change summary

assets/keymaps/vim.json     | 18 ++++++++++++++++++
crates/editor/src/editor.rs | 11 +----------
crates/vim/src/vim.rs       | 31 +++++++++++++++++--------------
3 files changed, 36 insertions(+), 24 deletions(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -694,5 +694,23 @@
       "shift-x": "git::StageAll",
       "shift-u": "git::UnstageAll"
     }
+  },
+  {
+    "context": "os == macos && edit_prediction",
+    "bindings": {
+      "alt-tab": "editor::AcceptEditPrediction"
+    }
+  },
+  {
+    "context": "os != macos && edit_prediction",
+    "bindings": {
+      "alt-enter": "editor::AcceptEditPrediction"
+    }
+  },
+  {
+    "context": "edit_prediction && !edit_prediction_requires_modifier",
+    "bindings": {
+      "tab": "editor::AcceptEditPrediction"
+    }
   }
 ]

crates/editor/src/editor.rs 🔗

@@ -48,7 +48,7 @@ mod signature_help;
 pub mod test;
 
 pub(crate) use actions::*;
-pub use actions::{OpenExcerpts, OpenExcerptsSplit};
+pub use actions::{AcceptEditPrediction, OpenExcerpts, OpenExcerptsSplit};
 use aho_corasick::AhoCorasick;
 use anyhow::{anyhow, Context as _, Result};
 use blink_manager::BlinkManager;
@@ -1940,15 +1940,6 @@ impl Editor {
         self.refresh_inline_completion(false, true, window, cx);
     }
 
-    pub fn inline_completion_start_anchor(&self) -> Option<Anchor> {
-        let active_completion = self.active_inline_completion.as_ref()?;
-        let result = match &active_completion.completion {
-            InlineCompletion::Edit { edits, .. } => edits.first()?.0.start,
-            InlineCompletion::Move { target, .. } => *target,
-        };
-        Some(result)
-    }
-
     fn inline_completions_disabled_in_scope(
         &self,
         buffer: &Entity<Buffer>,

crates/vim/src/vim.rs 🔗

@@ -23,7 +23,6 @@ use anyhow::Result;
 use collections::HashMap;
 use editor::{
     movement::{self, FindRange},
-    scroll::Autoscroll,
     Anchor, Bias, Editor, EditorEvent, EditorMode, ToPoint,
 };
 use gpui::{
@@ -649,20 +648,24 @@ impl Vim {
                 vim.push_count_digit(n.0, window, cx);
             });
             Vim::action(editor, cx, |vim, _: &Tab, window, cx| {
-                let Some(anchor) = vim
-                    .editor()
-                    .and_then(|editor| editor.read(cx).inline_completion_start_anchor())
-                else {
-                    return;
-                };
-
-                vim.update_editor(window, cx, |_, editor, window, cx| {
-                    editor.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
-                        s.select_anchor_ranges([anchor..anchor])
-                    });
-                });
-                vim.switch_mode(Mode::Insert, true, window, cx);
+                vim.input_ignored(" ".into(), window, cx)
             });
+            Vim::action(
+                editor,
+                cx,
+                |vim, action: &editor::AcceptEditPrediction, window, cx| {
+                    vim.update_editor(window, cx, |_, editor, window, cx| {
+                        editor.accept_edit_prediction(action, window, cx);
+                    });
+                    // In non-insertion modes, predictions will be hidden and instead a jump will be
+                    // displayed (and performed by `accept_edit_prediction`). This switches to
+                    // insert mode so that the prediction is displayed after the jump.
+                    match vim.mode {
+                        Mode::Replace => {}
+                        _ => vim.switch_mode(Mode::Insert, true, window, cx),
+                    };
+                },
+            );
             Vim::action(editor, cx, |vim, _: &Enter, window, cx| {
                 vim.input_ignored("\n".into(), window, cx)
             });