python: Fix autocomplete sorting (#44050)

Closes:
#38727 (Python autocompletion being sorted alphabetically)
<img
src="https://github.com/user-attachments/assets/8208d511-f4a4-41f9-8550-3b24370bf776"
width="400">

<img
src="https://github.com/user-attachments/assets/e7c99d7a-b61e-463b-b0f1-36cd279b3887"
width="400">


Release Notes:
- Improve sort order of pyright/basedpyright code completions
This commit is contained in:
Alexander Andreev
2025-12-03 13:51:18 +01:00
committed by GitHub
parent 4e8f6ddae9
commit a688239113
+33 -1
View File
@@ -101,9 +101,41 @@ impl FromStr for TestRunner {
/// The problem with it is that Pyright adjusts the sort text based on previous resolutions (items for which we've issued `completion/resolve` call have their sortText adjusted),
/// which - long story short - makes completion items list non-stable. Pyright probably relies on VSCode's implementation detail.
/// see https://github.com/microsoft/pyright/blob/95ef4e103b9b2f129c9320427e51b73ea7cf78bd/packages/pyright-internal/src/languageService/completionProvider.ts#LL2873
///
/// upd 02.12.25:
/// Decided to ignore Pyright's sortText() completely and to manually sort all entries
fn process_pyright_completions(items: &mut [lsp::CompletionItem]) {
for item in items {
item.sort_text.take();
let is_dunder = item.label.starts_with("__") && item.label.ends_with("__");
let visibility_priority = if is_dunder {
'3'
} else if item.label.starts_with("__") {
'2' // private non-dunder
} else if item.label.starts_with('_') {
'1' // protected
} else {
'0' // public
};
// Kind priority within same visibility level
let kind_priority = match item.kind {
Some(lsp::CompletionItemKind::ENUM_MEMBER) => '0',
Some(lsp::CompletionItemKind::FIELD) => '1',
Some(lsp::CompletionItemKind::PROPERTY) => '2',
Some(lsp::CompletionItemKind::VARIABLE) => '3',
Some(lsp::CompletionItemKind::CONSTANT) => '4',
Some(lsp::CompletionItemKind::METHOD) => '5',
Some(lsp::CompletionItemKind::FUNCTION) => '5',
Some(lsp::CompletionItemKind::CLASS) => '6',
Some(lsp::CompletionItemKind::MODULE) => '7',
_ => '8',
};
item.sort_text = Some(format!(
"{}{}{}",
visibility_priority, kind_priority, item.label
));
}
}