Skip to content

Commit 7e252f8

Browse files
authored
feat: macro autocomplete has descriptions (#4712)
1 parent 2c1ed26 commit 7e252f8

File tree

5 files changed

+33
-12
lines changed

5 files changed

+33
-12
lines changed

examples/sushi/macros/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
@macro()
77
def add_one(evaluator, column: int):
8-
# typed column will be cast to an int and return an integer back
8+
"""typed column will be cast to an int and return an integer back"""
99
assert isinstance(column, int)
1010
return column + 1
1111

1212

1313
@macro()
1414
def multiply(evaluator, column, num):
15-
# untyped column will be a sqlglot column and return a sqlglot exp "column > 0"
15+
"""untyped column will be a sqlglot column and return a sqlglot exp "column > 0"""
1616
assert isinstance(column, exp.Column)
1717
return column * num
1818

sqlmesh/lsp/completions.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from functools import lru_cache
22
from sqlglot import Dialect, Tokenizer
3-
from sqlmesh.lsp.custom import AllModelsResponse
3+
from sqlmesh.lsp.custom import AllModelsResponse, MacroCompletion
44
from sqlmesh import macro
55
import typing as t
66
from sqlmesh.lsp.context import AuditTarget, LSPContext, ModelTarget
@@ -60,15 +60,23 @@ def get_models(context: t.Optional[LSPContext], file_uri: t.Optional[URI]) -> t.
6060
return all_models
6161

6262

63-
def get_macros(context: t.Optional[LSPContext], file_uri: t.Optional[URI]) -> t.Set[str]:
64-
"""Return a set of all macros with the ``@`` prefix."""
65-
names = set(macro.get_registry())
63+
def get_macros(
64+
context: t.Optional[LSPContext], file_uri: t.Optional[URI]
65+
) -> t.List[MacroCompletion]:
66+
"""Return a list of macros with optional descriptions."""
67+
macros: t.Dict[str, t.Optional[str]] = {}
68+
69+
for name, m in macro.get_registry().items():
70+
macros[name] = getattr(m.func, "__doc__", None)
71+
6672
try:
6773
if context is not None:
68-
names.update(context.context._macros)
74+
for name, m in context.context._macros.items():
75+
macros[name] = getattr(m.func, "__doc__", None)
6976
except Exception:
7077
pass
71-
return names
78+
79+
return [MacroCompletion(name=name, description=doc) for name, doc in macros.items()]
7280

7381

7482
def get_keywords(context: t.Optional[LSPContext], file_uri: t.Optional[URI]) -> t.Set[str]:

sqlmesh/lsp/custom.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@ class AllModelsRequest(CustomMethodRequestBaseClass):
2323
textDocument: types.TextDocumentIdentifier
2424

2525

26+
class MacroCompletion(PydanticModel):
27+
"""Information about a macro for autocompletion."""
28+
29+
name: str
30+
description: t.Optional[str] = None
31+
32+
2633
class AllModelsResponse(CustomMethodResponseBaseClass):
2734
"""
2835
Response to get all the models that are in the current project.
2936
"""
3037

3138
models: t.List[str]
3239
keywords: t.List[str]
33-
macros: t.List[str]
40+
macros: t.List[MacroCompletion]
3441

3542

3643
RENDER_MODEL_FEATURE = "sqlmesh/render_model"

sqlmesh/lsp/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,8 @@ def completion(
625625
and getattr(params.context, "trigger_character", None) == "@"
626626
)
627627

628-
for macro_name in completion_response.macros:
628+
for macro in completion_response.macros:
629+
macro_name = macro.name
629630
insert_text = macro_name if triggered_by_at else f"@{macro_name}"
630631

631632
completion_items.append(
@@ -636,6 +637,7 @@ def completion(
636637
filter_text=macro_name,
637638
kind=types.CompletionItemKind.Function,
638639
detail="SQLMesh Macro",
640+
documentation=macro.description,
639641
)
640642
)
641643

tests/lsp/test_completions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@ def test_get_macros():
3333
file_uri = URI.from_path(file_path)
3434
completions = LSPContext.get_completions(lsp_context, file_uri, file_content)
3535

36-
assert "each" in completions.macros
37-
assert "add_one" in completions.macros
36+
each_macro = next((m for m in completions.macros if m.name == "each"))
37+
assert each_macro.name == "each"
38+
assert each_macro.description
39+
add_one_macro = next((m for m in completions.macros if m.name == "add_one"))
40+
assert add_one_macro.name == "add_one"
41+
assert add_one_macro.description
3842

3943

4044
def test_get_sql_completions_with_context_no_file_uri():

0 commit comments

Comments
 (0)