mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
completions: Complete available namespaces
Add completions for namespaces in the typelib path that can be imported. Accepting the completion automatically adds an import statement.
This commit is contained in:
parent
461fe25316
commit
21f138fa83
3 changed files with 37 additions and 7 deletions
|
@ -23,7 +23,7 @@ from . import annotations, gir, language
|
||||||
from .ast_utils import AstNode
|
from .ast_utils import AstNode
|
||||||
from .completions_utils import *
|
from .completions_utils import *
|
||||||
from .language.types import ClassName
|
from .language.types import ClassName
|
||||||
from .lsp_utils import Completion, CompletionItemKind
|
from .lsp_utils import Completion, CompletionItemKind, TextEdit
|
||||||
from .parser import SKIP_TOKENS
|
from .parser import SKIP_TOKENS
|
||||||
from .tokenizer import Token, TokenType
|
from .tokenizer import Token, TokenType
|
||||||
|
|
||||||
|
@ -96,14 +96,32 @@ def using_gtk(_ctx: CompletionContext):
|
||||||
)
|
)
|
||||||
def namespace(ctx: CompletionContext):
|
def namespace(ctx: CompletionContext):
|
||||||
yield Completion("Gtk", CompletionItemKind.Module, text="Gtk.")
|
yield Completion("Gtk", CompletionItemKind.Module, text="Gtk.")
|
||||||
|
|
||||||
|
imported_namespaces = set(["Gtk"])
|
||||||
|
|
||||||
for ns in ctx.ast_node.root.children[language.Import]:
|
for ns in ctx.ast_node.root.children[language.Import]:
|
||||||
if ns.gir_namespace is not None:
|
if ns.gir_namespace is not None:
|
||||||
|
imported_namespaces.add(ns.gir_namespace.name)
|
||||||
yield Completion(
|
yield Completion(
|
||||||
ns.gir_namespace.name,
|
ns.gir_namespace.name,
|
||||||
CompletionItemKind.Module,
|
CompletionItemKind.Module,
|
||||||
text=ns.gir_namespace.name + ".",
|
text=ns.gir_namespace.name + ".",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for ns, version in gir.get_available_namespaces():
|
||||||
|
if ns not in imported_namespaces:
|
||||||
|
yield Completion(
|
||||||
|
ns,
|
||||||
|
CompletionItemKind.Module,
|
||||||
|
text=ns + ".",
|
||||||
|
signature=f" using {ns} {version}",
|
||||||
|
additional_text_edits=[
|
||||||
|
TextEdit(
|
||||||
|
ctx.ast_node.root.import_range(ns), f"\nusing {ns} {version};"
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@completer(
|
@completer(
|
||||||
applies_in=[language.UI, language.ObjectContent, language.Template],
|
applies_in=[language.UI, language.ObjectContent, language.Template],
|
||||||
|
|
|
@ -110,16 +110,22 @@ class UI(AstNode):
|
||||||
and self.template.class_name.glib_type_name == id
|
and self.template.class_name.glib_type_name == id
|
||||||
)
|
)
|
||||||
|
|
||||||
def import_code_action(self, ns: str, version: str) -> CodeAction:
|
def import_range(self, ns: str):
|
||||||
if len(self.children[Import]):
|
"""Returns a range to insert a new import statement"""
|
||||||
pos = self.children[Import][-1].range.end
|
|
||||||
else:
|
|
||||||
pos = self.children[GtkDirective][0].range.end
|
pos = self.children[GtkDirective][0].range.end
|
||||||
|
|
||||||
|
# try to insert alphabetically
|
||||||
|
for import_ in self.children[Import]:
|
||||||
|
if ns.lower() > import_.namespace.lower():
|
||||||
|
pos = import_.range.end
|
||||||
|
|
||||||
|
return Range(pos, pos, self.group.text)
|
||||||
|
|
||||||
|
def import_code_action(self, ns: str, version: str) -> CodeAction:
|
||||||
return CodeAction(
|
return CodeAction(
|
||||||
f"Import {ns} {version}",
|
f"Import {ns} {version}",
|
||||||
f"\nusing {ns} {version};",
|
f"\nusing {ns} {version};",
|
||||||
Range(pos, pos, self.group.text),
|
self.import_range(ns),
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
|
|
@ -87,6 +87,7 @@ class Completion:
|
||||||
text: T.Optional[str] = None
|
text: T.Optional[str] = None
|
||||||
snippet: T.Optional[str] = None
|
snippet: T.Optional[str] = None
|
||||||
detail: T.Optional[str] = None
|
detail: T.Optional[str] = None
|
||||||
|
additional_text_edits: T.Optional[T.List["TextEdit"]] = None
|
||||||
|
|
||||||
def to_json(self, snippets: bool):
|
def to_json(self, snippets: bool):
|
||||||
insert_text = self.text or self.label
|
insert_text = self.text or self.label
|
||||||
|
@ -114,6 +115,11 @@ class Completion:
|
||||||
"insertText": insert_text,
|
"insertText": insert_text,
|
||||||
"insertTextFormat": insert_text_format,
|
"insertTextFormat": insert_text_format,
|
||||||
"detail": self.detail if self.detail else None,
|
"detail": self.detail if self.detail else None,
|
||||||
|
"additionalTextEdits": (
|
||||||
|
[edit.to_json() for edit in self.additional_text_edits]
|
||||||
|
if self.additional_text_edits
|
||||||
|
else None
|
||||||
|
),
|
||||||
}
|
}
|
||||||
return {k: v for k, v in result.items() if v is not None}
|
return {k: v for k, v in result.items() if v is not None}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue