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

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 `.`
This commit is contained in:
Arseny Kapoulkine 2025-06-02 20:34:46 -07:00 committed by GitHub
parent 58a400b1ee
commit e0b818af62
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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 { cx.emit(EditorEvent::InputHandled {
utf16_range_to_replace: None, utf16_range_to_replace: None,
text: new_text.clone().into(), text: new_text[common_prefix_len..].into(),
}); });
self.transact(window, cx, |this, window, cx| { self.transact(window, cx, |this, window, cx| {