editor: Improve code completion filtering to provide fewer and more accurate suggestions (#32928)

Closes #32756

- Uses `filter_text` from LSP source to filter items in completion list.
This fixes noisy lists like on typing `await` in Rust, it would suggest
`await.or`, `await.and`, etc., which are bad suggestions. Fallbacks to
label.
- Add `penalize_length` flag to fuzzy matcher, which was the default
behavior across. Now, this flag is set to `false` just for code
completion fuzzy matching. This fixes the case where if the query is
`unreac` and the completion items are `unreachable` and
`unreachable!()`, the item with a shorter length would have a larger
score than the other one, which is not right in the case of
auto-complete context. Now these two items will have the same fuzzy
score, and LSP `sort_text` will take over in finalizing its ranking.
- Updated test to be more utility based rather than example based. This
will help to iterate/verify logic faster on what's going on.

Before/After:

await: 
<img width="600" alt="before-await"
src="https://github.com/user-attachments/assets/384138dd-a90d-4942-a430-6ae15df37268"
/>
<img width="600" alt="after-await"
src="https://github.com/user-attachments/assets/d05a10fa-bae5-49bd-9fe7-9933ff215f29"
/>

iter:
<img width="600" alt="before-iter"
src="https://github.com/user-attachments/assets/6e57ffe9-007d-4b17-9cc2-d48fc0176c8e"
/>
<img width="600" alt="after-iter"
src="https://github.com/user-attachments/assets/a8577a9f-dcc8-4fd6-9ba0-b7590584ec31"
/>

opt:
<img width="600" alt="opt-before"
src="https://github.com/user-attachments/assets/d45b6c52-c9ee-4bf3-8552-d5e3fdbecbff"
/>
<img width="600" alt="opt-after"
src="https://github.com/user-attachments/assets/daac11a8-9699-48f8-b441-19fe9803848d"
/>

Release Notes:

- Improved code completion filtering to provide fewer and more accurate
suggestions.
This commit is contained in:
Smit Barmase 2025-06-18 16:01:28 +05:30 committed by GitHub
parent 65067dad9e
commit 131f2857a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 303 additions and 430 deletions

View file

@ -5303,6 +5303,16 @@ impl ProjectItem for Buffer {
}
impl Completion {
pub fn filter_text(&self) -> &str {
match &self.source {
CompletionSource::Lsp { lsp_completion, .. } => lsp_completion
.filter_text
.as_deref()
.unwrap_or_else(|| self.label.filter_text()),
_ => self.label.filter_text(),
}
}
pub fn kind(&self) -> Option<CompletionItemKind> {
self.source
// `lsp::CompletionListItemDefaults` has no `kind` field
@ -5319,17 +5329,18 @@ impl Completion {
/// A key that can be used to sort completions when displaying
/// them to the user.
pub fn sort_key(&self) -> (usize, &str) {
const DEFAULT_KIND_KEY: usize = 3;
const DEFAULT_KIND_KEY: usize = 4;
let kind_key = self
.kind()
.and_then(|lsp_completion_kind| match lsp_completion_kind {
lsp::CompletionItemKind::KEYWORD => Some(0),
lsp::CompletionItemKind::VARIABLE => Some(1),
lsp::CompletionItemKind::CONSTANT => Some(2),
lsp::CompletionItemKind::PROPERTY => Some(3),
_ => None,
})
.unwrap_or(DEFAULT_KIND_KEY);
(kind_key, &self.label.text[self.label.filter_range.clone()])
(kind_key, &self.label.filter_text())
}
/// Whether this completion is a snippet.