Fix duplicate prefixes when repeating completions in Vim mode (#31818)

Arseny Kapoulkine created

When text is completed, new_text contains the entire new completion
which replaces the old_text. In Vim mode, pressing . repeats the
completion; if InputHandled records the full text and no range to
replace, the entire completion gets appended; this happens after the
completion prefix typing repeats, and we get a duplicate prefix.

Using range to replace has some downsides when the completion is
repeated as a standalone action; in a common case, it should be
sufficient to record the new suffix. This is actually what used to
happen before #28586, which removed this code in a larger attempt to fix
completions at multiple cursors:

```rust
let text = &new_text[common_prefix_len..];
let utf16_range_to_replace = ...

cx.emit(EditorEvent::InputHandled {
    utf16_range_to_replace,
    text: text.into(),
});
```

Fixes #30758
Fixes #31759
Fixes #31779

Release Notes:

- Vim: Fix duplicate prefixes when repeating completions via `.`

Change summary

crates/editor/src/editor.rs | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -5531,9 +5531,18 @@ impl Editor {
             }
         }
 
+        let mut common_prefix_len = 0;
+        for (a, b) in old_text.chars().zip(new_text.chars()) {
+            if a == b {
+                common_prefix_len += a.len_utf8();
+            } else {
+                break;
+            }
+        }
+
         cx.emit(EditorEvent::InputHandled {
             utf16_range_to_replace: None,
-            text: new_text.clone().into(),
+            text: new_text[common_prefix_len..].into(),
         });
 
         self.transact(window, cx, |this, window, cx| {