Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aeebb5c964 | ||
|
|
f659db1147 | ||
|
|
b059a75205 | ||
|
|
27e2b3bf6e | ||
|
|
f55c3ba904 | ||
|
|
cb430a5553 | ||
|
|
31ccae9a40 |
@@ -79,7 +79,8 @@ export async function getWorkspaceSettings(
|
|||||||
interpreter: resolveVariables(interpreter, workspace),
|
interpreter: resolveVariables(interpreter, workspace),
|
||||||
importStrategy: config.get<string>(`importStrategy`) ?? "useBundled",
|
importStrategy: config.get<string>(`importStrategy`) ?? "useBundled",
|
||||||
showNotifications: config.get<string>(`showNotifications`) ?? "off",
|
showNotifications: config.get<string>(`showNotifications`) ?? "off",
|
||||||
formatter: config.get<boolean>(`formatter`) ?? true
|
formatter: config.get<boolean>(`formatter`) ?? true,
|
||||||
|
inlayHint: config.get<boolean>(`inlayHint`) ?? true
|
||||||
}
|
}
|
||||||
return workspaceSetting
|
return workspaceSetting
|
||||||
}
|
}
|
||||||
@@ -111,7 +112,8 @@ export async function getGlobalSettings(
|
|||||||
interpreter: interpreter,
|
interpreter: interpreter,
|
||||||
importStrategy: getGlobalValue<string>(config, "importStrategy", "useBundled"),
|
importStrategy: getGlobalValue<string>(config, "importStrategy", "useBundled"),
|
||||||
showNotifications: getGlobalValue<string>(config, "showNotifications", "off"),
|
showNotifications: getGlobalValue<string>(config, "showNotifications", "off"),
|
||||||
formatter: config.get<boolean>(`formatter`) ?? true
|
formatter: config.get<boolean>(`formatter`) ?? true,
|
||||||
|
inlayHint: config.get<boolean>(`inlayHint`) ?? true
|
||||||
}
|
}
|
||||||
return setting
|
return setting
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,8 @@ export function checkIfConfigurationChanged(
|
|||||||
`${namespace}.interpreter`,
|
`${namespace}.interpreter`,
|
||||||
`${namespace}.importStrategy`,
|
`${namespace}.importStrategy`,
|
||||||
`${namespace}.showNotifications`,
|
`${namespace}.showNotifications`,
|
||||||
`${namespace}.formatter`
|
`${namespace}.formatter`,
|
||||||
|
`${namespace}.inlayHint`
|
||||||
]
|
]
|
||||||
const changed = settings.map((s) => e.affectsConfiguration(s))
|
const changed = settings.map((s) => e.affectsConfiguration(s))
|
||||||
return changed.includes(true)
|
return changed.includes(true)
|
||||||
|
|||||||
+6
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "nx-post-support",
|
"name": "nx-post-support",
|
||||||
"displayName": "NX Postprocessor Support",
|
"displayName": "NX Postprocessor Support",
|
||||||
"description": "",
|
"description": "",
|
||||||
"version": "2025.8.1",
|
"version": "2025.9.0",
|
||||||
"publisher": "Christoph",
|
"publisher": "Christoph",
|
||||||
"icon": "images/nx-1.png",
|
"icon": "images/nx-1.png",
|
||||||
"serverInfo": {
|
"serverInfo": {
|
||||||
@@ -85,6 +85,11 @@
|
|||||||
"default": false,
|
"default": false,
|
||||||
"description": "Use the TCL formatter from `NX Postprocessor Support`"
|
"description": "Use the TCL formatter from `NX Postprocessor Support`"
|
||||||
},
|
},
|
||||||
|
"nx-post-support.inlayHint": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"description": "Use the Inlay Hints in from `NX Postprocessor Support`"
|
||||||
|
},
|
||||||
"nx-post-support.importStrategy": {
|
"nx-post-support.importStrategy": {
|
||||||
"default": "useBundled",
|
"default": "useBundled",
|
||||||
"description": "Defines where `NX Postprocessor Support` is imported from.",
|
"description": "Defines where `NX Postprocessor Support` is imported from.",
|
||||||
|
|||||||
@@ -71,6 +71,10 @@
|
|||||||
{
|
{
|
||||||
"label": "expr",
|
"label": "expr",
|
||||||
"kind": "keyword"
|
"kind": "keyword"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "return",
|
||||||
|
"kind": "keyword"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"MOM_procs": [
|
"MOM_procs": [
|
||||||
|
|||||||
+7
-112
@@ -38,123 +38,13 @@ update_sys_path(
|
|||||||
# pylint: disable=wrong-import-position,import-error
|
# pylint: disable=wrong-import-position,import-error
|
||||||
import lsp_jsonrpc as jsonrpc
|
import lsp_jsonrpc as jsonrpc
|
||||||
import lsprotocol.types as lsp
|
import lsprotocol.types as lsp
|
||||||
from pygls import server, uris, workspace
|
from pygls import uris, workspace
|
||||||
from pygls.workspace.text_document import TextDocument
|
|
||||||
from common.load_data import standard_items
|
from common.load_data import standard_items
|
||||||
from tclint.lexer import TclSyntaxError
|
|
||||||
from tclint.format import Formatter, FormatterOpts
|
|
||||||
from tclint.violations import Violation
|
|
||||||
from plugins.poco_plugin import commands
|
|
||||||
from tools import checks, parser
|
|
||||||
from tools.semantic_tokens import _Highlighter, TOKEN_TYPES, TokenModifier
|
from tools.semantic_tokens import _Highlighter, TOKEN_TYPES, TokenModifier
|
||||||
from tools.completion_items import completion, remove_existing_items, remove_shared_keys
|
from tools.completion_items import completion, remove_existing_items, remove_shared_keys
|
||||||
from tools.inlay_hint import InlayHintGenerator
|
from tools.inlay_hint import InlayHintGenerator
|
||||||
from tools.file_sourcing import get_all_psc_files, read_psc_file
|
from tools.file_sourcing import get_all_psc_files, read_psc_file
|
||||||
|
from lsp_tclserver import TclLanguageServer
|
||||||
DIAGNOSTIC_SOURCE = "nx-post-support"
|
|
||||||
|
|
||||||
|
|
||||||
class TclLanguageServer(server.LanguageServer):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.parser = parser.CustomParser()
|
|
||||||
for command in commands:
|
|
||||||
self.parser._commands.update(command)
|
|
||||||
self.diagnostics = {}
|
|
||||||
self.poco_completion: dict = {}
|
|
||||||
self.proc_signatures: dict = {}
|
|
||||||
|
|
||||||
def format(
|
|
||||||
self,
|
|
||||||
document: TextDocument,
|
|
||||||
options: lsp.FormattingOptions,
|
|
||||||
range: Optional[Tuple[int, int]] = None,
|
|
||||||
):
|
|
||||||
# parser = Parser(command_plugins=["nx_plugins.poco_plugin.py"])
|
|
||||||
# parser._commands.update(commands)
|
|
||||||
|
|
||||||
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], self.parser)
|
|
||||||
|
|
||||||
return formatter.format_top(document.source, self.parser)
|
|
||||||
|
|
||||||
def linter(
|
|
||||||
self,
|
|
||||||
document: TextDocument,
|
|
||||||
) -> List[Violation]:
|
|
||||||
violations = []
|
|
||||||
self.parser.violations = []
|
|
||||||
tree = self.parser.parse(document.source)
|
|
||||||
violations += self.parser.violations
|
|
||||||
# log_to_output(tree.pretty(2))
|
|
||||||
for checker in checks.get_checkers():
|
|
||||||
violations += checker.check(document.source, tree)
|
|
||||||
return violations
|
|
||||||
|
|
||||||
def lint(self, document: TextDocument):
|
|
||||||
diagnostics = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
violations = self.linter(document)
|
|
||||||
except TclSyntaxError as e:
|
|
||||||
return [
|
|
||||||
lsp.Diagnostic(
|
|
||||||
message=str(e),
|
|
||||||
severity=lsp.DiagnosticSeverity.Error,
|
|
||||||
range=lsp.Range(
|
|
||||||
start=lsp.Position(e.start[0] - 1, e.start[1] - 1),
|
|
||||||
end=lsp.Position(e.end[0] - 1, e.end[1] - 1),
|
|
||||||
),
|
|
||||||
code="syntax error",
|
|
||||||
source=DIAGNOSTIC_SOURCE,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
for violation in violations:
|
|
||||||
message = violation.message
|
|
||||||
severity = lsp.DiagnosticSeverity.Warning
|
|
||||||
start = lsp.Position(line=violation.start[0] - 1, character=violation.start[1] - 1)
|
|
||||||
end = lsp.Position(line=violation.end[0] - 1, character=violation.end[1] - 1)
|
|
||||||
|
|
||||||
diagnostics.append(
|
|
||||||
lsp.Diagnostic(
|
|
||||||
message=message,
|
|
||||||
severity=severity,
|
|
||||||
range=lsp.Range(
|
|
||||||
start=start,
|
|
||||||
end=end,
|
|
||||||
),
|
|
||||||
code=violation.id,
|
|
||||||
source=DIAGNOSTIC_SOURCE,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return diagnostics
|
|
||||||
|
|
||||||
def _compute_diagnostics(self, document: TextDocument) -> List[lsp.Diagnostic]:
|
|
||||||
return self.lint(document)
|
|
||||||
|
|
||||||
def compute_diagnostics(self, document: TextDocument):
|
|
||||||
# `None` sentinel ensures that `diagnostics` gets updated if the URI is not
|
|
||||||
# present.
|
|
||||||
_, previous = self.diagnostics.get(document, (0, None))
|
|
||||||
|
|
||||||
diagnostics = self._compute_diagnostics(document)
|
|
||||||
|
|
||||||
# Only update if the list has changed
|
|
||||||
if previous != diagnostics:
|
|
||||||
self.diagnostics[document.uri] = (document.version, diagnostics)
|
|
||||||
|
|
||||||
|
|
||||||
WORKSPACE_SETTINGS = {}
|
WORKSPACE_SETTINGS = {}
|
||||||
@@ -204,6 +94,7 @@ def did_change(params: lsp.DidChangeTextDocumentParams) -> None:
|
|||||||
"""LSP handler for textDocument/didChange request"""
|
"""LSP handler for textDocument/didChange request"""
|
||||||
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
||||||
LSP_SERVER.compute_diagnostics(document)
|
LSP_SERVER.compute_diagnostics(document)
|
||||||
|
LSP_SERVER.update_poco_completion_for_file(document)
|
||||||
|
|
||||||
|
|
||||||
@LSP_SERVER.feature(
|
@LSP_SERVER.feature(
|
||||||
@@ -253,6 +144,9 @@ def on_completion(params: lsp.CompletionParams) -> list[lsp.CompletionItem]:
|
|||||||
|
|
||||||
@LSP_SERVER.feature(lsp.TEXT_DOCUMENT_INLAY_HINT)
|
@LSP_SERVER.feature(lsp.TEXT_DOCUMENT_INLAY_HINT)
|
||||||
def inlay_hints(params: lsp.InlayHintParams):
|
def inlay_hints(params: lsp.InlayHintParams):
|
||||||
|
log_to_output(str(GLOBAL_SETTINGS.get("inlayHint", False)))
|
||||||
|
if not GLOBAL_SETTINGS.get("inlayHint", False):
|
||||||
|
return []
|
||||||
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
||||||
tree = LSP_SERVER.parser.parse(document.source)
|
tree = LSP_SERVER.parser.parse(document.source)
|
||||||
|
|
||||||
@@ -474,6 +368,7 @@ def _get_global_defaults():
|
|||||||
"importStrategy": GLOBAL_SETTINGS.get("importStrategy", "useBundled"),
|
"importStrategy": GLOBAL_SETTINGS.get("importStrategy", "useBundled"),
|
||||||
"showNotifications": GLOBAL_SETTINGS.get("showNotifications", "off"),
|
"showNotifications": GLOBAL_SETTINGS.get("showNotifications", "off"),
|
||||||
"formatter": GLOBAL_SETTINGS.get("formatter", True),
|
"formatter": GLOBAL_SETTINGS.get("formatter", True),
|
||||||
|
"inlayHint": GLOBAL_SETTINGS.get("inlayHint", True),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
import logging
|
||||||
|
import pathlib
|
||||||
|
from typing import List, Optional, Tuple
|
||||||
|
import lsprotocol.types as lsp
|
||||||
|
from pygls.workspace.text_document import TextDocument
|
||||||
|
from tclint.lexer import TclSyntaxError
|
||||||
|
from tclint.format import Formatter, FormatterOpts
|
||||||
|
from tclint.violations import Violation
|
||||||
|
from plugins.poco_plugin import commands
|
||||||
|
from tools import checks, parser
|
||||||
|
from pygls import server, uris
|
||||||
|
from tools.completion_items import completion, remove_existing_items, remove_shared_keys
|
||||||
|
|
||||||
|
|
||||||
|
DIAGNOSTIC_SOURCE = "nx-post-support"
|
||||||
|
|
||||||
|
|
||||||
|
class TclLanguageServer(server.LanguageServer):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.parser = parser.CustomParser()
|
||||||
|
for command in commands:
|
||||||
|
self.parser._commands.update(command)
|
||||||
|
self.diagnostics = {}
|
||||||
|
self.poco_completion: dict = {}
|
||||||
|
self.proc_signatures: dict = {}
|
||||||
|
|
||||||
|
def update_poco_completion_for_file(self, document: TextDocument):
|
||||||
|
"""Update poco_completion for a specific file when it changes"""
|
||||||
|
filepath = str(pathlib.Path(uris.to_fs_path(document.uri)))
|
||||||
|
|
||||||
|
# Remove existing completion items for this file
|
||||||
|
if filepath in self.poco_completion:
|
||||||
|
del self.poco_completion[filepath]
|
||||||
|
if filepath in self.proc_signatures:
|
||||||
|
del self.proc_signatures[filepath]
|
||||||
|
|
||||||
|
# Parse and extract new completion items
|
||||||
|
completion.reset()
|
||||||
|
try:
|
||||||
|
tree = self.parser.parse(document.source)
|
||||||
|
tree.accept(completion, recurse=True)
|
||||||
|
remove_existing_items(completion.custom_functions, self.poco_completion)
|
||||||
|
self.poco_completion[filepath] = completion.custom_functions
|
||||||
|
remove_shared_keys(self.proc_signatures, completion.proc_signatures)
|
||||||
|
self.proc_signatures[filepath] = completion.proc_signatures
|
||||||
|
except Exception as e:
|
||||||
|
logging.debug(f"Error parsing {filepath}: {e}")
|
||||||
|
|
||||||
|
def format(
|
||||||
|
self,
|
||||||
|
document: TextDocument,
|
||||||
|
options: lsp.FormattingOptions,
|
||||||
|
range: Optional[Tuple[int, int]] = None,
|
||||||
|
):
|
||||||
|
# parser = Parser(command_plugins=["nx_plugins.poco_plugin.py"])
|
||||||
|
# parser._commands.update(commands)
|
||||||
|
|
||||||
|
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], self.parser)
|
||||||
|
|
||||||
|
return formatter.format_top(document.source, self.parser)
|
||||||
|
|
||||||
|
def linter(
|
||||||
|
self,
|
||||||
|
document: TextDocument,
|
||||||
|
) -> List[Violation]:
|
||||||
|
violations = []
|
||||||
|
self.parser.violations = []
|
||||||
|
tree = self.parser.parse(document.source)
|
||||||
|
violations += self.parser.violations
|
||||||
|
for checker in checks.get_checkers():
|
||||||
|
violations += checker.check(document.source, tree)
|
||||||
|
return violations
|
||||||
|
|
||||||
|
def lint(self, document: TextDocument):
|
||||||
|
diagnostics = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
violations = self.linter(document)
|
||||||
|
except TclSyntaxError as e:
|
||||||
|
return [
|
||||||
|
lsp.Diagnostic(
|
||||||
|
message=str(e),
|
||||||
|
severity=lsp.DiagnosticSeverity.Error,
|
||||||
|
range=lsp.Range(
|
||||||
|
start=lsp.Position(e.start[0] - 1, e.start[1] - 1),
|
||||||
|
end=lsp.Position(e.end[0] - 1, e.end[1] - 1),
|
||||||
|
),
|
||||||
|
code="syntax error",
|
||||||
|
source=DIAGNOSTIC_SOURCE,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
for violation in violations:
|
||||||
|
message = violation.message
|
||||||
|
severity = lsp.DiagnosticSeverity.Warning
|
||||||
|
start = lsp.Position(line=violation.start[0] - 1, character=violation.start[1] - 1)
|
||||||
|
end = lsp.Position(line=violation.end[0] - 1, character=violation.end[1] - 1)
|
||||||
|
|
||||||
|
diagnostics.append(
|
||||||
|
lsp.Diagnostic(
|
||||||
|
message=message,
|
||||||
|
severity=severity,
|
||||||
|
range=lsp.Range(
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
),
|
||||||
|
code=violation.id,
|
||||||
|
source=DIAGNOSTIC_SOURCE,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return diagnostics
|
||||||
|
|
||||||
|
def _compute_diagnostics(self, document: TextDocument) -> List[lsp.Diagnostic]:
|
||||||
|
return self.lint(document)
|
||||||
|
|
||||||
|
def compute_diagnostics(self, document: TextDocument):
|
||||||
|
# `None` sentinel ensures that `diagnostics` gets updated if the URI is not
|
||||||
|
# present.
|
||||||
|
_, previous = self.diagnostics.get(document, (0, None))
|
||||||
|
|
||||||
|
diagnostics = self._compute_diagnostics(document)
|
||||||
|
|
||||||
|
# Only update if the list has changed
|
||||||
|
if previous != diagnostics:
|
||||||
|
self.diagnostics[document.uri] = (document.version, diagnostics)
|
||||||
+59
-214
@@ -1,30 +1,19 @@
|
|||||||
{
|
{
|
||||||
"fileTypes": [
|
"fileTypes": [ "tcl" ],
|
||||||
"tcl"
|
|
||||||
],
|
|
||||||
"name": "tcl",
|
"name": "tcl",
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#main" }
|
||||||
"include": "#main"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"scopeName": "source.tcl",
|
"scopeName": "source.tcl",
|
||||||
|
"uuid": "c7017136-2ff2-48e9-bdb0-570cf238b4a2",
|
||||||
"repository": {
|
"repository": {
|
||||||
"main": {
|
"main": {
|
||||||
"patterns": [
|
"patterns": [ { "include": "#command" } ]
|
||||||
{
|
|
||||||
"include": "#command"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"args": {
|
"args": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#quoted_args" },
|
||||||
"include": "#quoted_args"
|
{ "include": "#numeric" },
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#numeric"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "((?<=;)\\s*#.*$)",
|
"match": "((?<=;)\\s*#.*$)",
|
||||||
"name": "comment.tcl",
|
"name": "comment.tcl",
|
||||||
@@ -36,22 +25,10 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"begin": "((?<!\\\\)\\{)",
|
"begin": "((?<!\\\\)\\{)",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "punctuation.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#braced__1" } ],
|
||||||
"name": "punctuation.tcl"
|
"end": "(\\}([^\\s\\]\\x{0022}]*))",
|
||||||
}
|
"endCaptures": { "1": { "name": "punctuation.tcl" } }
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#braced__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "(\\}([^\\s\\]]*))",
|
|
||||||
"endCaptures": {
|
|
||||||
"1": {
|
|
||||||
"name": "punctuation.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -61,42 +38,24 @@
|
|||||||
"match": "(\\\\(?:\\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.))",
|
"match": "(\\\\(?:\\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.))",
|
||||||
"name": "constant.character.escape.tcl"
|
"name": "constant.character.escape.tcl"
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#keywords" },
|
||||||
"include": "#keywords"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "((?<={)\\s*(?:after|append|apply|array|auto_execok|auto_import|auto_load|auto_mkindex|auto_qualify|auto_reset|bgerror|binary|break|catch|cd|chan|clock|close|concat|continue|coroutine|dde|dict|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|fileevent|file|flush|foreach|for|format|gets|global|glob|history|http|if|incr|info|interp|join|lappend|lassign|lindex|linsert|list|llength|lmap|load|lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|memory|my|namespace|nextto|next|oo::class|oo::copy|oo::define|oo::objdefine|oo::object|open|package|parray|pid|pkg::create|pkg_mkIndex|platform::shell|proc|puts|pwd|read|regexp|registry|regsub|rename|return|scan|seek|self|set|socket|source|split|string|subst|switch|tailcall|tcl::prefix|tcl_endOfWord|tcl_findLibrary|tcl_startOfNextWord|tcl_startOfPreviousWord|tcl_wordBreakAfter|tcl_wordBreakBefore|tell|throw|time|trace|try|unknown|unload|unset|update|uplevel|upvar|variable|vwait|while|yieldto|yield)\\s+)",
|
"match": "((?<={)\\s*(?:after|append|apply|array|auto_execok|auto_import|auto_load|auto_mkindex|auto_qualify|auto_reset|bgerror|binary|break|catch|cd|chan|clock|close|concat|continue|coroutine|dde|dict|encoding|eof|error|eval|exec|exit|expr|fblocked|fconfigure|fcopy|fileevent|file|flush|foreach|for|format|gets|global|glob|history|http|if|incr|info|interp|join|lappend|lassign|lindex|linsert|list|llength|lmap|load|lrange|lrepeat|lreplace|lreverse|lsearch|lset|lsort|memory|my|namespace|nextto|next|oo::class|oo::copy|oo::define|oo::objdefine|oo::object|open|package|parray|pid|pkg::create|pkg_mkIndex|platform::shell|proc|puts|pwd|read|regexp|registry|regsub|rename|return|scan|seek|self|set|socket|source|split|string|subst|switch|tailcall|tcl::prefix|tcl_endOfWord|tcl_findLibrary|tcl_startOfNextWord|tcl_startOfPreviousWord|tcl_wordBreakAfter|tcl_wordBreakBefore|tell|throw|time|trace|try|unknown|unload|unset|update|uplevel|upvar|variable|vwait|while|yieldto|yield)\\s+)",
|
||||||
"name": "keyword.tcl",
|
"name": "keyword.tcl",
|
||||||
"comment": "Special handling for known commands."
|
"comment": "Special handling for known commands."
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#braced_inner" },
|
||||||
"include": "#braced_inner"
|
{ "include": "#args" }
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#args"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"braced_inner": {
|
"braced_inner": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"begin": "(\\{)",
|
"begin": "(\\{)",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "punctuation.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#braced_inner__1" } ],
|
||||||
"name": "punctuation.tcl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#braced_inner__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "(\\})",
|
"end": "(\\})",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "punctuation.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "punctuation.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -106,15 +65,9 @@
|
|||||||
"match": "(\\\\[\\x{007b}\\x{007d}])",
|
"match": "(\\\\[\\x{007b}\\x{007d}])",
|
||||||
"name": "constant.character.escape.tcl"
|
"name": "constant.character.escape.tcl"
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#numeric" },
|
||||||
"include": "#numeric"
|
{ "include": "#braced_inner" },
|
||||||
},
|
{ "include": "#args" }
|
||||||
{
|
|
||||||
"include": "#braced_inner"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#args"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"braced_lit": {
|
"braced_lit": {
|
||||||
@@ -139,22 +92,10 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"begin": "(\\\\\\s*$)",
|
"begin": "(\\\\\\s*$)",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "constant.character.escape.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#command__1" } ],
|
||||||
"name": "constant.character.escape.tcl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#command__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "((?<!\\\\\\s)$)",
|
"end": "((?<!\\\\\\s)$)",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "none.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "none.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"match": "(^\\s*#.*)",
|
"match": "(^\\s*#.*)",
|
||||||
@@ -169,73 +110,41 @@
|
|||||||
{
|
{
|
||||||
"match": "(?<=^|{)(\\s*proc\\s+)(\\S+\\s+)((?:(?<!\\\\){)(?:[^\\x{007b}\\x{007d}\\n]*(?:\\g<1>(?:\\\\{|\\\\}|[^\\x{007b}\\x{007d}])*)*)})",
|
"match": "(?<=^|{)(\\s*proc\\s+)(\\S+\\s+)((?:(?<!\\\\){)(?:[^\\x{007b}\\x{007d}\\n]*(?:\\g<1>(?:\\\\{|\\\\}|[^\\x{007b}\\x{007d}])*)*)})",
|
||||||
"captures": {
|
"captures": {
|
||||||
"1": {
|
"1": { "name": "keyword.tcl" },
|
||||||
"name": "keyword.tcl"
|
"2": { "name": "entity.name.function.tcl" },
|
||||||
},
|
"3": { "name": "none.tcl" }
|
||||||
"2": {
|
|
||||||
"name": "entity.name.function.tcl"
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "none.tcl"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"comment": "Proc command."
|
"comment": "Proc command."
|
||||||
},
|
},
|
||||||
|
{ "include": "#regexp" },
|
||||||
|
{ "include": "#keywords" },
|
||||||
{
|
{
|
||||||
"include": "#regexp"
|
"match": "(^\\s*[^\\s\\x{0022}]+|(?:(?<=[^\\x{005c}]\\[)[^\\s\\]]+))",
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#keywords"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"match": "(^\\s*\\S+|(?:(?<=[^\\x{005c}]\\[)[^\\s\\]]++(?!\\])))",
|
|
||||||
"name": "keyword.tcl",
|
"name": "keyword.tcl",
|
||||||
"comment": "All other commands. (NOTE: Iro doesn't support possessive quantifiers, but the grammar does; be sure to replace the second + with ++ after regenerating!)"
|
"comment": "All other commands. (NOTE: Iro doesn't support possessive quantifiers, but the grammar does; be sure to replace the second + with ++ after regenerating!)"
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#args" }
|
||||||
"include": "#args"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"command__1": {
|
"command__1": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#keywords" },
|
||||||
"include": "#keywords"
|
{ "include": "#args" }
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#args"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"embedded": {
|
"embedded": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"begin": "((?<!\\\\)\\[)",
|
"begin": "((?<!\\\\)\\[)",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "punctuation.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#embedded__1" } ],
|
||||||
"name": "punctuation.tcl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#embedded__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "((?<!\\\\)\\])",
|
"end": "((?<!\\\\)\\])",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "punctuation.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "punctuation.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"embedded__1": {
|
"embedded__1": {
|
||||||
"patterns": [
|
"patterns": [ { "include": "#command" } ]
|
||||||
{
|
|
||||||
"include": "#command"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"keywords": {
|
"keywords": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
@@ -263,30 +172,16 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"begin": "((?<!\\\\)\")",
|
"begin": "((?<!\\\\)\")",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "string.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#quoted__1" } ],
|
||||||
"name": "string.tcl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#quoted__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "(\")",
|
"end": "(\")",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "string.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "string.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"quoted__1": {
|
"quoted__1": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#quoted_args" },
|
||||||
"include": "#quoted_args"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "([^\\x{0024}\\x{005b}\\x{0022}\\x{005c}]+)",
|
"match": "([^\\x{0024}\\x{005b}\\x{0022}\\x{005c}]+)",
|
||||||
"name": "string.tcl"
|
"name": "string.tcl"
|
||||||
@@ -295,22 +190,14 @@
|
|||||||
},
|
},
|
||||||
"quoted_args": {
|
"quoted_args": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#braced" },
|
||||||
"include": "#braced"
|
{ "include": "#quoted" },
|
||||||
},
|
{ "include": "#embedded" },
|
||||||
{
|
|
||||||
"include": "#quoted"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#embedded"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "(\\\\(?:\\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.))",
|
"match": "(\\\\(?:\\d{1,3}|x[a-fA-F0-9]{1,2}|u[a-fA-F0-9]{1,4}|U[a-fA-F0-9]{1,8}|.))",
|
||||||
"name": "constant.character.escape.tcl"
|
"name": "constant.character.escape.tcl"
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#variable" }
|
||||||
"include": "#variable"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"regexp": {
|
"regexp": {
|
||||||
@@ -318,57 +205,27 @@
|
|||||||
{
|
{
|
||||||
"begin": "((?<=^|[\\[\\x{007b}\\x{003b}])\\s*(?:regexp|regsub)\\s+)((?:(?:(?:-about|-all|-expanded|-indices|-inline|-lineanchor|-linestop|-line|-nocase|(?:-index\\s+(?:end|\\d+)(?:[\\+\\-]-?\\d+)?))\\s+)*(?:--\\s+)?)?)",
|
"begin": "((?<=^|[\\[\\x{007b}\\x{003b}])\\s*(?:regexp|regsub)\\s+)((?:(?:(?:-about|-all|-expanded|-indices|-inline|-lineanchor|-linestop|-line|-nocase|(?:-index\\s+(?:end|\\d+)(?:[\\+\\-]-?\\d+)?))\\s+)*(?:--\\s+)?)?)",
|
||||||
"beginCaptures": {
|
"beginCaptures": {
|
||||||
"1": {
|
"1": { "name": "keyword.tcl" },
|
||||||
"name": "keyword.tcl"
|
"2": { "name": "none.tcl" }
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"name": "none.tcl"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"patterns": [
|
"patterns": [ { "include": "#regexp__1" } ],
|
||||||
{
|
|
||||||
"include": "#regexp__1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "(\\s+)",
|
"end": "(\\s+)",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "none.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "none.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{ "include": "#args" }
|
||||||
"include": "#args"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"regexp__1": {
|
"regexp__1": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#braced_lit_re" },
|
||||||
"include": "#braced_lit_re"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"begin": "((?:(?<!\\\\)\"))",
|
"begin": "((?:(?<!\\\\)\"))",
|
||||||
"beginCaptures": {
|
"beginCaptures": { "1": { "name": "string.regexp.tcl" } },
|
||||||
"1": {
|
"patterns": [ { "include": "#regexp__2" } ],
|
||||||
"name": "string.regexp.tcl"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"patterns": [
|
|
||||||
{
|
|
||||||
"include": "#regexp__2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"end": "((?:(?<!\\\\)\"))",
|
"end": "((?:(?<!\\\\)\"))",
|
||||||
"endCaptures": {
|
"endCaptures": { "1": { "name": "string.regexp.tcl" } }
|
||||||
"1": {
|
|
||||||
"name": "string.regexp.tcl"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#variable"
|
|
||||||
},
|
},
|
||||||
|
{ "include": "#variable" },
|
||||||
{
|
{
|
||||||
"match": "(\\S+)",
|
"match": "(\\S+)",
|
||||||
"name": "string.regexp.tcl",
|
"name": "string.regexp.tcl",
|
||||||
@@ -378,15 +235,9 @@
|
|||||||
},
|
},
|
||||||
"regexp__2": {
|
"regexp__2": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#braced_lit_re" },
|
||||||
"include": "#braced_lit_re"
|
{ "include": "#embedded" },
|
||||||
},
|
{ "include": "#variable" },
|
||||||
{
|
|
||||||
"include": "#embedded"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#variable"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "(\\\\\"|[^\\x{0022}])",
|
"match": "(\\\\\"|[^\\x{0022}])",
|
||||||
"name": "string.regexp.tcl",
|
"name": "string.regexp.tcl",
|
||||||
@@ -404,15 +255,9 @@
|
|||||||
},
|
},
|
||||||
"word_lit__1": {
|
"word_lit__1": {
|
||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{ "include": "#braced_lit" },
|
||||||
"include": "#braced_lit"
|
{ "include": "#embedded" },
|
||||||
},
|
{ "include": "#variable" },
|
||||||
{
|
|
||||||
"include": "#embedded"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"include": "#variable"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"match": "(\\\\\"|[^\\x{0022}])",
|
"match": "(\\\\\"|[^\\x{0022}])",
|
||||||
"name": "string.tcl",
|
"name": "string.tcl",
|
||||||
|
|||||||
Reference in New Issue
Block a user