44from sqlmesh import macro
55import typing as t
66from sqlmesh .lsp .context import AuditTarget , LSPContext , ModelTarget
7+ from sqlmesh .lsp .custom import ModelCompletion
8+ from sqlmesh .lsp .description import generate_markdown_description
79from sqlmesh .lsp .uri import URI
810
911
@@ -21,7 +23,9 @@ def get_sql_completions(
2123 # Get keywords from file content if provided
2224 file_keywords = set ()
2325 if content :
24- file_keywords = extract_keywords_from_content (content , get_dialect (context , file_uri ))
26+ file_keywords = extract_keywords_from_content (
27+ content , get_dialect (context , file_uri )
28+ )
2529
2630 # Combine keywords - SQL keywords first, then file keywords
2731 all_keywords = list (sql_keywords ) + list (file_keywords - sql_keywords )
@@ -33,31 +37,33 @@ def get_sql_completions(
3337 )
3438
3539
36- def get_models (context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]) -> t .Set [str ]:
40+ def get_models (
41+ context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]
42+ ) -> t .List [ModelCompletion ]:
3743 """
3844 Return a list of models for a given file.
3945
4046 If there is no context, return an empty list.
4147 If there is a context, return a list of all models bar the ones the file itself defines.
4248 """
4349 if context is None :
44- return set ()
50+ return []
4551
46- all_models = set ()
47- # Extract model names from ModelInfo objects
48- for file_info in context .map .values ():
49- if isinstance (file_info , ModelTarget ):
50- all_models .update (file_info .names )
52+ current_path = file_uri .to_path () if file_uri is not None else None
5153
52- # Remove models from the current file
53- path = file_uri .to_path () if file_uri is not None else None
54- if path is not None and path in context .map :
55- file_info = context .map [path ]
56- if isinstance (file_info , ModelTarget ):
57- for model in file_info .names :
58- all_models .discard (model )
54+ completions : t .List [ModelCompletion ] = []
55+ for model in context .context .models .values ():
56+ if current_path is not None and model ._path == current_path :
57+ continue
58+ description = None
59+ try :
60+ description = generate_markdown_description (model )
61+ except Exception :
62+ description = getattr (model , "description" , None )
5963
60- return all_models
64+ completions .append (ModelCompletion (name = model .name , description = description ))
65+
66+ return completions
6167
6268
6369def get_macros (
@@ -79,7 +85,9 @@ def get_macros(
7985 return [MacroCompletion (name = name , description = doc ) for name , doc in macros .items ()]
8086
8187
82- def get_keywords (context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]) -> t .Set [str ]:
88+ def get_keywords (
89+ context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]
90+ ) -> t .Set [str ]:
8391 """
8492 Return a list of sql keywords for a given file.
8593 If no context is provided, return ANSI SQL keywords.
@@ -90,7 +98,11 @@ def get_keywords(context: t.Optional[LSPContext], file_uri: t.Optional[URI]) ->
9098 If both a context and a file_uri are provided, returns the keywords
9199 for the dialect of the model that the file belongs to.
92100 """
93- if file_uri is not None and context is not None and file_uri .to_path () in context .map :
101+ if (
102+ file_uri is not None
103+ and context is not None
104+ and file_uri .to_path () in context .map
105+ ):
94106 file_info = context .map [file_uri .to_path ()]
95107
96108 # Handle ModelInfo objects
@@ -133,11 +145,17 @@ def get_keywords_from_tokenizer(dialect: t.Optional[str] = None) -> t.Set[str]:
133145 return expanded_keywords
134146
135147
136- def get_dialect (context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]) -> t .Optional [str ]:
148+ def get_dialect (
149+ context : t .Optional [LSPContext ], file_uri : t .Optional [URI ]
150+ ) -> t .Optional [str ]:
137151 """
138152 Get the dialect for a given file.
139153 """
140- if file_uri is not None and context is not None and file_uri .to_path () in context .map :
154+ if (
155+ file_uri is not None
156+ and context is not None
157+ and file_uri .to_path () in context .map
158+ ):
141159 file_info = context .map [file_uri .to_path ()]
142160
143161 # Handle ModelInfo objects
@@ -158,7 +176,9 @@ def get_dialect(context: t.Optional[LSPContext], file_uri: t.Optional[URI]) -> t
158176 return None
159177
160178
161- def extract_keywords_from_content (content : str , dialect : t .Optional [str ] = None ) -> t .Set [str ]:
179+ def extract_keywords_from_content (
180+ content : str , dialect : t .Optional [str ] = None
181+ ) -> t .Set [str ]:
162182 """
163183 Extract identifiers from SQL content using the tokenizer.
164184
0 commit comments