vim: Increment search right (#10866)

Hendrik Sollich and Conrad Irwin created

Hi there, nice editor!
Here's my attempt at fixing #10865.

Thanks

Release Notes:

-vim: Fix ctrl+a when cursor is on a decimal point
([#10865](https://github.com/zed-industries/zed/issues/10865)).

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>

Change summary

crates/vim/src/normal/increment.rs                     | 57 ++++++++++-
crates/vim/test_data/test_increment_with_dot.json      |  5 +
crates/vim/test_data/test_increment_with_two_dots.json |  5 +
3 files changed, 61 insertions(+), 6 deletions(-)

Detailed changes

crates/vim/src/normal/increment.rs 🔗

@@ -117,13 +117,16 @@ fn find_number(
 ) -> Option<(Range<Point>, String, u32)> {
     let mut offset = start.to_offset(snapshot);
 
-    // go backwards to the start of any number the selection is within
-    for ch in snapshot.reversed_chars_at(offset) {
-        if ch.is_ascii_digit() || ch == '-' || ch == 'b' || ch == 'x' {
-            offset -= ch.len_utf8();
-            continue;
+    let ch0 = snapshot.chars_at(offset).next();
+    if ch0.as_ref().is_some_and(char::is_ascii_digit) || matches!(ch0, Some('-' | 'b' | 'x')) {
+        // go backwards to the start of any number the selection is within
+        for ch in snapshot.reversed_chars_at(offset) {
+            if ch.is_ascii_digit() || ch == '-' || ch == 'b' || ch == 'x' {
+                offset -= ch.len_utf8();
+                continue;
+            }
+            break;
         }
-        break;
     }
 
     let mut begin = None;
@@ -217,6 +220,48 @@ mod test {
             .await;
     }
 
+    #[gpui::test]
+    async fn test_increment_with_dot(cx: &mut gpui::TestAppContext) {
+        let mut cx = NeovimBackedTestContext::new(cx).await;
+
+        cx.set_shared_state(indoc! {"
+            1ˇ.2
+            "})
+            .await;
+
+        cx.simulate_shared_keystrokes(["ctrl-a"]).await;
+        cx.assert_shared_state(indoc! {"
+            1.ˇ3
+            "})
+            .await;
+        cx.simulate_shared_keystrokes(["ctrl-x"]).await;
+        cx.assert_shared_state(indoc! {"
+            1.ˇ2
+            "})
+            .await;
+    }
+
+    #[gpui::test]
+    async fn test_increment_with_two_dots(cx: &mut gpui::TestAppContext) {
+        let mut cx = NeovimBackedTestContext::new(cx).await;
+
+        cx.set_shared_state(indoc! {"
+            111.ˇ.2
+            "})
+            .await;
+
+        cx.simulate_shared_keystrokes(["ctrl-a"]).await;
+        cx.assert_shared_state(indoc! {"
+            111..ˇ3
+            "})
+            .await;
+        cx.simulate_shared_keystrokes(["ctrl-x"]).await;
+        cx.assert_shared_state(indoc! {"
+            111..ˇ2
+            "})
+            .await;
+    }
+
     #[gpui::test]
     async fn test_increment_radix(cx: &mut gpui::TestAppContext) {
         let mut cx = NeovimBackedTestContext::new(cx).await;