From e0b818af6236455ab22db1a11645a95ea0995d98 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 2 Jun 2025 20:34:46 -0700 Subject: [PATCH] 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 `.` --- crates/editor/src/editor.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8d94aec8e6d9835d9ae6547b6a45d75fc11cc91b..e68220eea955763b292509e1ce7ed682fcfa2dc4 100644 --- a/crates/editor/src/editor.rs +++ b/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| {