vim: Fix clear exchange not working (#25804)

Thomas Heartman created

Fixes two issues with the Vim exchange implementation:

1. The clear exchange implementation **didn't** clear the exchange. This
was due to us asking the editor to clear normal highlights instead of
background highlights.
2. Calling clear exchange also wouldn't cause the operator to be
cleared, so you would be left in operator = "cx".

I've added tests for both of these cases.

Partially closes #25750. It doesn't address the problem with dot repeat
not working for my custom bindings, but I don't know what would cause
that. I'd love to hear some thoughts on why that is. That might be a
problem on my part or it might be something with the code. Input would
be appreciated.

Release Notes:

- Fixed: Vim exchange's "clear exchange" function didn't clear the
exchange and kept you in operator pending mode.

Change summary

crates/vim/src/replace.rs | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)

Detailed changes

crates/vim/src/replace.rs 🔗

@@ -170,8 +170,9 @@ impl Vim {
     pub fn clear_exchange(&mut self, window: &mut Window, cx: &mut Context<Self>) {
         self.stop_recording(cx);
         self.update_editor(window, cx, |_, editor, _, cx| {
-            editor.clear_highlights::<VimExchange>(cx);
+            editor.clear_background_highlights::<VimExchange>(cx);
         });
+        self.clear_operator(window, cx);
     }
 
     pub fn exchange_motion(
@@ -483,4 +484,27 @@ mod test {
         cx.simulate_keystrokes("c x t r w c x i w");
         cx.assert_state("hello ˇworld", Mode::Normal);
     }
+
+    #[gpui::test]
+    async fn test_clear_exchange_clears_operator(cx: &mut gpui::TestAppContext) {
+        let mut cx = VimTestContext::new(cx, true).await;
+
+        cx.set_state("ˇirrelevant", Mode::Normal);
+        cx.simulate_keystrokes("c x c");
+
+        assert_eq!(cx.active_operator(), None);
+    }
+
+    #[gpui::test]
+    async fn test_clear_exchange(cx: &mut gpui::TestAppContext) {
+        let mut cx = VimTestContext::new(cx, true).await;
+
+        cx.set_state("ˇhello world", Mode::Normal);
+        cx.simulate_keystrokes("c x i w c x c");
+
+        cx.update_editor(|editor, window, cx| {
+            let highlights = editor.all_text_background_highlights(window, cx);
+            assert_eq!(0, highlights.len());
+        });
+    }
 }