vim: Adjust surrounding_markers method (#14752)

Hans created

At present, when calculating some ranges, we take the `tuple_windows` to
iterate forward, which will cause some problems when the cursor is being
front, because `tuple_windows` iteration cannot iterate to the very
beginning, so there will be some cases that cannot be calculated, adjust
this method, and now it can calculate more perfectly, and the execution
speed is about the same

Release Notes:

- N/A

Change summary

crates/vim/src/object.rs                                                | 27 
crates/vim/test_data/test_singleline_surrounding_character_objects.json | 10 
2 files changed, 34 insertions(+), 3 deletions(-)

Detailed changes

crates/vim/src/object.rs 🔗

@@ -838,13 +838,16 @@ fn surrounding_markers(
     }
 
     if opening.is_none() {
-        for ((ch, range), (before_ch, _)) in movement::chars_before(map, point).tuple_windows() {
+        let mut chars_before = movement::chars_before(map, point).peekable();
+        while let Some((ch, range)) = chars_before.next() {
             if ch == '\n' && !search_across_lines {
                 break;
             }
 
-            if before_ch == '\\' {
-                continue;
+            if let Some((before_ch, _)) = chars_before.peek() {
+                if *before_ch == '\\' {
+                    continue;
+                }
             }
 
             if ch == open_marker {
@@ -1209,6 +1212,24 @@ mod test {
         let mut cx = NeovimBackedTestContext::new(cx).await;
         cx.set_shared_wrap(12).await;
 
+        cx.set_shared_state(indoc! {
+            "\"ˇhello world\"!"
+        })
+        .await;
+        cx.simulate_shared_keystrokes("v i \"").await;
+        cx.shared_state().await.assert_eq(indoc! {
+            "\"«hello worldˇ»\"!"
+        });
+
+        cx.set_shared_state(indoc! {
+            "\"hˇello world\"!"
+        })
+        .await;
+        cx.simulate_shared_keystrokes("v i \"").await;
+        cx.shared_state().await.assert_eq(indoc! {
+            "\"«hello worldˇ»\"!"
+        });
+
         cx.set_shared_state(indoc! {
             "helˇlo \"world\"!"
         })

crates/vim/test_data/test_singleline_surrounding_character_objects.json 🔗

@@ -1,5 +1,15 @@
 {"SetOption":{"value":"wrap"}}
 {"SetOption":{"value":"columns=12"}}
+{"Put":{"state":"\"ˇhello world\"!"}}
+{"Key":"v"}
+{"Key":"i"}
+{"Key":"\""}
+{"Get":{"state":"\"«hello worldˇ»\"!","mode":"Visual"}}
+{"Put":{"state":"\"hˇello world\"!"}}
+{"Key":"v"}
+{"Key":"i"}
+{"Key":"\""}
+{"Get":{"state":"\"«hello worldˇ»\"!","mode":"Visual"}}
 {"Put":{"state":"helˇlo \"world\"!"}}
 {"Key":"v"}
 {"Key":"i"}