agent: Support vim-mode in the agent panel's editor (#31915)

Oleksiy Syvokon , Ben Kunkle , and Conrad Irwin created

Closes #30081

Release Notes:

- Added vim-mode support in the agent panel's editor

---------

Co-authored-by: Ben Kunkle <ben.kunkle@gmail.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>

Change summary

assets/keymaps/vim.json                 | 13 +++++++++++++
crates/agent/src/message_editor.rs      |  1 +
crates/vim/src/test/vim_test_context.rs |  4 +++-
crates/vim/src/vim.rs                   |  6 ++++++
4 files changed, 23 insertions(+), 1 deletion(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -838,6 +838,19 @@
       "tab": "editor::AcceptEditPrediction"
     }
   },
+  {
+    "context": "MessageEditor > Editor && VimControl",
+    "bindings": {
+      "enter": "agent::Chat",
+      // TODO: Implement search
+      "/": null,
+      "?": null,
+      "#": null,
+      "*": null,
+      "n": null,
+      "shift-n": null
+    }
+  },
   {
     "context": "os != macos && Editor && edit_prediction_conflict",
     "bindings": {

crates/agent/src/message_editor.rs 🔗

@@ -112,6 +112,7 @@ pub(crate) fn create_editor(
         editor.set_placeholder_text("Message the agent – @ to include context", cx);
         editor.set_show_indent_guides(false, cx);
         editor.set_soft_wrap();
+        editor.set_use_modal_editing(true);
         editor.set_context_menu_options(ContextMenuOptions {
             min_entries_visible: 12,
             max_entries_visible: 12,

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

@@ -1,11 +1,13 @@
 use std::ops::{Deref, DerefMut};
 
 use editor::test::editor_lsp_test_context::EditorLspTestContext;
-use gpui::{Context, Entity, SemanticVersion, UpdateGlobal};
+use gpui::{Context, Entity, SemanticVersion, UpdateGlobal, actions};
 use search::{BufferSearchBar, project_search::ProjectSearchBar};
 
 use crate::{state::Operator, *};
 
+actions!(agent, [Chat]);
+
 pub struct VimTestContext {
     cx: EditorLspTestContext,
 }

crates/vim/src/vim.rs 🔗

@@ -433,6 +433,12 @@ impl Vim {
     fn activate(editor: &mut Editor, window: &mut Window, cx: &mut Context<Editor>) {
         let vim = Vim::new(window, cx);
 
+        if !editor.mode().is_full() {
+            vim.update(cx, |vim, _| {
+                vim.mode = Mode::Insert;
+            });
+        }
+
         editor.register_addon(VimAddon {
             entity: vim.clone(),
         });