feat(tcl): add dynamic argument completion and snippets
The changes add dynamic, semantic argument completion for Tcl commands and snippet support. - Introduces DynamicCompletionKind, TclArgumentCompletion, and dynamic rules for Tcl to provide variable, procedure, namespace, and path suggestions. - Adds snippet-backed commands and arguments for Tcl blocks and paths. - Refactors tcl_argument_completion and updates the LSP to use dynamic path, variable, and namespace completions with snippet kinds.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Set
|
||||
|
||||
from tclint.syntax_tree import Command, Node, Script
|
||||
from tclint.syntax_tree import List as TclList
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -18,13 +18,14 @@ def _normalize_var_name(raw_name: str | None) -> str | None:
|
||||
return None
|
||||
|
||||
base = raw_name.split("(", 1)[0]
|
||||
if base.startswith("::"):
|
||||
base = base[2:]
|
||||
base = base.removeprefix("::")
|
||||
|
||||
return base or None
|
||||
|
||||
|
||||
def build_variable_index(source: str, tree: Node | None = None) -> tuple[Set[str], Dict[str, Set[str]], List[ProcRange]]:
|
||||
def build_variable_index(
|
||||
source: str, tree: Node | None = None
|
||||
) -> tuple[set[str], dict[str, set[str]], list[ProcRange]]:
|
||||
"""
|
||||
Parse Tcl source text and build:
|
||||
- globals: set of variable names considered global suggestions
|
||||
@@ -40,9 +41,9 @@ def build_variable_index(source: str, tree: Node | None = None) -> tuple[Set[str
|
||||
"""
|
||||
_ = source # Kept for signature compatibility with callers.
|
||||
|
||||
globals_set: Set[str] = set()
|
||||
procs: Dict[str, Set[str]] = {}
|
||||
proc_ranges: List[ProcRange] = []
|
||||
globals_set: set[str] = set()
|
||||
procs: dict[str, set[str]] = {}
|
||||
proc_ranges: list[ProcRange] = []
|
||||
|
||||
if tree is None:
|
||||
return globals_set, procs, proc_ranges
|
||||
@@ -54,7 +55,16 @@ def build_variable_index(source: str, tree: Node | None = None) -> tuple[Set[str
|
||||
if routine == "proc" and len(node.args) >= 3 and isinstance(node.args[2], Script):
|
||||
proc_name = _normalize_var_name(getattr(node.args[0], "contents", None))
|
||||
if proc_name is not None:
|
||||
procs.setdefault(proc_name, set())
|
||||
local_variables = procs.setdefault(proc_name, set())
|
||||
for parameter in getattr(node.args[1], "children", []):
|
||||
parameter_node = parameter
|
||||
if isinstance(parameter, TclList) and parameter.children:
|
||||
parameter_node = parameter.children[0]
|
||||
parameter_name = _normalize_var_name(
|
||||
getattr(parameter_node, "contents", None)
|
||||
)
|
||||
if parameter_name is not None:
|
||||
local_variables.add(parameter_name)
|
||||
proc_ranges.append(
|
||||
ProcRange(
|
||||
name=proc_name,
|
||||
|
||||
Reference in New Issue
Block a user