From 32859a38ede0eb1017a79f13af2db17baadf5492 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Feb 2022 12:03:36 +0100 Subject: [PATCH] Refine autocompletion when text matches a prefix of the suggestion --- crates/editor/src/editor.rs | 40 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 789ea4c0cd..9af15f9b9e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1699,31 +1699,39 @@ impl Editor { }; let snapshot = self.buffer.read(cx).snapshot(cx); let old_range = completion.old_range.to_offset(&snapshot); + let old_text = snapshot + .text_for_range(old_range.clone()) + .collect::(); let selections = self.local_selections::(cx); - let mut common_prefix_len = None; + let newest_selection = selections.iter().max_by_key(|s| s.id)?; + let lookbehind = newest_selection.start.saturating_sub(old_range.start); + let lookahead = old_range.end.saturating_sub(newest_selection.end); + let mut common_prefix_len = old_text + .bytes() + .zip(text.bytes()) + .take_while(|(a, b)| a == b) + .count(); + let mut ranges = Vec::new(); for selection in &selections { - let start = selection.start.saturating_sub(old_range.len()); - let prefix_len = snapshot - .bytes_at(start) - .zip(completion.new_text.bytes()) - .take_while(|(a, b)| a == b) - .count(); - if common_prefix_len.is_none() { - common_prefix_len = Some(prefix_len); - } - - if common_prefix_len == Some(prefix_len) { - ranges.push(start + prefix_len..selection.end); + if snapshot.contains_str_at(selection.start.saturating_sub(lookbehind), &old_text) { + let start = selection.start.saturating_sub(lookbehind); + let end = selection.end + lookahead; + ranges.push(start + common_prefix_len..end); } else { - common_prefix_len.take(); + common_prefix_len = 0; ranges.clear(); - ranges.extend(selections.iter().map(|s| s.start..s.end)); + ranges.extend(selections.iter().map(|s| { + if s.id == newest_selection.id { + old_range.clone() + } else { + s.start..s.end + } + })); break; } } - let common_prefix_len = common_prefix_len.unwrap_or(0); let text = &text[common_prefix_len..]; self.start_transaction(cx);