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:
parent
65067dad9e
commit
131f2857a5
45 changed files with 303 additions and 430 deletions
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue