Fix vim surround behavior around text objects (#17603)

Eric Andres created

Performing `ysa")` on `"Hello World"` should produce `("Hello World")`.
Instead it places the parens inside the quotes (i.e. `"(Hello World)"`).
This PR fixes the behavior by preserving the `around` flag from the
operator sequence.

Closes #12976 and partially fixes #13841

Release Notes:

- Fixed the behavior of surrounding a text object in vim.

Change summary

crates/vim/src/normal.rs    |  2 
crates/vim/src/surrounds.rs | 40 ++++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 4 deletions(-)

Detailed changes

crates/vim/src/normal.rs 🔗

@@ -248,7 +248,7 @@ impl Vim {
                 }
                 Some(Operator::AddSurrounds { target: None }) => {
                     waiting_operator = Some(Operator::AddSurrounds {
-                        target: Some(SurroundsType::Object(object)),
+                        target: Some(SurroundsType::Object(object, around)),
                     });
                 }
                 Some(Operator::ToggleComments) => self.toggle_comments_object(object, around, cx),

crates/vim/src/surrounds.rs 🔗

@@ -13,7 +13,7 @@ use ui::ViewContext;
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum SurroundsType {
     Motion(Motion),
-    Object(Object),
+    Object(Object, bool),
     Selection,
 }
 
@@ -59,8 +59,8 @@ impl Vim {
 
                 for selection in &display_selections {
                     let range = match &target {
-                        SurroundsType::Object(object) => {
-                            object.range(&display_map, selection.clone(), false)
+                        SurroundsType::Object(object, around) => {
+                            object.range(&display_map, selection.clone(), *around)
                         }
                         SurroundsType::Motion(motion) => {
                             motion
@@ -697,6 +697,40 @@ mod test {
             the lazy dog."},
             Mode::Normal,
         );
+
+        // test add surrounds around object
+        cx.set_state(
+            indoc! {"
+            The [quˇick] brown
+            fox jumps over
+            the lazy dog."},
+            Mode::Normal,
+        );
+        cx.simulate_keystrokes("y s a ] )");
+        cx.assert_state(
+            indoc! {"
+            The ˇ([quick]) brown
+            fox jumps over
+            the lazy dog."},
+            Mode::Normal,
+        );
+
+        // test add surrounds inside object
+        cx.set_state(
+            indoc! {"
+            The [quˇick] brown
+            fox jumps over
+            the lazy dog."},
+            Mode::Normal,
+        );
+        cx.simulate_keystrokes("y s i ] )");
+        cx.assert_state(
+            indoc! {"
+            The [ˇ(quick)] brown
+            fox jumps over
+            the lazy dog."},
+            Mode::Normal,
+        );
     }
 
     #[gpui::test]