Delegate TCL folding to server, fix bugs, and enhance stability
- Move TCL folding range computation from client to language server, avoiding duplicate regions. - Serialize language server restarts to prevent multiple server instances running concurrently. - Pin server-side Python dependencies to specific minor versions for improved stability and predictability. - Make debug server connection non-fatal, allowing the language server to start even if the debugger isn't attached. - Optimize semantic token generation by caching Tclint plugin commands.
This commit is contained in:
@@ -4,9 +4,12 @@ version = "0.1.0"
|
||||
description = "Python language server for NX Postprocessor Support"
|
||||
requires-python = ">=3.8"
|
||||
dependencies = [
|
||||
"pygls",
|
||||
"packaging",
|
||||
"tclint",
|
||||
# Upper bounds guard against breaking API changes in bundled deps. The code
|
||||
# is written against tclint 0.8.x (see tools/semantic_tokens.py); pin it so a
|
||||
# re-bundle can't silently pull an incompatible major/minor.
|
||||
"pygls>=1.3,<2",
|
||||
"packaging>=24,<27",
|
||||
"tclint>=0.8,<0.9",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
|
||||
@@ -27,7 +27,17 @@ if debugger_path:
|
||||
|
||||
# 5678 is the default port, If you need to change it update it here
|
||||
# and in launch.json.
|
||||
debugpy.connect(5678)
|
||||
# Connecting requires the "Python debug server" listener (launch.json) to be
|
||||
# up first. If it isn't (e.g. wrong launch config was used), don't crash the
|
||||
# whole language server - just continue running without the debugger attached.
|
||||
try:
|
||||
debugpy.connect(5678)
|
||||
except (ConnectionRefusedError, OSError) as exc:
|
||||
print(
|
||||
f"debugpy: could not connect to debug adapter on port 5678 "
|
||||
f"({exc}); continuing without debugging.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
# This will ensure that execution is paused as soon as the debugger
|
||||
# connects to VS Code. If you don't want to pause here comment this
|
||||
|
||||
@@ -7,6 +7,23 @@ from common.load_data import standard_items
|
||||
import lsprotocol.types as lsp
|
||||
|
||||
|
||||
# Constructing a PluginManager scans entry points, and get_commands() rebuilds
|
||||
# the builtin command set on every call. Semantic tokens are requested often, so
|
||||
# cache the manager and the resolved commands per plugin set.
|
||||
_PLUGIN_MANAGER = None
|
||||
_COMMANDS_CACHE = {}
|
||||
|
||||
|
||||
def _load_commands(plugins):
|
||||
global _PLUGIN_MANAGER
|
||||
if _PLUGIN_MANAGER is None:
|
||||
_PLUGIN_MANAGER = PluginManager()
|
||||
key = tuple(plugins)
|
||||
if key not in _COMMANDS_CACHE:
|
||||
_COMMANDS_CACHE[key] = _PLUGIN_MANAGER.get_commands(list(plugins))
|
||||
return _COMMANDS_CACHE[key]
|
||||
|
||||
|
||||
class TokenModifier(enum.IntFlag):
|
||||
deprecated = enum.auto()
|
||||
readonly = enum.auto()
|
||||
@@ -47,7 +64,7 @@ TOKEN_TYPES = [
|
||||
|
||||
class _Highlighter(Visitor):
|
||||
def __init__(self, plugins, custom_functions: dict[str : list[lsp.CompletionItem]]):
|
||||
self._commands = PluginManager().get_commands(plugins)
|
||||
self._commands = _load_commands(plugins)
|
||||
self._tokens = []
|
||||
self.custom_functions = custom_functions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user