use tclint as parser / formatter
This commit is contained in:
+82
-13
@@ -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
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user