From d0394136cfd153004c1e889becb6021a00a59b93 Mon Sep 17 00:00:00 2001 From: James Westman Date: Sun, 5 Jan 2025 14:16:29 -0600 Subject: [PATCH] completions: Sort completion items --- blueprintcompiler/completions.py | 31 ++++++++++++--- blueprintcompiler/completions_utils.py | 16 ++++++++ .../language/adw_response_dialog.py | 5 ++- blueprintcompiler/language/gtk_a11y.py | 5 ++- .../language/gtk_combo_box_text.py | 7 +++- blueprintcompiler/language/gtk_file_filter.py | 19 +++++++-- blueprintcompiler/language/gtk_layout.py | 7 +++- blueprintcompiler/language/gtk_menu.py | 39 ++++++++++++++++--- blueprintcompiler/language/gtk_scale.py | 7 +++- blueprintcompiler/language/gtk_size_group.py | 7 +++- blueprintcompiler/language/gtk_string_list.py | 7 +++- blueprintcompiler/language/gtk_styles.py | 7 +++- 12 files changed, 135 insertions(+), 22 deletions(-) diff --git a/blueprintcompiler/completions.py b/blueprintcompiler/completions.py index be881fa..b5a0721 100644 --- a/blueprintcompiler/completions.py +++ b/blueprintcompiler/completions.py @@ -110,6 +110,7 @@ def using(ctx: CompletionContext): f"using {ns} {version}", CompletionItemKind.Module, text=f"using {ns} {version};", + sort_text=get_sort_key(CompletionPriority.NAMESPACE, ns), ) @@ -130,6 +131,7 @@ def translation_domain(ctx: CompletionContext): yield Completion( "translation-domain", CompletionItemKind.Keyword, + sort_text=get_sort_key(CompletionPriority.KEYWORD, "translation-domain"), snippet='translation-domain "$0";', docs=get_docs_section("Syntax TranslationDomain"), ) @@ -146,6 +148,7 @@ def _ns_prefix_completions(ctx: CompletionContext): ns, CompletionItemKind.Module, text=ns + ".", + sort_text=get_sort_key(CompletionPriority.IMPORT_NAMESPACE, ns), signature=f" using {ns} {version}", additional_text_edits=[ TextEdit( @@ -168,6 +171,9 @@ def namespace(ctx: CompletionContext): ns.gir_namespace.name, CompletionItemKind.Module, text=ns.gir_namespace.name + ".", + sort_text=get_sort_key( + CompletionPriority.NAMESPACE, ns.gir_namespace.name + ), ) yield from _ns_prefix_completions(ctx) @@ -191,6 +197,7 @@ def object_completer(ctx: CompletionContext): yield Completion( c.name, CompletionItemKind.Class, + sort_text=get_sort_key(CompletionPriority.CLASS, c.name), snippet=snippet, docs=c.doc, detail=c.detail, @@ -212,6 +219,7 @@ def gtk_object_completer(ctx: CompletionContext): yield Completion( c.name, CompletionItemKind.Class, + sort_text=get_sort_key(CompletionPriority.CLASS, c.name), snippet=snippet, docs=c.doc, detail=c.detail, @@ -254,7 +262,7 @@ def property_completer(ctx: CompletionContext): yield Completion( prop_name, CompletionItemKind.Property, - sort_text=f"0 {prop_name}", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, prop_name), snippet=snippet, docs=prop.doc, detail=prop.detail, @@ -272,6 +280,7 @@ def prop_value_completer(ctx: CompletionContext): CompletionItemKind.Keyword, snippet="bind $0", docs=get_docs_section("Syntax Binding"), + sort_text=get_sort_key(CompletionPriority.KEYWORD, "bind"), ) assert isinstance(ctx.ast_node, language.Property) or isinstance( @@ -286,11 +295,20 @@ def prop_value_completer(ctx: CompletionContext): CompletionItemKind.EnumMember, docs=member.doc, detail=member.detail, + sort_text=get_sort_key(CompletionPriority.ENUM_MEMBER, name), ) elif isinstance(vt.value_type, gir.BoolType): - yield Completion("true", CompletionItemKind.Constant) - yield Completion("false", CompletionItemKind.Constant) + yield Completion( + "true", + CompletionItemKind.Constant, + sort_text=get_sort_key(CompletionPriority.ENUM_MEMBER, "true"), + ) + yield Completion( + "false", + CompletionItemKind.Constant, + sort_text=get_sort_key(CompletionPriority.ENUM_MEMBER, "false"), + ) elif isinstance(vt.value_type, gir.Class) or isinstance( vt.value_type, gir.Interface @@ -298,6 +316,7 @@ def prop_value_completer(ctx: CompletionContext): yield Completion( "null", CompletionItemKind.Constant, + sort_text=get_sort_key(CompletionPriority.KEYWORD, "null"), ) yield from _ns_prefix_completions(ctx) @@ -309,7 +328,8 @@ def prop_value_completer(ctx: CompletionContext): yield Completion( id, CompletionItemKind.Variable, - detail=obj.signature, + signature=" " + obj.signature, + sort_text=get_sort_key(CompletionPriority.NAMED_OBJECT, id), ) for ns in ctx.ast_node.root.gir.namespaces.values(): @@ -322,6 +342,7 @@ def prop_value_completer(ctx: CompletionContext): yield Completion( name, CompletionItemKind.Class, + sort_text=get_sort_key(CompletionPriority.CLASS, name), snippet=snippet, detail=c.detail, docs=c.doc, @@ -355,7 +376,7 @@ def signal_completer(ctx: CompletionContext): yield Completion( signal_name, CompletionItemKind.Event, - sort_text=f"1 {signal_name}", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, signal_name), snippet=snippet, docs=signal.doc, detail=signal.detail, diff --git a/blueprintcompiler/completions_utils.py b/blueprintcompiler/completions_utils.py index eb0bb79..4d9ceb2 100644 --- a/blueprintcompiler/completions_utils.py +++ b/blueprintcompiler/completions_utils.py @@ -20,12 +20,28 @@ import typing as T from dataclasses import dataclass +from enum import Enum from .ast_utils import AstNode from .lsp_utils import Completion from .tokenizer import Token, TokenType +class CompletionPriority(Enum): + ENUM_MEMBER = "00" + NAMED_OBJECT = "01" + OBJECT_MEMBER = "02" + CLASS = "03" + NAMESPACE = "04" + KEYWORD = "05" + # An available namespace that hasn't been imported yet + IMPORT_NAMESPACE = "99" + + +def get_sort_key(priority: CompletionPriority, name: str): + return f"{priority.value} {name}" + + @dataclass class CompletionContext: client_supports_completion_choice: bool diff --git a/blueprintcompiler/language/adw_response_dialog.py b/blueprintcompiler/language/adw_response_dialog.py index 516c69a..c621df0 100644 --- a/blueprintcompiler/language/adw_response_dialog.py +++ b/blueprintcompiler/language/adw_response_dialog.py @@ -156,7 +156,10 @@ def complete_adw_message_dialog(_ctx: CompletionContext): ) def complete_adw_alert_dialog(_ctx: CompletionContext): yield Completion( - "responses", CompletionItemKind.Keyword, snippet="responses [\n\t$0\n]" + "responses", + CompletionItemKind.Keyword, + snippet="responses [\n\t$0\n]", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "responses"), ) diff --git a/blueprintcompiler/language/gtk_a11y.py b/blueprintcompiler/language/gtk_a11y.py index a8bf300..cd52746 100644 --- a/blueprintcompiler/language/gtk_a11y.py +++ b/blueprintcompiler/language/gtk_a11y.py @@ -236,7 +236,10 @@ class ExtAccessibility(AstNode): ) def a11y_completer(_ctx: CompletionContext): yield Completion( - "accessibility", CompletionItemKind.Snippet, snippet="accessibility {\n $0\n}" + "accessibility", + CompletionItemKind.Snippet, + snippet="accessibility {\n $0\n}", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "accessibility"), ) diff --git a/blueprintcompiler/language/gtk_combo_box_text.py b/blueprintcompiler/language/gtk_combo_box_text.py index e162cca..5a7a892 100644 --- a/blueprintcompiler/language/gtk_combo_box_text.py +++ b/blueprintcompiler/language/gtk_combo_box_text.py @@ -95,7 +95,12 @@ class ExtComboBoxItems(AstNode): matches=new_statement_patterns, ) def items_completer(_ctx: CompletionContext): - yield Completion("items", CompletionItemKind.Snippet, snippet="items [$0]") + yield Completion( + "items", + CompletionItemKind.Snippet, + snippet="items [$0]", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "items"), + ) @decompiler("items", parent_type="Gtk.ComboBoxText") diff --git a/blueprintcompiler/language/gtk_file_filter.py b/blueprintcompiler/language/gtk_file_filter.py index 754130a..d0e53d2 100644 --- a/blueprintcompiler/language/gtk_file_filter.py +++ b/blueprintcompiler/language/gtk_file_filter.py @@ -103,10 +103,23 @@ ext_file_filter_suffixes = create_node("suffixes", "suffix") ) def file_filter_completer(_ctx: CompletionContext): yield Completion( - "mime-types", CompletionItemKind.Snippet, snippet='mime-types ["$0"]' + "mime-types", + CompletionItemKind.Snippet, + snippet='mime-types ["$0"]', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "mime-types"), + ) + yield Completion( + "patterns", + CompletionItemKind.Snippet, + snippet='patterns ["$0"]', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "patterns"), + ) + yield Completion( + "suffixes", + CompletionItemKind.Snippet, + snippet='suffixes ["$0"]', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "suffixes"), ) - yield Completion("patterns", CompletionItemKind.Snippet, snippet='patterns ["$0"]') - yield Completion("suffixes", CompletionItemKind.Snippet, snippet='suffixes ["$0"]') @decompiler("mime-types") diff --git a/blueprintcompiler/language/gtk_layout.py b/blueprintcompiler/language/gtk_layout.py index 901c40d..63bc0f6 100644 --- a/blueprintcompiler/language/gtk_layout.py +++ b/blueprintcompiler/language/gtk_layout.py @@ -94,7 +94,12 @@ class ExtLayout(AstNode): matches=new_statement_patterns, ) def layout_completer(_ctx: CompletionContext): - yield Completion("layout", CompletionItemKind.Snippet, snippet="layout {\n $0\n}") + yield Completion( + "layout", + CompletionItemKind.Snippet, + snippet="layout {\n $0\n}", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "layout"), + ) @decompiler("layout") diff --git a/blueprintcompiler/language/gtk_menu.py b/blueprintcompiler/language/gtk_menu.py index d5bf4fb..ed7ede8 100644 --- a/blueprintcompiler/language/gtk_menu.py +++ b/blueprintcompiler/language/gtk_menu.py @@ -253,21 +253,48 @@ def menu_completer(_ctx: CompletionContext): ) def menu_content_completer(_ctx: CompletionContext): yield Completion( - "submenu", CompletionItemKind.Snippet, snippet="submenu {\n $0\n}" + "submenu", + CompletionItemKind.Snippet, + snippet="submenu {\n $0\n}", + sort_text=get_sort_key(CompletionPriority.CLASS, "1 submenu"), ) yield Completion( - "section", CompletionItemKind.Snippet, snippet="section {\n $0\n}" + "section", + CompletionItemKind.Snippet, + snippet="section {\n $0\n}", + sort_text=get_sort_key(CompletionPriority.CLASS, "1 section"), + ) + yield Completion( + "item", + CompletionItemKind.Snippet, + snippet="item {\n $0\n}", + sort_text=get_sort_key(CompletionPriority.CLASS, "1 item"), ) - yield Completion("item", CompletionItemKind.Snippet, snippet="item {\n $0\n}") yield Completion( "item (shorthand)", CompletionItemKind.Snippet, snippet='item (_("${1:Label}"), "${2:action-name}", "${3:icon-name}")', + sort_text=get_sort_key(CompletionPriority.CLASS, "0 item (shorthand)"), ) - yield Completion("label", CompletionItemKind.Snippet, snippet="label: $0;") - yield Completion("action", CompletionItemKind.Snippet, snippet='action: "$0";') - yield Completion("icon", CompletionItemKind.Snippet, snippet='icon: "$0";') + yield Completion( + "label", + CompletionItemKind.Snippet, + snippet="label: $0;", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "label"), + ) + yield Completion( + "action", + CompletionItemKind.Snippet, + snippet='action: "$0";', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "action"), + ) + yield Completion( + "icon", + CompletionItemKind.Snippet, + snippet='icon: "$0";', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "icon"), + ) @decompiler("menu") diff --git a/blueprintcompiler/language/gtk_scale.py b/blueprintcompiler/language/gtk_scale.py index 2615a67..21089a4 100644 --- a/blueprintcompiler/language/gtk_scale.py +++ b/blueprintcompiler/language/gtk_scale.py @@ -138,7 +138,12 @@ class ExtScaleMarks(AstNode): matches=new_statement_patterns, ) def complete_marks(_ctx: CompletionContext): - yield Completion("marks", CompletionItemKind.Keyword, snippet="marks [\n\t$0\n]") + yield Completion( + "marks", + CompletionItemKind.Keyword, + snippet="marks [\n\t$0\n]", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "marks"), + ) @completer( diff --git a/blueprintcompiler/language/gtk_size_group.py b/blueprintcompiler/language/gtk_size_group.py index 3505a06..d30eef9 100644 --- a/blueprintcompiler/language/gtk_size_group.py +++ b/blueprintcompiler/language/gtk_size_group.py @@ -105,7 +105,12 @@ class ExtSizeGroupWidgets(AstNode): matches=new_statement_patterns, ) def size_group_completer(_ctx: CompletionContext): - yield Completion("widgets", CompletionItemKind.Snippet, snippet="widgets [$0]") + yield Completion( + "widgets", + CompletionItemKind.Snippet, + snippet="widgets [$0]", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "widgets"), + ) @decompiler("widgets") diff --git a/blueprintcompiler/language/gtk_string_list.py b/blueprintcompiler/language/gtk_string_list.py index 0e6c00a..a4fa3b5 100644 --- a/blueprintcompiler/language/gtk_string_list.py +++ b/blueprintcompiler/language/gtk_string_list.py @@ -76,7 +76,12 @@ class ExtStringListStrings(AstNode): matches=new_statement_patterns, ) def strings_completer(_ctx: CompletionContext): - yield Completion("strings", CompletionItemKind.Snippet, snippet="strings [$0]") + yield Completion( + "strings", + CompletionItemKind.Snippet, + snippet="strings [$0]", + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "strings"), + ) @decompiler("items", parent_type="Gtk.StringList") diff --git a/blueprintcompiler/language/gtk_styles.py b/blueprintcompiler/language/gtk_styles.py index 0cdea0b..7c9252c 100644 --- a/blueprintcompiler/language/gtk_styles.py +++ b/blueprintcompiler/language/gtk_styles.py @@ -81,7 +81,12 @@ class ExtStyles(AstNode): matches=new_statement_patterns, ) def style_completer(_ctx: CompletionContext): - yield Completion("styles", CompletionItemKind.Keyword, snippet='styles ["$0"]') + yield Completion( + "styles", + CompletionItemKind.Keyword, + snippet='styles ["$0"]', + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, "styles"), + ) @decompiler("style")