Sort completions by relevance for strong matches (#20145)

Further enhancement:
On exploring VSCode's sorting logic, there are two major distinctions:
* A config option exists to adjust sort priority of snippets. They can
be placed inline (default), top or at bottom of completitions.
* The sorting order sorts by (in order): sort_text (lower case),
sort_text, kind

ref:
6f2d4781e8/src/vs/editor/contrib/suggest/browser/suggest.ts (L338-L383)

Closes #19786

Release Notes:

- Improved sort order in completions to show relevant matches first
([#19786](https://github.com/zed-industries/zed/issues/19786))
This commit is contained in:
Avinash Thakur 2024-11-05 01:53:36 +05:30 committed by GitHub
parent 8196db6022
commit c9ec235b12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 76 additions and 8 deletions

View file

@ -8385,6 +8385,74 @@ async fn test_completion_page_up_down_keys(cx: &mut gpui::TestAppContext) {
});
}
#[gpui::test]
async fn test_completion_sort(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorLspTestContext::new_rust(
lsp::ServerCapabilities {
completion_provider: Some(lsp::CompletionOptions {
trigger_characters: Some(vec![".".to_string()]),
..Default::default()
}),
..Default::default()
},
cx,
)
.await;
cx.lsp
.handle_request::<lsp::request::Completion, _, _>(move |_, _| async move {
Ok(Some(lsp::CompletionResponse::Array(vec![
lsp::CompletionItem {
label: "Range".into(),
sort_text: Some("a".into()),
..Default::default()
},
lsp::CompletionItem {
label: "r".into(),
sort_text: Some("b".into()),
..Default::default()
},
lsp::CompletionItem {
label: "ret".into(),
sort_text: Some("c".into()),
..Default::default()
},
lsp::CompletionItem {
label: "return".into(),
sort_text: Some("d".into()),
..Default::default()
},
lsp::CompletionItem {
label: "slice".into(),
sort_text: Some("d".into()),
..Default::default()
},
])))
});
cx.set_state("");
cx.executor().run_until_parked();
cx.update_editor(|editor, cx| {
editor.show_completions(
&ShowCompletions {
trigger: Some("r".into()),
},
cx,
);
});
cx.executor().run_until_parked();
cx.update_editor(|editor, _| {
if let Some(ContextMenu::Completions(menu)) = editor.context_menu.read().as_ref() {
assert_eq!(
menu.matches.iter().map(|m| &m.string).collect::<Vec<_>>(),
&["r", "ret", "Range", "return"]
);
} else {
panic!("expected completion menu to be open");
}
});
}
#[gpui::test]
async fn test_no_duplicated_completion_requests(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});