diff --git a/src/core/controllers/lsp/lsp_controller.py b/src/core/controllers/lsp/lsp_controller.py index 32e42a5..5517de7 100644 --- a/src/core/controllers/lsp/lsp_controller.py +++ b/src/core/controllers/lsp/lsp_controller.py @@ -7,6 +7,7 @@ import threading from libs.dto.lsp_messages import get_message_str from libs.dto.lsp_message_structs import LSPResponseTypes, ClientRequest, ClientNotification from .lsp_controller_stdin_stdout import LSPControllerSTDInSTDOut +from .lsp_controller_websocket import LSPControllerWebsocket @@ -20,6 +21,7 @@ def _log_list(): class LSPController(LSPControllerSTDInSTDOut): +# class LSPController(LSPControllerWebsocket): def __init__(self): super(LSPController).__init__() @@ -80,12 +82,10 @@ class LSPController(LSPControllerSTDInSTDOut): if not pid: return self._lsp_pid = pid - self._monitor_lsp_response() else: self.stop_lsp() self.log_list.clear() def handle_lsp_response(self, lsp_response: LSPResponseTypes): - self._monitor_lsp_response() self.log_list.add_log_entry("LSP Response", lsp_response) - event_system.emit("respond-to-client", (get_message_str(lsp_response),)) \ No newline at end of file + event_system.emit("respond-to-client", (get_message_str(lsp_response),)) diff --git a/src/core/controllers/lsp/lsp_controller_stdin_stdout.py b/src/core/controllers/lsp/lsp_controller_stdin_stdout.py index 534a9f2..94af486 100644 --- a/src/core/controllers/lsp/lsp_controller_stdin_stdout.py +++ b/src/core/controllers/lsp/lsp_controller_stdin_stdout.py @@ -16,13 +16,13 @@ from libs.dto.lsp_message_structs import \ class LSPControllerSTDInSTDOut(LSPControllerBase): def _send_message(self, data: ClientRequest or ClientNotification): if not data or not hasattr(self, "lsp_process"): return - message_str = get_message_str(data) message_size = len(message_str) message = f"Content-Length: {message_size}\r\n\r\n{message_str}" self.log_list.add_log_entry("Client", data) + self._monitor_lsp_response() with self.write_lock: self.lsp_process.stdin.write( message.encode("utf-8") ) self.lsp_process.stdin.flush() @@ -114,3 +114,4 @@ class LSPControllerSTDInSTDOut(LSPControllerBase): if not lsp_response: return GLib.idle_add(self.handle_lsp_response, lsp_response) + GLib.idle_add(self._monitor_lsp_response) diff --git a/src/core/controllers/lsp/lsp_controller_websocket.py b/src/core/controllers/lsp/lsp_controller_websocket.py new file mode 100644 index 0000000..63c8c7b --- /dev/null +++ b/src/core/controllers/lsp/lsp_controller_websocket.py @@ -0,0 +1,97 @@ +# Python imports +import subprocess +import asyncio + +# Lib imports +from gi.repository import GLib + +# Application imports +from libs import websockets +from libs.dto.lsp_messages import LEN_HEADER, TYPE_HEADER, get_message_str, get_message_obj +from .lsp_controller_base import LSPControllerBase +from libs.dto.lsp_message_structs import \ + LSPResponseTypes, ClientRequest, ClientNotification, LSPResponseRequest, LSPResponseNotification + + + + +class LSPControllerWebsocket(LSPControllerBase): + def _send_message(self, data: ClientRequest or ClientNotification): + if not data or not hasattr(self, "lsp_process"): return + + message_str = get_message_str(data) + message_size = len(message_str) + message = f"Content-Length: {message_size}\r\n\r\n{message_str}" + + self.log_list.add_log_entry("Client", data) + + uri = "ws://localhost:4114" + async def do_message(message_str): + async with websockets.connect(uri) as websocket: + await websocket.send(message_str) + response = await websocket.recv() + GLib.idle_add(self._monitor_lsp_response, response) + + asyncio.get_event_loop().run_until_complete( do_message(message_str) ) + + + def start_lsp(self): + if not self._start_command: return + try: + self.lsp_process = subprocess.Popen( + ["pylsp", "--ws", "--port", "4114"], + stdout = subprocess.PIPE, + stdin = subprocess.PIPE + ) + except Exception as e: + self.log_list.add_log_entry( + "LSP Client Error", + LSPResponseRequest( + "2.0", + None, + { + "error": repr(e) + } + ) + ) + + return + + return self.lsp_process.pid + + def stop_lsp(self): + if self._lsp_pid == -1: return + + self._lsp_pid = -1 + self._message_id = 0 + self.lsp_process.terminate() + + def _monitor_lsp_response(self, data: None or {}): + if not hasattr(self, "lsp_process"): return + if not data: return + + message = get_message_obj(data) + keys = message.keys() + lsp_response = None + + if "result" in keys: + lsp_response = LSPResponseRequest(**get_message_obj(data)) + + if "method" in keys: + lsp_response = LSPResponseNotification(**get_message_obj(data)) + + response_id = -1 + + print() + print() + print() + print() + print() + print(f"Response: {lsp_response}") + print() + print() + print() + print() + + if not lsp_response: return + self.handle_lsp_response(lsp_response) diff --git a/src/libs/lsp_endpoint_server.py b/src/libs/lsp_endpoint_server.py index 2682326..40e706c 100644 --- a/src/libs/lsp_endpoint_server.py +++ b/src/libs/lsp_endpoint_server.py @@ -105,6 +105,10 @@ class LSPEndpointServer(Singleton): def send_client_ipc_message(self, message: str = "Empty Data...") -> None: try: if self._conn_type == "socket": + if not os.path.exists(self._client_ipc_address): + logger.error(f"Socket: {self._client_ipc_address} doesn't exist. NOT sending message...") + return + conn = Client(address=self._client_ipc_address, family="AF_UNIX", authkey=self._client_ipc_authkey) elif "unsecured" not in self._conn_type: conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey)