use tclint as parser / formatter

This commit is contained in:
2025-07-27 17:55:48 +02:00
parent c34dac847a
commit c6f0758b97
132 changed files with 10193 additions and 10794 deletions
+82 -13
View File
@@ -12,7 +12,7 @@ import re
import sys
import sysconfig
import traceback
from typing import Any, Optional, Sequence
from typing import Any, Optional, Sequence, Tuple
import re
@@ -42,16 +42,67 @@ import lsp_jsonrpc as jsonrpc
import lsp_utils as utils
import lsprotocol.types as lsp
from pygls import server, uris, workspace
from pygls.workspace.text_document import TextDocument
from common.load_data import standard_items
from common.formatter import format_tcl
from tclint.parser import Parser
from tclint.format import Formatter, FormatterOpts
from tools.semantic_tokens import (
SemanticTokenCollector,
collect_semantic_tokens,
encode_tokens,
)
from tools.nx_plugins import commands
class TclLanguageServer(server.LanguageServer):
def format(
self,
document: TextDocument,
options: lsp.FormattingOptions,
range: Optional[Tuple[int, int]] = None,
):
parser = Parser()
parser._commands.update(commands)
tree = parser.parse(document.source)
log_to_output(tree.pretty(2))
indent = "\t" if not options.insert_spaces else " " * options.tab_size
formatter = Formatter(
FormatterOpts(
indent=indent,
spaces_in_braces=False,
max_blank_lines=500,
indent_namespace_eval=True,
),
)
if range is not None:
start, end = range
return formatter.format_partial(document.source[start:end], parser)
return formatter.format_top(document.source, parser)
WORKSPACE_SETTINGS = {}
GLOBAL_SETTINGS = {}
RUNNER = pathlib.Path(__file__).parent / "lsp_runner.py"
TOKEN_TYPES = [
"command",
"variable",
"function",
"string",
"number",
"keyword",
"comment",
]
TOKEN_MODIFIERS = []
MAX_WORKERS = 5
LSP_SERVER = server.LanguageServer(
LSP_SERVER = TclLanguageServer(
name="NX Postprocessor Support", version="0.0.1", max_workers=MAX_WORKERS
)
@@ -104,6 +155,17 @@ def on_completion(params: lsp.CompletionParams) -> list[lsp.CompletionItem]:
return lsp.CompletionList(is_incomplete=False, items=items)
@LSP_SERVER.feature(lsp.TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL)
def on_semantic_tokens(params: lsp.SemanticTokensParams):
doc = LSP_SERVER.workspace.get_document(params.text_document.uri)
code = doc.source
tokens = collect_semantic_tokens(code)
data = encode_tokens(tokens)
return lsp.SemanticTokens(data=data)
@LSP_SERVER.feature(lsp.TEXT_DOCUMENT_HOVER)
def hover(params: lsp.HoverParams) -> lsp.Hover:
pos = params.position
@@ -189,19 +251,19 @@ def hover(params: lsp.HoverParams) -> lsp.Hover:
def formatting(params: lsp.DocumentFormattingParams) -> list[lsp.TextEdit] | None:
"""LSP handler for textDocument/formatting request."""
doc = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
text = doc.source
formatted = text
if GLOBAL_SETTINGS.get("formatter", False):
formatted = format_tcl(text)
source = doc.source
start = lsp.Position(line=0, character=0)
last_line = source.rsplit("\n", 1)[-1]
end = lsp.Position(line=source.count("\n"), character=len(last_line))
last_line = len(text.splitlines())
full_range = lsp.Range(
start=lsp.Position(line=0, character=0),
end=lsp.Position(line=last_line, character=0),
)
edit = lsp.TextEdit(range=full_range, new_text=formatted)
return [edit]
formatted = LSP_SERVER.format(doc, params.options)
return [
lsp.TextEdit(
range=lsp.Range(start=start, end=end),
new_text=formatted,
)
]
# **********************************************************
@@ -232,9 +294,16 @@ def initialize(params: lsp.InitializeParams) -> lsp.InitializeResult:
log_to_output(
f"Global settings:\r\n{json.dumps(GLOBAL_SETTINGS, indent=4, ensure_ascii=False)}\r\n"
)
semantic_tokens_legend = lsp.SemanticTokensLegend(
token_types=TOKEN_TYPES,
token_modifiers=TOKEN_MODIFIERS,
)
return lsp.InitializeResult(
capabilities=lsp.ServerCapabilities(
document_formatting_provider=GLOBAL_SETTINGS.get("formatter", True),
semantic_tokens_provider=lsp.SemanticTokensOptions(
legend=semantic_tokens_legend, full=True, range=False
),
)
)