From 3681cc35b88b19bad2d8056979bb398f7fe8d8a3 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Wed, 18 Sep 2024 22:07:57 -0500 Subject: [PATCH] wrapped utf-8 in single quotes --- src/core/controllers/lsp/lsp_controller.py | 4 +- .../lsp/lsp_controller_websocket.py | 2 +- src/core/controllers/lsp/requirements.txt | 7 ++ src/libs/dto/lsp_controller_stdin_stdout.py | 117 ++++++++++++++++++ src/libs/lsp_endpoint_server.py | 2 +- 5 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/core/controllers/lsp/requirements.txt create mode 100644 src/libs/dto/lsp_controller_stdin_stdout.py diff --git a/src/core/controllers/lsp/lsp_controller.py b/src/core/controllers/lsp/lsp_controller.py index 5517de7..586232b 100644 --- a/src/core/controllers/lsp/lsp_controller.py +++ b/src/core/controllers/lsp/lsp_controller.py @@ -7,7 +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 +# from .lsp_controller_websocket import LSPControllerWebsocket @@ -88,4 +88,4 @@ class LSPController(LSPControllerSTDInSTDOut): def handle_lsp_response(self, lsp_response: LSPResponseTypes): self.log_list.add_log_entry("LSP Response", lsp_response) - event_system.emit("respond-to-client", (get_message_str(lsp_response),)) + event_system.emit("respond-to-client", (get_message_str(lsp_response),)) \ No newline at end of file diff --git a/src/core/controllers/lsp/lsp_controller_websocket.py b/src/core/controllers/lsp/lsp_controller_websocket.py index 63c8c7b..5943636 100644 --- a/src/core/controllers/lsp/lsp_controller_websocket.py +++ b/src/core/controllers/lsp/lsp_controller_websocket.py @@ -94,4 +94,4 @@ class LSPControllerWebsocket(LSPControllerBase): print() if not lsp_response: return - self.handle_lsp_response(lsp_response) + self.handle_lsp_response(lsp_response) \ No newline at end of file diff --git a/src/core/controllers/lsp/requirements.txt b/src/core/controllers/lsp/requirements.txt new file mode 100644 index 0000000..bfb1be3 --- /dev/null +++ b/src/core/controllers/lsp/requirements.txt @@ -0,0 +1,7 @@ +PyGObject==3.40.1 +pygobject-stubs --no-cache-dir --config-settings=config=Gtk3,Gdk3,Soup2 +setproctitle==1.2.2 +pyxdg==0.27 +psutil==5.8.0 +pycryptodome==3.20.0 +sqlmodel==0.0.19 \ No newline at end of file diff --git a/src/libs/dto/lsp_controller_stdin_stdout.py b/src/libs/dto/lsp_controller_stdin_stdout.py new file mode 100644 index 0000000..94af486 --- /dev/null +++ b/src/libs/dto/lsp_controller_stdin_stdout.py @@ -0,0 +1,117 @@ +# Python imports +import subprocess + +# Lib imports +from gi.repository import GLib + +# Application imports +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 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() + + def start_lsp(self): + if not self._start_command: return + try: + self.lsp_process = subprocess.Popen( + self._start_command, + 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() + + # https://github.com/sr-lab/coqpyt/blob/master/coqpyt/lsp/json_rpc_endpoint.py#L65 + # Virtually this whole method unabashedly taken from ^ ... + @daemon_threaded + def _monitor_lsp_response(self): + if not hasattr(self, "lsp_process"): return + + with self.read_lock: + message_size = None + while True: + line = self.lsp_process.stdout.readline() + if not line: return None # Quit listener... + + line = line.decode("utf-8") + if not line.endswith("\r\n"): + raise Exception( + "Bad header: missing newline" + ) + line = line[:-2] # Strip the "\r\n" + if line == "": # We're done with the headers... + break + elif line.startswith(LEN_HEADER): + line = line[len(LEN_HEADER) :] + if not line.isdigit(): + raise Exception( + "Bad header: size is not int", + ) + message_size = int(line) + elif line.startswith(TYPE_HEADER): + # Not doing anything with type header, currently... + pass + else: + line = line.split(LEN_HEADER) + if len(line) == 2: + message_size = line[1] + raise Exception( + "Bad header: unknown header" + ) + + if not message_size: return + + _data = self.lsp_process.stdout.read(message_size) + data = _data.decode("utf-8") + 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 + + 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/libs/lsp_endpoint_server.py b/src/libs/lsp_endpoint_server.py index 40e706c..dcc5932 100644 --- a/src/libs/lsp_endpoint_server.py +++ b/src/libs/lsp_endpoint_server.py @@ -115,7 +115,7 @@ class LSPEndpointServer(Singleton): else: conn = Client((self._ipc_address, self._ipc_port)) - conn.send( f"MANAGER|{ base64.b64encode(message.encode("utf-8")).decode("utf-8") }" ) + conn.send( f"MANAGER|{ base64.b64encode(message.encode('utf-8')).decode('utf-8') }" ) conn.close() except ConnectionRefusedError as e: logger.error("Connection refused...")