feat(server/lsp_tclserver): index .def symbols and provide completion items

This commit is contained in:
2026-09-24 07:53:15 +02:00
parent aa0780dd51
commit abf32a5e50
+44 -1
View File
@@ -18,7 +18,8 @@ from tools import checks, incremental_parse, parser
from tools.completion_items import CompletionCollector
from tools.tcloo_symbols import class_completion_items
from tools.tcloo_completion import indexed_classes
from tools.file_sourcing import get_all_psc_files, psc_script_files
from tools.def_symbols import DefSymbols, read_def_symbols
from tools.file_sourcing import get_all_psc_files, psc_defined_event_files, psc_script_files
from tools.formatter import NxFormatter as Formatter
from tools.index_cache import FileStat, IndexCache, file_stat
from tools.inlay_hint import InlayHintSignature, build_custom_inlay_signatures
@@ -61,6 +62,8 @@ class TclLanguageServer(LanguageServer):
self.psc_script_paths: list[str] = []
self._psc_files: dict[str, list[pathlib.Path]] = {}
self._psc_lock = threading.RLock()
# .def path -> BLOCK_TEMPLATE/ADDRESS names, in PSC DefinedEvents order.
self.def_symbols: dict[str, DefSymbols] = {}
self.navigation_indexes: dict[str, FileSymbolIndex] = {}
self.variable_indexes: dict[
str,
@@ -252,8 +255,48 @@ class TclLanguageServer(LanguageServer):
classes.update(indexes.get(self._normalized_path(path), {}))
return classes
def refresh_def_symbols(self, roots, report=LOGGER.warning):
"""Read the block templates and addresses of all .def files listed as PSC DefinedEvents."""
symbols: dict[str, DefSymbols] = {}
for root in roots:
for psc in get_all_psc_files(root):
try:
def_files = psc_defined_event_files(psc)
except (OSError, ET.ParseError) as error:
report(f"Could not read PSC {psc}: {error}")
continue
for def_file in def_files:
if str(def_file) in symbols:
continue
try:
symbols[str(def_file)] = read_def_symbols(def_file)
except OSError as error:
report(f"Could not read DEF file {def_file}: {error}")
with self._index_lock:
self.def_symbols = symbols
def _def_symbol_items(self, attribute: str, kind, description: str) -> list[lsp.CompletionItem]:
with self._index_lock:
symbols = dict(self.def_symbols)
return [
lsp.CompletionItem(
label=name,
kind=kind,
detail=f"{description} ({pathlib.Path(path).name})",
)
for path, def_symbols in symbols.items()
for name in getattr(def_symbols, attribute)
]
def block_template_items(self) -> list[lsp.CompletionItem]:
return self._def_symbol_items("block_templates", lsp.CompletionItemKind.Struct, "Block template")
def address_items(self) -> list[lsp.CompletionItem]:
return self._def_symbol_items("addresses", lsp.CompletionItemKind.Field, "Address")
def refresh_psc_scripts(self, roots, report=LOGGER.warning):
"""Index PSC dependencies through the same pipeline as workspace procs."""
self.refresh_def_symbols(roots, report=report)
with self._psc_lock:
discovered = {}
for root in roots: