fix compile

HactarCE and Conrad Irwin created

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>

Change summary

crates/editor/src/editor.rs | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -22972,7 +22972,7 @@ fn snippet_completions(
         let buffer_offset = text::ToOffset::to_offset(&buffer_anchor, &snapshot);
         let window_start = buffer_offset.saturating_sub(MAX_PREFIX_LEN);
         let max_buffer_window: String = snapshot
-            .text_for_range(window_start.to_anchor(&snapshot)..buffer_anchor)
+            .text_for_range(window_start..buffer_offset)
             .collect();
 
         if max_buffer_window.is_empty() {
@@ -22998,11 +22998,22 @@ fn snippet_completions(
                     snippet
                         .prefix
                         .iter()
-                        .map(|prefix| (snippet_ix, prefix, snippet_match_points(prefix).count()))
+                        .enumerate()
+                        .map(move |(prefix_ix, prefix)| {
+                            (
+                                (snippet_ix, prefix_ix),
+                                prefix,
+                                snippet_match_points(prefix).count(),
+                            )
+                        })
                 })
                 .collect_vec();
 
-            sorted_snippet_candidates.sort_unstable_by_key(|(_, _, match_points)| match_points);
+            // Match longer snippets first
+            sorted_snippet_candidates
+                .sort_unstable_by_key(|(_, _, match_points)| usize::MAX - *match_points);
+            // One snippet may be matched multiple times, but each prefix may only be matched once.
+            let mut sorted_snippet_candidates_seen = HashSet::<usize>::default();
 
             let buffer_windows = snippet_match_points(&max_buffer_window)
                 .take(
@@ -23031,13 +23042,15 @@ fn snippet_completions(
                     snippet_list_cutoff_index += 1;
                 }
 
+                // Take only the candidates with at least `word_count` many words
                 let snippet_candidates_at_word_len =
                     &sorted_snippet_candidates[..snippet_list_cutoff_index];
 
                 let candidates = snippet_candidates_at_word_len
                     .iter()
+                    .enumerate() // index in `sorted_snippet_candidates`
                     // First char must match
-                    .filter(|(_ix, prefix, _snippet_word_count)| {
+                    .filter(|(_ix, (_, prefix, _snippet_word_count))| {
                         itertools::equal(
                             prefix
                                 .chars()
@@ -23051,10 +23064,15 @@ fn snippet_completions(
                                 .flat_map(|c| c.to_lowercase()),
                         )
                     })
-                    .map(|(ix, prefix, _snippet_word_count)| StringMatchCandidate::new(*ix, prefix))
+                    // Match each prefix only once
+                    .filter(|(ix, (_, _prefix, _snippet_word_count))| {
+                        sorted_snippet_candidates_seen.insert(*ix)
+                    })
+                    .map(|(ix, (_, prefix, _snippet_word_count))| {
+                        StringMatchCandidate::new(ix, prefix)
+                    })
                     .collect::<Vec<StringMatchCandidate>>();
 
-                // TODO: ok to match same snippet multiple times?
                 matches.extend(
                     fuzzy::match_strings(
                         &candidates,
@@ -23092,9 +23110,10 @@ fn snippet_completions(
                 matches
                     .iter()
                     .filter_map(|(string_match, buffer_window_len)| {
-                        let snippet_index = string_match.candidate_id;
+                        let (snippet_index, prefix_index) =
+                            sorted_snippet_candidates[string_match.candidate_id].0;
                         let snippet = &snippets[snippet_index];
-                        let matching_prefix = todo!();
+                        let matching_prefix = &snippet.prefix[prefix_index];
                         let start = buffer_offset - buffer_window_len;
                         let start = snapshot.anchor_before(start);
                         let range = start..buffer_anchor;