2026-03-11 23:15:19 -05:00
|
|
|
# Python imports
|
|
|
|
|
|
|
|
|
|
# Lib imports
|
|
|
|
|
|
|
|
|
|
# Application imports
|
|
|
|
|
from libs.dto.code.lsp.lsp_message_structs import LSPResponseTypes, LSPResponseRequest, LSPResponseNotification
|
|
|
|
|
|
|
|
|
|
from .provider import Provider
|
|
|
|
|
from .provider_response_cache import ProviderResponseCache
|
|
|
|
|
from .lsp_manager_ui import LSPManagerUI
|
2026-03-12 00:04:08 -05:00
|
|
|
from .lsp_manager_client import LSPManagerClient
|
2026-03-15 01:50:23 -05:00
|
|
|
from .response_handlers.response_registry import ResponseRegistry
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-12 00:04:08 -05:00
|
|
|
class LSPManager:
|
2026-03-11 23:15:19 -05:00
|
|
|
def __init__(self):
|
2026-03-12 00:04:08 -05:00
|
|
|
super(LSPManager, self).__init__()
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
self._init()
|
|
|
|
|
self._load_widgets()
|
|
|
|
|
self._do_bind_mapping()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _init(self):
|
2026-03-12 00:04:08 -05:00
|
|
|
self.provider: Provider = Provider()
|
|
|
|
|
self.response_cache: ProviderResponseCache = ProviderResponseCache()
|
|
|
|
|
self.lsp_manager_client: LSPManagerClient = LSPManagerClient()
|
2026-03-15 01:50:23 -05:00
|
|
|
self.response_registry: ResponseRegistry = ResponseRegistry()
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
def _load_widgets(self):
|
|
|
|
|
self.lsp_manager_ui: LSPManagerUI = LSPManagerUI()
|
2026-03-15 01:50:23 -05:00
|
|
|
self.lsp_manager_ui.connect('create-client', self._on_create_client)
|
|
|
|
|
self.lsp_manager_ui.connect('close-client', self._on_close_client)
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
def _do_bind_mapping(self):
|
2026-03-15 01:50:23 -05:00
|
|
|
self.response_cache.set_lsp_client(self.lsp_manager_client)
|
|
|
|
|
self.provider.response_cache = self.response_cache
|
|
|
|
|
|
|
|
|
|
def _on_create_client(self, ui, lang_id: str, workspace_uri: str) -> bool:
|
|
|
|
|
init_opts = ui.get_init_opts(lang_id)
|
|
|
|
|
result = self.create_client(lang_id, workspace_uri, init_opts)
|
|
|
|
|
if result:
|
|
|
|
|
ui.toggle_client_buttons(show_close=True)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def _on_close_client(self, ui, lang_id: str) -> bool:
|
|
|
|
|
result = self.close_client(lang_id)
|
|
|
|
|
if result:
|
|
|
|
|
ui.toggle_client_buttons(show_close=False)
|
|
|
|
|
return result
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
def create_client(
|
|
|
|
|
self,
|
|
|
|
|
lang_id: str = "python",
|
|
|
|
|
workspace_uri: str = "",
|
|
|
|
|
init_opts: dict = {}
|
|
|
|
|
) -> bool:
|
2026-03-12 00:04:08 -05:00
|
|
|
client = self.lsp_manager_client.create_client(
|
2026-03-11 23:15:19 -05:00
|
|
|
lang_id, workspace_uri, init_opts
|
|
|
|
|
)
|
2026-03-15 01:50:23 -05:00
|
|
|
handler = self.response_registry.get_handler(lang_id)
|
2026-03-12 00:04:08 -05:00
|
|
|
self.lsp_manager_client.active_language_id = lang_id
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
if not client or not handler:
|
2026-03-12 00:04:08 -05:00
|
|
|
logger.error(f"LSP Manager: Either 'client' or 'handler' didn't get created...'")
|
2026-03-11 23:15:19 -05:00
|
|
|
self.close_client(lang_id)
|
|
|
|
|
return False
|
|
|
|
|
|
2026-03-15 01:50:23 -05:00
|
|
|
handler.set_context(self.response_registry)
|
2026-03-11 23:15:19 -05:00
|
|
|
handler.set_response_cache(self.response_cache)
|
|
|
|
|
|
|
|
|
|
client.handle_lsp_response = self.server_response
|
|
|
|
|
client.send_initialize_message(init_opts, "", f"file://{workspace_uri}")
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def close_client(self, lang_id: str) -> bool:
|
2026-03-12 00:04:08 -05:00
|
|
|
self.lsp_manager_client.close_client(lang_id)
|
2026-03-15 01:50:23 -05:00
|
|
|
self.response_registry.close_handler(lang_id)
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def server_response(self, lsp_response: LSPResponseTypes):
|
|
|
|
|
logger.debug(f"LSP Response: { lsp_response }")
|
|
|
|
|
|
|
|
|
|
if isinstance(lsp_response, LSPResponseRequest):
|
2026-03-12 00:04:08 -05:00
|
|
|
if not self.lsp_manager_client.active_language_id in self.lsp_manager_client.clients:
|
|
|
|
|
logger.debug(f"No LSP client for '{self.lsp_manager_client.active_language_id}', skipping 'server_response'")
|
2026-03-11 23:15:19 -05:00
|
|
|
return
|
|
|
|
|
|
2026-03-12 00:04:08 -05:00
|
|
|
controller = self.lsp_manager_client.get_active_client()
|
2026-03-11 23:15:19 -05:00
|
|
|
event = controller.get_event_by_id(lsp_response.id)
|
2026-03-15 01:50:23 -05:00
|
|
|
handler = self.response_registry.get_handler(
|
2026-03-12 00:04:08 -05:00
|
|
|
self.lsp_manager_client.active_language_id, event
|
2026-03-11 23:15:19 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not handler: return
|
|
|
|
|
handler.handle(event, lsp_response.result, controller)
|
|
|
|
|
elif isinstance(lsp_response, LSPResponseNotification):
|
2026-03-15 01:50:23 -05:00
|
|
|
handler = self.response_registry.get_handler("default", lsp_response.method)
|
2026-03-11 23:15:19 -05:00
|
|
|
|
|
|
|
|
if not handler: return
|
|
|
|
|
|
2026-03-15 01:50:23 -05:00
|
|
|
handler.set_context(self.response_registry)
|
2026-03-11 23:15:19 -05:00
|
|
|
handler.set_response_cache(self.response_cache)
|
|
|
|
|
handler.handle(lsp_response.method, lsp_response.params, None)
|