update
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
from tclint.syntax_tree import Visitor, BareWord, BracedWord, Script, Command
|
||||
from tclint.parser import Parser
|
||||
import lsprotocol.types as lsp
|
||||
|
||||
|
||||
class OutlineVisitor(Visitor):
|
||||
def __init__(self, parser: Parser):
|
||||
self.parser = parser
|
||||
self.stack = [[]] # Root symbol list
|
||||
|
||||
def _range(self, node) -> lsp.Range:
|
||||
line = node.line - 1
|
||||
col = node.col - 1
|
||||
if node.end_pos:
|
||||
end_line = node.end_pos[0] - 1
|
||||
end_col = node.end_pos[1] - 1
|
||||
else:
|
||||
end_line = line
|
||||
end_col = col + 1
|
||||
|
||||
return lsp.Range(
|
||||
start=lsp.Position(line=line, character=col),
|
||||
end=lsp.Position(line=end_line, character=end_col),
|
||||
)
|
||||
|
||||
def _add(self, name: str, kind: lsp.SymbolKind, node, children=None):
|
||||
symbol = lsp.DocumentSymbol(
|
||||
name=name,
|
||||
kind=kind,
|
||||
range=self._range(node),
|
||||
selection_range=self._range(node),
|
||||
children=children or [],
|
||||
)
|
||||
self.stack[-1].append(symbol)
|
||||
return symbol
|
||||
|
||||
def visit_script(self, script):
|
||||
for child in script.children:
|
||||
child.accept(self, recurse=False)
|
||||
|
||||
def visit_command(self, command: Command):
|
||||
if not isinstance(command.routine, BareWord):
|
||||
return
|
||||
name = command.routine.contents
|
||||
|
||||
# --- NAMESPACE EVAL ---
|
||||
if name == "namespace" and len(command.args) >= 3:
|
||||
subcmd = command.args[0]
|
||||
if isinstance(subcmd, BareWord) and subcmd.contents == "eval":
|
||||
ns_arg = command.args[1]
|
||||
ns_name = (
|
||||
ns_arg.contents if isinstance(ns_arg, BareWord) else "<namespace>"
|
||||
)
|
||||
ns_body = command.args[2]
|
||||
|
||||
ns_symbol = self._add(
|
||||
ns_name, lsp.SymbolKind.Namespace, command, children=[]
|
||||
)
|
||||
self.stack.append(ns_symbol.children)
|
||||
|
||||
if isinstance(ns_body, BracedWord):
|
||||
try:
|
||||
subtree = self.parser.parse_script(ns_body)
|
||||
subtree.accept(self, recurse=False)
|
||||
except Exception as e:
|
||||
print(f"Failed parsing namespace body: {e}")
|
||||
|
||||
self.stack.pop()
|
||||
|
||||
# --- PROC ---
|
||||
elif name == "proc" and len(command.args) >= 1:
|
||||
proc_arg = command.args[0]
|
||||
proc_name = (
|
||||
proc_arg.contents if isinstance(proc_arg, BareWord) else "<proc>"
|
||||
)
|
||||
self._add(proc_name, lsp.SymbolKind.Function, command)
|
||||
|
||||
# --- SET ---
|
||||
elif name == "set" and len(command.args) >= 1:
|
||||
var_arg = command.args[0]
|
||||
var_name = var_arg.contents if isinstance(var_arg, BareWord) else "<var>"
|
||||
self._add(var_name, lsp.SymbolKind.Variable, command)
|
||||
Reference in New Issue
Block a user