mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-06 16:19:07 -04:00
Compare commits
1 commit
72583be267
...
3ba85d1e47
Author | SHA1 | Date | |
---|---|---|---|
|
3ba85d1e47 |
13 changed files with 122 additions and 97 deletions
|
@ -31,13 +31,18 @@ Pattern = T.List[T.Tuple[TokenType, T.Optional[str]]]
|
||||||
|
|
||||||
|
|
||||||
def _complete(
|
def _complete(
|
||||||
lsp, ast_node: AstNode, tokens: T.List[Token], idx: int, token_idx: int
|
lsp,
|
||||||
|
ast_node: AstNode,
|
||||||
|
tokens: T.List[Token],
|
||||||
|
idx: int,
|
||||||
|
token_idx: int,
|
||||||
|
next_token: Token,
|
||||||
) -> T.Iterator[Completion]:
|
) -> T.Iterator[Completion]:
|
||||||
for child in ast_node.children:
|
for child in ast_node.children:
|
||||||
if child.group.start <= idx and (
|
if child.group.start <= idx and (
|
||||||
idx < child.group.end or (idx == child.group.end and child.incomplete)
|
idx < child.group.end or (idx == child.group.end and child.incomplete)
|
||||||
):
|
):
|
||||||
yield from _complete(lsp, child, tokens, idx, token_idx)
|
yield from _complete(lsp, child, tokens, idx, token_idx, next_token)
|
||||||
return
|
return
|
||||||
|
|
||||||
prev_tokens: T.List[Token] = []
|
prev_tokens: T.List[Token] = []
|
||||||
|
@ -50,7 +55,7 @@ def _complete(
|
||||||
token_idx -= 1
|
token_idx -= 1
|
||||||
|
|
||||||
for completer in ast_node.completers:
|
for completer in ast_node.completers:
|
||||||
yield from completer(prev_tokens, ast_node, lsp)
|
yield from completer(prev_tokens, next_token, ast_node, lsp)
|
||||||
|
|
||||||
|
|
||||||
def complete(
|
def complete(
|
||||||
|
@ -62,16 +67,24 @@ def complete(
|
||||||
if token.start < idx <= token.end:
|
if token.start < idx <= token.end:
|
||||||
token_idx = i
|
token_idx = i
|
||||||
|
|
||||||
|
if tokens[token_idx].type == TokenType.EOF:
|
||||||
|
next_token = tokens[token_idx]
|
||||||
|
else:
|
||||||
|
next_token_idx = token_idx + 1
|
||||||
|
while tokens[next_token_idx].type == TokenType.WHITESPACE:
|
||||||
|
next_token_idx += 1
|
||||||
|
next_token = tokens[next_token_idx]
|
||||||
|
|
||||||
# if the current token is an identifier or whitespace, move to the token before it
|
# if the current token is an identifier or whitespace, move to the token before it
|
||||||
while tokens[token_idx].type in [TokenType.IDENT, TokenType.WHITESPACE]:
|
while tokens[token_idx].type in [TokenType.IDENT, TokenType.WHITESPACE]:
|
||||||
idx = tokens[token_idx].start
|
idx = tokens[token_idx].start
|
||||||
token_idx -= 1
|
token_idx -= 1
|
||||||
|
|
||||||
yield from _complete(lsp, ast_node, tokens, idx, token_idx)
|
yield from _complete(lsp, ast_node, tokens, idx, token_idx, next_token)
|
||||||
|
|
||||||
|
|
||||||
@completer([language.GtkDirective])
|
@completer([language.GtkDirective])
|
||||||
def using_gtk(lsp, ast_node, match_variables):
|
def using_gtk(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"using Gtk 4.0", CompletionItemKind.Keyword, snippet="using Gtk 4.0;\n"
|
"using Gtk 4.0", CompletionItemKind.Keyword, snippet="using Gtk 4.0;\n"
|
||||||
)
|
)
|
||||||
|
@ -81,9 +94,9 @@ def using_gtk(lsp, ast_node, match_variables):
|
||||||
applies_in=[language.UI, language.ObjectContent, language.Template],
|
applies_in=[language.UI, language.ObjectContent, language.Template],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def namespace(lsp, ast_node, match_variables):
|
def namespace(ctx: CompletionContext):
|
||||||
yield Completion("Gtk", CompletionItemKind.Module, text="Gtk.")
|
yield Completion("Gtk", CompletionItemKind.Module, text="Gtk.")
|
||||||
for ns in 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:
|
||||||
yield Completion(
|
yield Completion(
|
||||||
ns.gir_namespace.name,
|
ns.gir_namespace.name,
|
||||||
|
@ -99,14 +112,18 @@ def namespace(lsp, ast_node, match_variables):
|
||||||
[(TokenType.IDENT, None), (TokenType.OP, ".")],
|
[(TokenType.IDENT, None), (TokenType.OP, ".")],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def object_completer(lsp, ast_node, match_variables):
|
def object_completer(ctx: CompletionContext):
|
||||||
ns = ast_node.root.gir.namespaces.get(match_variables[0])
|
ns = ctx.ast_node.root.gir.namespaces.get(ctx.match_variables[0])
|
||||||
if ns is not None:
|
if ns is not None:
|
||||||
for c in ns.classes.values():
|
for c in ns.classes.values():
|
||||||
|
snippet = c.name
|
||||||
|
if str(ctx.next_token) != "{":
|
||||||
|
snippet += " {\n $0\n}"
|
||||||
|
|
||||||
yield Completion(
|
yield Completion(
|
||||||
c.name,
|
c.name,
|
||||||
CompletionItemKind.Class,
|
CompletionItemKind.Class,
|
||||||
snippet=f"{c.name} {{\n $0\n}}",
|
snippet=snippet,
|
||||||
docs=c.doc,
|
docs=c.doc,
|
||||||
detail=c.detail,
|
detail=c.detail,
|
||||||
)
|
)
|
||||||
|
@ -116,14 +133,18 @@ def object_completer(lsp, ast_node, match_variables):
|
||||||
applies_in=[language.UI, language.ObjectContent, language.Template],
|
applies_in=[language.UI, language.ObjectContent, language.Template],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def gtk_object_completer(lsp, ast_node, match_variables):
|
def gtk_object_completer(ctx: CompletionContext):
|
||||||
ns = ast_node.root.gir.namespaces.get("Gtk")
|
ns = ctx.ast_node.root.gir.namespaces.get("Gtk")
|
||||||
if ns is not None:
|
if ns is not None:
|
||||||
for c in ns.classes.values():
|
for c in ns.classes.values():
|
||||||
|
snippet = c.name
|
||||||
|
if str(ctx.next_token) != "{":
|
||||||
|
snippet += " {\n $0\n}"
|
||||||
|
|
||||||
yield Completion(
|
yield Completion(
|
||||||
c.name,
|
c.name,
|
||||||
CompletionItemKind.Class,
|
CompletionItemKind.Class,
|
||||||
snippet=f"{c.name} {{\n $0\n}}",
|
snippet=snippet,
|
||||||
docs=c.doc,
|
docs=c.doc,
|
||||||
detail=c.detail,
|
detail=c.detail,
|
||||||
)
|
)
|
||||||
|
@ -133,27 +154,34 @@ def gtk_object_completer(lsp, ast_node, match_variables):
|
||||||
applies_in=[language.ObjectContent],
|
applies_in=[language.ObjectContent],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def property_completer(lsp, ast_node, match_variables):
|
def property_completer(ctx: CompletionContext):
|
||||||
if ast_node.gir_class and hasattr(ast_node.gir_class, "properties"):
|
assert isinstance(ctx.ast_node, language.ObjectContent)
|
||||||
for prop_name, prop in ast_node.gir_class.properties.items():
|
if ctx.ast_node.gir_class and hasattr(ctx.ast_node.gir_class, "properties"):
|
||||||
if (
|
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)
|
isinstance(prop.type, gir.BoolType)
|
||||||
and lsp.client_supports_completion_choice
|
and ctx.client_supports_completion_choice
|
||||||
):
|
):
|
||||||
yield Completion(
|
snippet = f"{prop_name}: ${{1|true,false|}};"
|
||||||
prop_name,
|
|
||||||
CompletionItemKind.Property,
|
|
||||||
sort_text=f"0 {prop_name}",
|
|
||||||
snippet=f"{prop_name}: ${{1|true,false|}};",
|
|
||||||
docs=prop.doc,
|
|
||||||
detail=prop.detail,
|
|
||||||
)
|
|
||||||
elif isinstance(prop.type, gir.StringType):
|
elif isinstance(prop.type, gir.StringType):
|
||||||
snippet = (
|
snippet = (
|
||||||
f'{prop_name}: _("$0");'
|
f'{prop_name}: _("$0");'
|
||||||
if annotations.is_property_translated(prop)
|
if annotations.is_property_translated(prop)
|
||||||
else f'{prop_name}: "$0";'
|
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 Completion(
|
||||||
prop_name,
|
prop_name,
|
||||||
|
@ -163,46 +191,18 @@ def property_completer(lsp, ast_node, match_variables):
|
||||||
docs=prop.doc,
|
docs=prop.doc,
|
||||||
detail=prop.detail,
|
detail=prop.detail,
|
||||||
)
|
)
|
||||||
elif (
|
|
||||||
isinstance(prop.type, gir.Enumeration)
|
|
||||||
and len(prop.type.members) <= 10
|
|
||||||
and lsp.client_supports_completion_choice
|
|
||||||
):
|
|
||||||
choices = ",".join(prop.type.members.keys())
|
|
||||||
yield Completion(
|
|
||||||
prop_name,
|
|
||||||
CompletionItemKind.Property,
|
|
||||||
sort_text=f"0 {prop_name}",
|
|
||||||
snippet=f"{prop_name}: ${{1|{choices}|}};",
|
|
||||||
docs=prop.doc,
|
|
||||||
detail=prop.detail,
|
|
||||||
)
|
|
||||||
elif prop.type.full_name == "Gtk.Expression":
|
|
||||||
yield Completion(
|
|
||||||
prop_name,
|
|
||||||
CompletionItemKind.Property,
|
|
||||||
sort_text=f"0 {prop_name}",
|
|
||||||
snippet=f"{prop_name}: expr $0;",
|
|
||||||
docs=prop.doc,
|
|
||||||
detail=prop.detail,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
yield Completion(
|
|
||||||
prop_name,
|
|
||||||
CompletionItemKind.Property,
|
|
||||||
sort_text=f"0 {prop_name}",
|
|
||||||
snippet=f"{prop_name}: $0;",
|
|
||||||
docs=prop.doc,
|
|
||||||
detail=prop.detail,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@completer(
|
@completer(
|
||||||
applies_in=[language.Property, language.A11yProperty],
|
applies_in=[language.Property, language.A11yProperty],
|
||||||
matches=[[(TokenType.IDENT, None), (TokenType.OP, ":")]],
|
matches=[[(TokenType.IDENT, None), (TokenType.OP, ":")]],
|
||||||
)
|
)
|
||||||
def prop_value_completer(lsp, ast_node, match_variables):
|
def prop_value_completer(ctx: CompletionContext):
|
||||||
if (vt := ast_node.value_type) is not None:
|
assert isinstance(ctx.ast_node, language.Property) or isinstance(
|
||||||
|
ctx.ast_node, language.A11yProperty
|
||||||
|
)
|
||||||
|
|
||||||
|
if (vt := ctx.ast_node.value_type) is not None:
|
||||||
if isinstance(vt.value_type, gir.Enumeration):
|
if isinstance(vt.value_type, gir.Enumeration):
|
||||||
for name, member in vt.value_type.members.items():
|
for name, member in vt.value_type.members.items():
|
||||||
yield Completion(
|
yield Completion(
|
||||||
|
@ -221,30 +221,38 @@ def prop_value_completer(lsp, ast_node, match_variables):
|
||||||
applies_in=[language.ObjectContent],
|
applies_in=[language.ObjectContent],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def signal_completer(lsp, ast_node, match_variables):
|
def signal_completer(ctx: CompletionContext):
|
||||||
if ast_node.gir_class and hasattr(ast_node.gir_class, "signals"):
|
assert isinstance(ctx.ast_node, language.ObjectContent)
|
||||||
for signal_name, signal in ast_node.gir_class.signals.items():
|
|
||||||
if not isinstance(ast_node.parent, language.Object):
|
if ctx.ast_node.gir_class and hasattr(ctx.ast_node.gir_class, "signals"):
|
||||||
|
for signal_name, signal in ctx.ast_node.gir_class.signals.items():
|
||||||
|
if str(ctx.next_token) == "=>":
|
||||||
|
snippet = signal_name
|
||||||
|
else:
|
||||||
|
if not isinstance(ctx.ast_node.parent, language.Object):
|
||||||
name = "on"
|
name = "on"
|
||||||
else:
|
else:
|
||||||
name = "on_" + (
|
name = "on_" + (
|
||||||
ast_node.parent.children[ClassName][0].tokens["id"]
|
ctx.ast_node.parent.children[ClassName][0].tokens["id"]
|
||||||
or ast_node.parent.children[ClassName][0]
|
or ctx.ast_node.parent.children[ClassName][0]
|
||||||
.tokens["class_name"]
|
.tokens["class_name"]
|
||||||
.lower()
|
.lower()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
snippet = f"{signal_name} => \\$${{1:${name}_{signal_name.replace('-', '_')}}}()$0;"
|
||||||
|
|
||||||
yield Completion(
|
yield Completion(
|
||||||
signal_name,
|
signal_name,
|
||||||
CompletionItemKind.Event,
|
CompletionItemKind.Event,
|
||||||
sort_text=f"1 {signal_name}",
|
sort_text=f"1 {signal_name}",
|
||||||
snippet=f"{signal_name} => \\$${{1:${name}_{signal_name.replace('-', '_')}}}()$0;",
|
snippet=snippet,
|
||||||
docs=signal.doc,
|
docs=signal.doc,
|
||||||
detail=signal.detail,
|
detail=signal.detail,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@completer(applies_in=[language.UI], matches=new_statement_patterns)
|
@completer(applies_in=[language.UI], matches=new_statement_patterns)
|
||||||
def template_completer(lsp, ast_node, match_variables):
|
def template_completer(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"template",
|
"template",
|
||||||
CompletionItemKind.Snippet,
|
CompletionItemKind.Snippet,
|
||||||
|
|
|
@ -19,10 +19,21 @@
|
||||||
|
|
||||||
|
|
||||||
import typing as T
|
import typing as T
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from .ast_utils import AstNode
|
||||||
from .lsp_utils import Completion
|
from .lsp_utils import Completion
|
||||||
from .tokenizer import Token, TokenType
|
from .tokenizer import Token, TokenType
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CompletionContext:
|
||||||
|
client_supports_completion_choice: bool
|
||||||
|
ast_node: AstNode
|
||||||
|
match_variables: T.List[str]
|
||||||
|
next_token: Token
|
||||||
|
|
||||||
|
|
||||||
new_statement_patterns = [
|
new_statement_patterns = [
|
||||||
[(TokenType.PUNCTUATION, "{")],
|
[(TokenType.PUNCTUATION, "{")],
|
||||||
[(TokenType.PUNCTUATION, "}")],
|
[(TokenType.PUNCTUATION, "}")],
|
||||||
|
@ -32,8 +43,8 @@ new_statement_patterns = [
|
||||||
|
|
||||||
|
|
||||||
def completer(applies_in: T.List, matches: T.List = [], applies_in_subclass=None):
|
def completer(applies_in: T.List, matches: T.List = [], applies_in_subclass=None):
|
||||||
def decorator(func):
|
def decorator(func: T.Callable[[CompletionContext], T.Generator[Completion]]):
|
||||||
def inner(prev_tokens: T.List[Token], ast_node, lsp):
|
def inner(prev_tokens: T.List[Token], next_token: Token, ast_node, lsp):
|
||||||
# For completers that apply in ObjectContent nodes, we can further
|
# For completers that apply in ObjectContent nodes, we can further
|
||||||
# check that the object is the right class
|
# check that the object is the right class
|
||||||
if applies_in_subclass is not None:
|
if applies_in_subclass is not None:
|
||||||
|
@ -66,7 +77,13 @@ def completer(applies_in: T.List, matches: T.List = [], applies_in_subclass=None
|
||||||
if not any_match:
|
if not any_match:
|
||||||
return
|
return
|
||||||
|
|
||||||
yield from func(lsp, ast_node, match_variables)
|
context = CompletionContext(
|
||||||
|
client_supports_completion_choice=lsp.client_supports_completion_choice,
|
||||||
|
ast_node=ast_node,
|
||||||
|
match_variables=match_variables,
|
||||||
|
next_token=next_token,
|
||||||
|
)
|
||||||
|
yield from func(context)
|
||||||
|
|
||||||
for c in applies_in:
|
for c in applies_in:
|
||||||
c.completers.append(inner)
|
c.completers.append(inner)
|
||||||
|
|
|
@ -143,7 +143,7 @@ class ExtAdwResponseDialog(AstNode):
|
||||||
applies_in_subclass=("Adw", "MessageDialog"),
|
applies_in_subclass=("Adw", "MessageDialog"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def complete_adw_message_dialog(lsp, ast_node, match_variables):
|
def complete_adw_message_dialog(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"responses", CompletionItemKind.Keyword, snippet="responses [\n\t$0\n]"
|
"responses", CompletionItemKind.Keyword, snippet="responses [\n\t$0\n]"
|
||||||
)
|
)
|
||||||
|
@ -154,7 +154,7 @@ def complete_adw_message_dialog(lsp, ast_node, match_variables):
|
||||||
applies_in_subclass=("Adw", "AlertDialog"),
|
applies_in_subclass=("Adw", "AlertDialog"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def complete_adw_alert_dialog(lsp, ast_node, match_variables):
|
def complete_adw_alert_dialog(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"responses", CompletionItemKind.Keyword, snippet="responses [\n\t$0\n]"
|
"responses", CompletionItemKind.Keyword, snippet="responses [\n\t$0\n]"
|
||||||
)
|
)
|
||||||
|
|
|
@ -232,7 +232,7 @@ class ExtAccessibility(AstNode):
|
||||||
applies_in=[ObjectContent],
|
applies_in=[ObjectContent],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def a11y_completer(lsp, ast_node, match_variables):
|
def a11y_completer(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"accessibility", CompletionItemKind.Snippet, snippet="accessibility {\n $0\n}"
|
"accessibility", CompletionItemKind.Snippet, snippet="accessibility {\n $0\n}"
|
||||||
)
|
)
|
||||||
|
@ -242,12 +242,12 @@ def a11y_completer(lsp, ast_node, match_variables):
|
||||||
applies_in=[ExtAccessibility],
|
applies_in=[ExtAccessibility],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def a11y_name_completer(lsp, ast_node, match_variables):
|
def a11y_name_completer(ctx: CompletionContext):
|
||||||
for name, type in get_types(ast_node.root.gir).items():
|
for name, type in get_types(ctx.ast_node.root.gir).items():
|
||||||
yield Completion(
|
yield Completion(
|
||||||
name,
|
name,
|
||||||
CompletionItemKind.Property,
|
CompletionItemKind.Property,
|
||||||
docs=_get_docs(ast_node.root.gir, type.name),
|
docs=_get_docs(ctx.ast_node.root.gir, type.name),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class ExtComboBoxItems(AstNode):
|
||||||
applies_in_subclass=("Gtk", "ComboBoxText"),
|
applies_in_subclass=("Gtk", "ComboBoxText"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def items_completer(lsp, ast_node, match_variables):
|
def items_completer(_ctx: CompletionContext):
|
||||||
yield Completion("items", CompletionItemKind.Snippet, snippet="items [$0]")
|
yield Completion("items", CompletionItemKind.Snippet, snippet="items [$0]")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ ext_file_filter_suffixes = create_node("suffixes", "suffix")
|
||||||
applies_in_subclass=("Gtk", "FileFilter"),
|
applies_in_subclass=("Gtk", "FileFilter"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def file_filter_completer(lsp, ast_node, match_variables):
|
def file_filter_completer(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"mime-types", CompletionItemKind.Snippet, snippet='mime-types ["$0"]'
|
"mime-types", CompletionItemKind.Snippet, snippet='mime-types ["$0"]'
|
||||||
)
|
)
|
||||||
|
|
|
@ -93,7 +93,7 @@ class ExtLayout(AstNode):
|
||||||
applies_in_subclass=("Gtk", "Widget"),
|
applies_in_subclass=("Gtk", "Widget"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def layout_completer(lsp, ast_node, match_variables):
|
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}")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,7 @@ from .ui import UI
|
||||||
applies_in=[UI],
|
applies_in=[UI],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def menu_completer(lsp, ast_node, match_variables):
|
def menu_completer(_ctx: CompletionContext):
|
||||||
yield Completion("menu", CompletionItemKind.Snippet, snippet="menu {\n $0\n}")
|
yield Completion("menu", CompletionItemKind.Snippet, snippet="menu {\n $0\n}")
|
||||||
|
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ def menu_completer(lsp, ast_node, match_variables):
|
||||||
applies_in=[Menu],
|
applies_in=[Menu],
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def menu_content_completer(lsp, ast_node, match_variables):
|
def menu_content_completer(_ctx: CompletionContext):
|
||||||
yield Completion(
|
yield Completion(
|
||||||
"submenu", CompletionItemKind.Snippet, snippet="submenu {\n $0\n}"
|
"submenu", CompletionItemKind.Snippet, snippet="submenu {\n $0\n}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -137,14 +137,14 @@ class ExtScaleMarks(AstNode):
|
||||||
applies_in_subclass=("Gtk", "Scale"),
|
applies_in_subclass=("Gtk", "Scale"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def complete_marks(lsp, ast_node, match_variables):
|
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]")
|
||||||
|
|
||||||
|
|
||||||
@completer(
|
@completer(
|
||||||
applies_in=[ExtScaleMarks],
|
applies_in=[ExtScaleMarks],
|
||||||
)
|
)
|
||||||
def complete_mark(lsp, ast_node, match_variables):
|
def complete_mark(_ctx: CompletionContext):
|
||||||
yield Completion("mark", CompletionItemKind.Keyword, snippet="mark ($0),")
|
yield Completion("mark", CompletionItemKind.Keyword, snippet="mark ($0),")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ class ExtSizeGroupWidgets(AstNode):
|
||||||
applies_in_subclass=("Gtk", "SizeGroup"),
|
applies_in_subclass=("Gtk", "SizeGroup"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def size_group_completer(lsp, ast_node, match_variables):
|
def size_group_completer(_ctx: CompletionContext):
|
||||||
yield Completion("widgets", CompletionItemKind.Snippet, snippet="widgets [$0]")
|
yield Completion("widgets", CompletionItemKind.Snippet, snippet="widgets [$0]")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ExtStringListStrings(AstNode):
|
||||||
applies_in_subclass=("Gtk", "StringList"),
|
applies_in_subclass=("Gtk", "StringList"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def strings_completer(lsp, ast_node, match_variables):
|
def strings_completer(_ctx: CompletionContext):
|
||||||
yield Completion("strings", CompletionItemKind.Snippet, snippet="strings [$0]")
|
yield Completion("strings", CompletionItemKind.Snippet, snippet="strings [$0]")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ class ExtStyles(AstNode):
|
||||||
applies_in_subclass=("Gtk", "Widget"),
|
applies_in_subclass=("Gtk", "Widget"),
|
||||||
matches=new_statement_patterns,
|
matches=new_statement_patterns,
|
||||||
)
|
)
|
||||||
def style_completer(lsp, ast_node, match_variables):
|
def style_completer(_ctx: CompletionContext):
|
||||||
yield Completion("styles", CompletionItemKind.Keyword, snippet='styles ["$0"]')
|
yield Completion("styles", CompletionItemKind.Keyword, snippet='styles ["$0"]')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,11 @@ class TestSamples(unittest.TestCase):
|
||||||
|
|
||||||
def assert_ast_doesnt_crash(self, text, tokens, ast: AstNode):
|
def assert_ast_doesnt_crash(self, text, tokens, ast: AstNode):
|
||||||
lsp = LanguageServer()
|
lsp = LanguageServer()
|
||||||
for i in range(len(text)):
|
for i in range(len(text) + 1):
|
||||||
ast.get_docs(i)
|
ast.get_docs(i)
|
||||||
for i in range(len(text)):
|
for i in range(len(text) + 1):
|
||||||
list(complete(lsp, ast, tokens, i))
|
list(complete(lsp, ast, tokens, i))
|
||||||
for i in range(len(text)):
|
for i in range(len(text) + 1):
|
||||||
ast.get_reference(i)
|
ast.get_reference(i)
|
||||||
ast.get_document_symbols()
|
ast.get_document_symbols()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue