refactor(lsp): replace LSPManager with controller-based architecture

- Remove legacy LSPManager dialog implementation
- Introduce LSPController as the central LSP entry point
- Route UI interactions through lsp_controller.lsp_manager_ui
- Move client lifecycle handling out of ProviderResponseCache
- Simplify completion cache and matcher filtering
- Improve LSP completion item parsing with safer fallbacks
- Modernize typing (Python 3.10 union syntax)
- Remove unused imports and dead code
- Use GLib.idle_add for safe UI scrolling operations
- Minor comment and spelling fixes
This commit is contained in:
2026-03-11 23:17:57 -05:00
parent 060f68237b
commit 71bab687d7
21 changed files with 602 additions and 175 deletions

View File

@@ -23,7 +23,7 @@ class LSPClientEventsMixin:
uri = f"file://{fpath}" if not fpath.startswith("file://") else fpath
buffer = event.file.buffer
text = buffer.get_text(*buffer.get_bounds())
self._last_active_language_id = lang_id
self.active_language_id = lang_id
controller._lsp_did_open({
"uri": uri,
@@ -54,7 +54,7 @@ class LSPClientEventsMixin:
uri = f"file://{fpath}" if not fpath.startswith("file://") else fpath
buffer = event.file.buffer
text = buffer.get_text(*buffer.get_bounds())
self._last_active_language_id = lang_id
self.active_language_id = lang_id
controller._lsp_did_save({"uri": uri, "text": text})
@@ -71,7 +71,7 @@ class LSPClientEventsMixin:
uri = f"file://{fpath}" if not fpath.startswith("file://") else fpath
buffer = event.file.buffer
text = buffer.get_text(*buffer.get_bounds())
self._last_active_language_id = lang_id
self.active_language_id = lang_id
controller._lsp_did_change({
"uri": uri,
@@ -97,7 +97,7 @@ class LSPClientEventsMixin:
controller = self.clients[lang_id]
uri = f"file://{fpath}" if not fpath.startswith("file://") else fpath
self._last_active_language_id = lang_id
self.active_language_id = lang_id
controller._lsp_definition({
"uri": uri,
@@ -116,7 +116,7 @@ class LSPClientEventsMixin:
controller = self.clients[lang_id]
uri = f"file://{fpath}" if not fpath.startswith("file://") else fpath
self._last_active_language_id = lang_id
self.active_language_id = lang_id
controller._lsp_completion({
"uri": uri,

View File

@@ -29,22 +29,25 @@ class LSPServerEventsMixin:
self.matchers.clear()
for item in items:
label = item.get("label", "")
if not label: continue
label = item.get("label")
if not label: return None
text = item.get("insertText")
if not text and "textEdit" in item:
text = item["textEdit"].get("newText", "")
text = (
item.get("insertText")
or item.get("textEdit", {}).get("newText")
or item.get("textEditText", "")
or label
)
info = ""
if "detail" in item:
info = item["detail"]
elif "documentation" in item:
doc = item["documentation"]
if isinstance(doc, dict):
info = doc.get("value", "")
else:
info = str(doc)
detail = item.get("detail")
doc = item.get("documentation")
if detail:
info = detail
elif isinstance(doc, dict):
info = doc.get("value", "")
else:
info = str(doc) if doc else ""
self.matchers[label] = {
"label": label,