Fix vim escape in normal mode

Conrad Irwin created

Fixes: zed-industries/community#1857

Change summary

assets/keymaps/vim.json | 16 ++++++++++++++++
crates/vim/src/test.rs  | 10 ++++++++++
2 files changed, 26 insertions(+)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -236,6 +236,14 @@
       "ctrl-w ctrl-q": "pane::CloseAllItems"
     }
   },
+  {
+    // escape is in its own section so that it cancels a pending count.
+    "context": "Editor && vim_mode == normal && vim_operator == none && !VimWaiting",
+    "bindings": {
+      "escape": "editor::Cancel",
+      "ctrl+[": "editor::Cancel"
+    }
+  },
   {
     "context": "Editor && vim_mode == normal && (vim_operator == none || vim_operator == n) && !VimWaiting",
     "bindings": {
@@ -389,6 +397,14 @@
         "vim::SwitchMode",
         "Normal"
       ],
+      "escape": [
+        "vim::SwitchMode",
+        "Normal"
+      ],
+      "ctrl+[": [
+        "vim::SwitchMode",
+        "Normal"
+      ],
       ">": "editor::Indent",
       "<": "editor::Outdent"
     }

crates/vim/src/test.rs 🔗

@@ -157,6 +157,16 @@ async fn test_escape_command_palette(cx: &mut gpui::TestAppContext) {
     cx.assert_state("aˇbc\n", Mode::Insert);
 }
 
+#[gpui::test]
+async fn test_escape_cancels(cx: &mut gpui::TestAppContext) {
+    let mut cx = VimTestContext::new(cx, true).await;
+
+    cx.set_state("aˇbˇc", Mode::Normal);
+    cx.simulate_keystrokes(["escape"]);
+
+    cx.assert_state("aˇbc", Mode::Normal);
+}
+
 #[gpui::test]
 async fn test_selection_on_search(cx: &mut gpui::TestAppContext) {
     let mut cx = VimTestContext::new(cx, true).await;