From a46ca323567aada6960467c447d789a606db3d6a Mon Sep 17 00:00:00 2001 From: Julia Date: Sat, 7 Jan 2023 15:34:28 -0500 Subject: [PATCH] Completion word start filtering which is codepoint aware --- crates/editor/src/editor.rs | 38 ++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 354a2be97d..4405fc0b33 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -830,33 +830,41 @@ impl CompletionsMenu { //Remove all candidates where the query's start does not match the start of any word in the candidate if let Some(query) = query { - if let Some(&start) = query.as_bytes().get(0) { - let start = start.to_ascii_lowercase(); - matches.retain(|m| { - let bytes = m.string.as_bytes(); + if let Some(query_start) = query.chars().next() { + matches.retain(|string_match| { + let text = &string_match.string; + let mut index = 0; + let mut codepoints = text.char_indices().peekable(); std::iter::from_fn(move || { let start_index = index; - while index < bytes.len() { - let current_upper = bytes[index].is_ascii_uppercase(); - let has_more = index + 1 < bytes.len(); - let next_upper = has_more && bytes[index + 1].is_ascii_uppercase(); + while let Some((new_index, codepoint)) = codepoints.next() { + index = new_index + codepoint.len_utf8(); + let current_upper = codepoint.is_uppercase(); + let next_upper = codepoints + .peek() + .map(|(_, c)| c.is_uppercase()) + .unwrap_or(false); - index += 1; if !current_upper && next_upper { - return Some(&m.string[start_index..index]); + return Some(&text[start_index..index]); } } - index = bytes.len(); - if start_index < bytes.len() { - return Some(&m.string[start_index..]); + index = text.len(); + if start_index < text.len() { + return Some(&text[start_index..]); } None }) - .flat_map(|w| w.split_inclusive('_')) - .any(|w| w.as_bytes().first().map(|&b| b.to_ascii_lowercase()) == Some(start)) + .flat_map(|word| word.split_inclusive('_')) + .any(|word| { + word.chars() + .flat_map(|codepoint| codepoint.to_lowercase()) + .zip(query_start.to_lowercase()) + .all(|(word_cp, query_cp)| word_cp == query_cp) + }) }); } }