refactor(lsp): cache analysis results and debounce diagnostics
build_and_puplish.yml / build_and_publish (release) Successful in 29s

This change adds cached and incremental analysis for the LSP
server to improve responsiveness. The client now debounces
diagnostic updates to avoid excessive recomputation. The
server introduces per-document line caches and various
caches for completions, inlay hints, and metadata to
support faster, incremental updates.

- Debounce diagnostics on text changes to reduce noise.
- Add caches for completions, inlay hints, and metadata.
- Introduce incremental analysis with per-document line caches.
This commit is contained in:
Christoph Brandau
2026-08-19 13:41:53 +02:00
parent ecb50be2b8
commit af195a577b
11 changed files with 616 additions and 181 deletions
+9 -4
View File
@@ -1,8 +1,9 @@
from tclint.syntax_tree import Visitor, Command, BareWord, List
import lsprotocol.types as lsp
from common.load_data import standard_items
from tclint.syntax_tree import BareWord, Command, List, Visitor
BUILTIN_VAR_LABELS = {ci.label for ci in standard_items.nx_variables}
BUILTIN_PROC_LABELS = {ci.label for ci in standard_items.nx_procs}
class CompletionItems:
@@ -22,6 +23,7 @@ class CompletionCollector(Visitor):
def __init__(self):
super().__init__()
self._custom_functions: list[lsp.CompletionItem] = []
self._custom_function_keys: set[tuple[str, lsp.CompletionItemKind | None]] = set()
self._proc_signatures = {}
@property
@@ -34,8 +36,11 @@ class CompletionCollector(Visitor):
def _append_unique(self, item: lsp.CompletionItem):
# Avoid duplicate labels within the same file scan
if not any(ci.label == item.label for ci in self._custom_functions):
self._custom_functions.append(item)
key = (item.label, item.kind)
if key in self._custom_function_keys:
return
self._custom_function_keys.add(key)
self._custom_functions.append(item)
def visit_command(self, command: Command):
routine = command.routine
@@ -46,7 +51,7 @@ class CompletionCollector(Visitor):
if not getattr(first_arg, "value", None):
return
if any(item.label == first_arg.value for item in standard_items.nx_procs):
if first_arg.value in BUILTIN_PROC_LABELS:
return
# Record proc name as a completion item