From cf13a766184ebe334a275a4cafa35aac1394f2ac Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Tue, 29 Jul 2025 01:15:29 +0530 Subject: [PATCH] editor: Prioritize fuzzy score over sort positions in code completion sort (#35229) We already prioritize matches that come after separators like `_`: https://github.com/zed-industries/zed/blob/cef7d53607381975ea00d6302d8a9aab3c40eb1f/crates/fuzzy/src/matcher.rs#L274 and deprioritize non-consecutive matches using distance penalty: https://github.com/zed-industries/zed/blob/cef7d53607381975ea00d6302d8a9aab3c40eb1f/crates/fuzzy/src/matcher.rs#L281 In completion sort, letting fuzzy score be the primary sort factor and sort positions be secondary yields better results upon testing. We still need sort positions because of this kind of test case: https://github.com/zed-industries/zed/blob/cef7d53607381975ea00d6302d8a9aab3c40eb1f/crates/editor/src/code_completion_tests.rs#L195-L217 Before/After: image image Release Notes: - N/A --- crates/editor/src/code_completion_tests.rs | 24 +++++++++++++++++++++- crates/editor/src/code_context_menus.rs | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/crates/editor/src/code_completion_tests.rs b/crates/editor/src/code_completion_tests.rs index 4f9822b597eee13a8e3bad540b833e3158e2123e..fd8db29584d8eb6944ff674dd8bf5d860ce32428 100644 --- a/crates/editor/src/code_completion_tests.rs +++ b/crates/editor/src/code_completion_tests.rs @@ -94,7 +94,7 @@ async fn test_fuzzy_score(cx: &mut TestAppContext) { filter_and_sort_matches("set_text", &completions, SnippetSortOrder::Top, cx).await; assert_eq!(matches[0].string, "set_text"); assert_eq!(matches[1].string, "set_text_style_refinement"); - assert_eq!(matches[2].string, "set_context_menu_options"); + assert_eq!(matches[2].string, "set_placeholder_text"); } // fuzzy filter text over label, sort_text and sort_kind @@ -216,6 +216,28 @@ async fn test_sort_positions(cx: &mut TestAppContext) { assert_eq!(matches[0].string, "rounded-full"); } +#[gpui::test] +async fn test_fuzzy_over_sort_positions(cx: &mut TestAppContext) { + let completions = vec![ + CompletionBuilder::variable("lsp_document_colors", None, "7fffffff"), // 0.29 fuzzy score + CompletionBuilder::function( + "language_servers_running_disk_based_diagnostics", + None, + "7fffffff", + ), // 0.168 fuzzy score + CompletionBuilder::function("code_lens", None, "7fffffff"), // 3.2 fuzzy score + CompletionBuilder::variable("lsp_code_lens", None, "7fffffff"), // 3.2 fuzzy score + CompletionBuilder::function("fetch_code_lens", None, "7fffffff"), // 3.2 fuzzy score + ]; + + let matches = + filter_and_sort_matches("lens", &completions, SnippetSortOrder::default(), cx).await; + + assert_eq!(matches[0].string, "code_lens"); + assert_eq!(matches[1].string, "lsp_code_lens"); + assert_eq!(matches[2].string, "fetch_code_lens"); +} + async fn test_for_each_prefix( target: &str, completions: &Vec, diff --git a/crates/editor/src/code_context_menus.rs b/crates/editor/src/code_context_menus.rs index 9f842836ed20bb960c1e112398b8939d6f77e6cc..4ae2a14ca730dafa7cfecd9e9b3bacbe3f7bc47b 100644 --- a/crates/editor/src/code_context_menus.rs +++ b/crates/editor/src/code_context_menus.rs @@ -1057,9 +1057,9 @@ impl CompletionsMenu { enum MatchTier<'a> { WordStartMatch { sort_exact: Reverse, - sort_positions: Vec, sort_snippet: Reverse, sort_score: Reverse>, + sort_positions: Vec, sort_text: Option<&'a str>, sort_kind: usize, sort_label: &'a str, @@ -1137,9 +1137,9 @@ impl CompletionsMenu { MatchTier::WordStartMatch { sort_exact, - sort_positions, sort_snippet, sort_score, + sort_positions, sort_text, sort_kind, sort_label,