diff --git a/blueprintcompiler/completions.py b/blueprintcompiler/completions.py index b5a0721..a4e86b9 100644 --- a/blueprintcompiler/completions.py +++ b/blueprintcompiler/completions.py @@ -137,7 +137,7 @@ def translation_domain(ctx: CompletionContext): ) -def _ns_prefix_completions(ctx: CompletionContext): +def _available_namespace_completions(ctx: CompletionContext): imported_namespaces = set( [import_.namespace for import_ in ctx.ast_node.root.using] ) @@ -176,7 +176,7 @@ def namespace(ctx: CompletionContext): ), ) - yield from _ns_prefix_completions(ctx) + yield from _available_namespace_completions(ctx) @completer( @@ -234,38 +234,12 @@ def property_completer(ctx: CompletionContext): assert isinstance(ctx.ast_node, language.ObjectContent) if ctx.ast_node.gir_class and hasattr(ctx.ast_node.gir_class, "properties"): for prop_name, prop in ctx.ast_node.gir_class.properties.items(): - if str(ctx.next_token) == ":": - snippet = prop_name - elif ( - isinstance(prop.type, gir.BoolType) - and ctx.client_supports_completion_choice - ): - snippet = f"{prop_name}: ${{1|true,false|}};" - elif isinstance(prop.type, gir.StringType): - snippet = ( - f'{prop_name}: _("$0");' - if annotations.is_property_translated(prop) - else f'{prop_name}: "$0";' - ) - elif ( - isinstance(prop.type, gir.Enumeration) - and len(prop.type.members) <= 10 - and ctx.client_supports_completion_choice - ): - choices = ",".join(prop.type.members.keys()) - snippet = f"{prop_name}: ${{1|{choices}|}};" - elif prop.type.full_name == "Gtk.Expression": - snippet = f"{prop_name}: expr $0;" - else: - snippet = f"{prop_name}: $0;" - - yield Completion( + yield get_property_completion( prop_name, - CompletionItemKind.Property, - sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, prop_name), - snippet=snippet, - docs=prop.doc, - detail=prop.detail, + prop, + ctx, + annotations.is_property_translated(prop), + prop.doc, ) @@ -319,8 +293,6 @@ def prop_value_completer(ctx: CompletionContext): sort_text=get_sort_key(CompletionPriority.KEYWORD, "null"), ) - yield from _ns_prefix_completions(ctx) - for id, obj in ctx.ast_node.root.context[language.ScopeCtx].objects.items(): if obj.gir_class is not None and obj.gir_class.assignable_to( vt.value_type @@ -332,21 +304,26 @@ def prop_value_completer(ctx: CompletionContext): sort_text=get_sort_key(CompletionPriority.NAMED_OBJECT, id), ) - for ns in ctx.ast_node.root.gir.namespaces.values(): - for c in ns.classes.values(): - if not c.abstract and c.assignable_to(vt.value_type): - name = c.name if ns.name == "Gtk" else ns.name + "." + c.name - snippet = name - if str(ctx.next_token) != "{": - snippet += " {\n $0\n}" - yield Completion( - name, - CompletionItemKind.Class, - sort_text=get_sort_key(CompletionPriority.CLASS, name), - snippet=snippet, - detail=c.detail, - docs=c.doc, - ) + if isinstance(ctx.ast_node, language.Property): + yield from _available_namespace_completions(ctx) + + for ns in ctx.ast_node.root.gir.namespaces.values(): + for c in ns.classes.values(): + if not c.abstract and c.assignable_to(vt.value_type): + name = ( + c.name if ns.name == "Gtk" else ns.name + "." + c.name + ) + snippet = name + if str(ctx.next_token) != "{": + snippet += " {\n $0\n}" + yield Completion( + name, + CompletionItemKind.Class, + sort_text=get_sort_key(CompletionPriority.CLASS, name), + snippet=snippet, + detail=c.detail, + docs=c.doc, + ) @completer( diff --git a/blueprintcompiler/completions_utils.py b/blueprintcompiler/completions_utils.py index 4d9ceb2..bfca55a 100644 --- a/blueprintcompiler/completions_utils.py +++ b/blueprintcompiler/completions_utils.py @@ -22,8 +22,9 @@ import typing as T from dataclasses import dataclass from enum import Enum +from . import gir from .ast_utils import AstNode -from .lsp_utils import Completion +from .lsp_utils import Completion, CompletionItemKind from .tokenizer import Token, TokenType @@ -110,3 +111,37 @@ def completer(applies_in: T.List, matches: T.List = [], applies_in_subclass=None return inner return decorator + + +def get_property_completion( + name: str, + type: gir.GirType, + ctx: CompletionContext, + translated: bool, + doc: str, +) -> Completion: + if str(ctx.next_token) == ":": + snippet = name + elif isinstance(type, gir.BoolType) and ctx.client_supports_completion_choice: + snippet = f"{name}: ${{1|true,false|}};" + elif isinstance(type, gir.StringType): + snippet = f'{name}: _("$0");' if translated else f'{name}: "$0";' + elif ( + isinstance(type, gir.Enumeration) + and len(type.members) <= 10 + and ctx.client_supports_completion_choice + ): + choices = ",".join(type.members.keys()) + snippet = f"{name}: ${{1|{choices}|}};" + elif type.full_name == "Gtk.Expression": + snippet = f"{name}: expr $0;" + else: + snippet = f"{name}: $0;" + + return Completion( + name, + CompletionItemKind.Property, + sort_text=get_sort_key(CompletionPriority.OBJECT_MEMBER, name), + snippet=snippet, + docs=doc, + ) diff --git a/blueprintcompiler/language/gtk_a11y.py b/blueprintcompiler/language/gtk_a11y.py index cd52746..7f90b6e 100644 --- a/blueprintcompiler/language/gtk_a11y.py +++ b/blueprintcompiler/language/gtk_a11y.py @@ -25,7 +25,7 @@ from .gobject_object import ObjectContent, validate_parent_type from .values import Value -def get_property_types(gir): +def get_property_types(gir: gir.GirContext) -> T.Dict[str, T.Optional[GirType]]: # from return { "autocomplete": gir.get_type("AccessibleAutocomplete", "Gtk"), @@ -50,7 +50,7 @@ def get_property_types(gir): } -def get_relation_types(gir): +def get_relation_types(gir: gir.GirContext) -> T.Dict[str, T.Optional[GirType]]: # from widget = gir.get_type("Widget", "Gtk") return { @@ -75,7 +75,7 @@ def get_relation_types(gir): } -def get_state_types(gir): +def get_state_types(gir: gir.GirContext) -> T.Dict[str, T.Optional[GirType]]: # from return { "busy": BoolType(), @@ -89,6 +89,20 @@ def get_state_types(gir): } +TRANSLATED = set( + [ + "description", + "help-text", + "label", + "placeholder", + "role-description", + "value-text", + "col-index-text", + "row-index-text", + ] +) + + def get_types(gir): return { **get_property_types(gir), @@ -247,12 +261,14 @@ def a11y_completer(_ctx: CompletionContext): applies_in=[ExtAccessibility], matches=new_statement_patterns, ) -def a11y_name_completer(ctx: CompletionContext): +def a11y_property_completer(ctx: CompletionContext): for name, type in get_types(ctx.ast_node.root.gir).items(): - yield Completion( + yield get_property_completion( name, - CompletionItemKind.Property, - docs=_get_docs(ctx.ast_node.root.gir, type.name), + type, + ctx, + name in TRANSLATED, + _get_docs(ctx.ast_node.root.gir, name), )