More wiring of lsp manager calls and responses

This commit is contained in:
itdominator 2024-09-14 16:39:21 -05:00
parent e0664123da
commit bc52f62982
7 changed files with 125 additions and 84 deletions

View File

@ -1,5 +1,4 @@
# Python imports # Python imports
import os
import signal import signal
import subprocess import subprocess
import threading import threading
@ -9,7 +8,7 @@ import json
from gi.repository import GLib from gi.repository import GLib
# Application imports # Application imports
from libs.dto.lsp_messages import LEN_HEADER, TYPE_HEADER, get_message_str, get_message_obj, definition_query, references_query, symbols_query from libs.dto.lsp_messages import LEN_HEADER, TYPE_HEADER, get_message_str, get_message_obj
from libs.dto.lsp_message_structs import \ from libs.dto.lsp_message_structs import \
LSPResponseTypes, ClientRequest, ClientNotification, LSPResponseRequest, LSPResponseNotification LSPResponseTypes, ClientRequest, ClientNotification, LSPResponseRequest, LSPResponseNotification
from .lsp_controller_events import LSPControllerEvents from .lsp_controller_events import LSPControllerEvents
@ -48,9 +47,6 @@ class LSPController(LSPControllerEvents):
def _subscribe_to_events(self): def _subscribe_to_events(self):
# event_system.subscribe("client-send-request", self._client_send_request)
# event_system.subscribe("client-send-notification", self._client_send_notification)
event_system.subscribe("textDocument/didOpen", self._lsp_did_open) event_system.subscribe("textDocument/didOpen", self._lsp_did_open)
# event_system.subscribe("textDocument/didSave", self._lsp_did_save) # event_system.subscribe("textDocument/didSave", self._lsp_did_save)
# event_system.subscribe("textDocument/didClose", self._lsp_did_close) # event_system.subscribe("textDocument/didClose", self._lsp_did_close)
@ -58,26 +54,6 @@ class LSPController(LSPControllerEvents):
event_system.subscribe("textDocument/definition", self._lsp_goto) event_system.subscribe("textDocument/definition", self._lsp_goto)
event_system.subscribe("textDocument/completion", self._lsp_completion) event_system.subscribe("textDocument/completion", self._lsp_completion)
def _client_send_request(self, method: str, uri: str, line: int, character: int):
if not method: return
if "textDocument/definition":
params = symbols_query
elif "textDocument/references":
params = symbols_query
elif "textDocument/documentSymbol":
params = symbols_query
params["textDocument"]["uri"] = uri
params["textDocument"]["languageId"] = self._language
params["position"]["line"] = line
params["position"]["character"] = character
self.send_request(method, params)
def _client_send_notification(self, method: str, line: int, char: int):
if not method: return
self.send_notification(method, params)
def set_language(self, language): def set_language(self, language):
self._language = language self._language = language
@ -91,25 +67,6 @@ class LSPController(LSPControllerEvents):
def unset_start_command(self): def unset_start_command(self):
self._start_command = None self._start_command = None
def send_initialize_message(self, init_ops: str, workspace_file: str, workspace_uri: str):
folder_name = os.path.basename(workspace_file)
self._init_params["processId"] = settings_manager.get_app_pid()
self._init_params["rootPath"] = workspace_file
self._init_params["rootUri"] = workspace_uri
self._init_params["workspaceFolders"] = [
{
"name": folder_name,
"uri": workspace_uri
}
]
self._init_params["initializationOptions"] = get_message_obj(init_ops)
self.send_request("initialize", self._init_params)
def send_initialized_message(self):
self.send_notification("initialized")
def send_notification(self, method: str, params: {} = {}): def send_notification(self, method: str, params: {} = {}):
self._send_message( ClientNotification(method, params) ) self._send_message( ClientNotification(method, params) )
@ -237,4 +194,4 @@ class LSPController(LSPControllerEvents):
def handle_lsp_response(self, lsp_response: LSPResponseTypes): def handle_lsp_response(self, lsp_response: LSPResponseTypes):
self.log_list.add_log_entry("LSP Response", lsp_response) 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),))

View File

@ -1,15 +1,34 @@
# Python imports # Python imports
import os
# Lib imports # Lib imports
from gi.repository import GLib from gi.repository import GLib
# Application imports # Application imports
# from libs.dto.lsp_messages import LEN_HEADER, TYPE_HEADER, get_message_str, get_message_obj, definition_query, references_query, symbols_query from libs.dto.lsp_messages import get_message_obj, didopen_notification, completion_request, didchange_notification
from libs.dto.lsp_messages import didopen_notification
class LSPControllerEvents: class LSPControllerEvents:
def send_initialize_message(self, init_ops: str, workspace_file: str, workspace_uri: str):
folder_name = os.path.basename(workspace_file)
self._init_params["processId"] = settings_manager.get_app_pid()
self._init_params["rootPath"] = workspace_file
self._init_params["rootUri"] = workspace_uri
self._init_params["workspaceFolders"] = [
{
"name": folder_name,
"uri": workspace_uri
}
]
self._init_params["initializationOptions"] = get_message_obj(init_ops)
self.send_request("initialize", self._init_params)
def send_initialized_message(self):
self.send_notification("initialized")
def _lsp_did_open(self, data: dict): def _lsp_did_open(self, data: dict):
method = data["method"] method = data["method"]
params = didopen_notification["params"] params = didopen_notification["params"]
@ -21,23 +40,30 @@ class LSPControllerEvents:
GLib.idle_add( self.send_notification, method, params ) GLib.idle_add( self.send_notification, method, params )
def _lsp_did_save(self, data: dict): def _lsp_did_save(self, data: dict):
# self.send_notification(method, params) # GLib.idle_add( self.send_notification, method, params )
... ...
def _lsp_did_close(self, data: dict): def _lsp_did_close(self, data: dict):
# self.send_notification(method, params) # GLib.idle_add( self.send_notification, method, params )
... ...
def _lsp_did_change(self, data: dict): def _lsp_did_change(self, data: dict):
method = data["method"] method = data["method"]
language_id = data["language_id"] params = didchange_notification["params"]
uri = data["uri"]
text = data["text"]
line = data["line"]
column = data["column"]
self.send_notification(method, params) params["textDocument"]["uri"] = data["uri"]
# return "{'notification':'some kind of response'}" params["textDocument"]["languageId"] = data["language_id"]
params["textDocument"]["version"] = data["version"]
contentChanges = params["contentChanges"][0]
start = contentChanges["range"]["start"]
end = contentChanges["range"]["end"]
start["line"] = data["line"]
start["character"] = 0
end["line"] = data["line"]
end["character"] = data["column"]
GLib.idle_add( self.send_notification, method, params )
def _lsp_goto(self, data: dict): def _lsp_goto(self, data: dict):
method = data["method"] method = data["method"]
@ -46,14 +72,17 @@ class LSPControllerEvents:
line = data["line"] line = data["line"]
column = data["column"] column = data["column"]
self._client_send_request(method, uri, line, column) GLib.idle_add( self.send_request, method, params )
# return "{'response':'some kind of response'}"
def _lsp_completion(self, data: dict): def _lsp_completion(self, data: dict):
method = data["method"] method = data["method"]
language_id = data["language_id"] params = completion_request["params"]
uri = data["uri"]
line = data["line"]
column = data["column"]
# self._client_send_request(method, uri, line, column) params["textDocument"]["uri"] = data["uri"]
params["textDocument"]["languageId"] = data["language_id"]
params["textDocument"]["version"] = data["version"]
params["position"]["line"] = data["line"]
params["position"]["character"] = data["column"]
GLib.idle_add( self.send_request, method, params )

View File

@ -28,7 +28,8 @@ class WorkspaceFolderChoserButton(Gtk.FileChooserButton):
self.set_title("Chose Workspace") self.set_title("Chose Workspace")
self.set_action( Gtk.FileChooserAction.SELECT_FOLDER ) self.set_action( Gtk.FileChooserAction.SELECT_FOLDER )
# self.set_uri("file:///home/abaddon/Coding/Projects/Active/Python_Projects/testing/lsp_manager") # self.set_uri("file:///home/abaddon/Coding/Projects/Active/Python_Projects/testing/lsp_manager")
self.set_uri("file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager") # self.set_uri("file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager")
self.set_uri("file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/Newton_Editor")
def _setup_signals(self): def _setup_signals(self):

View File

@ -28,7 +28,7 @@ content_part = {
"params": { "params": {
"textDocument": { "textDocument": {
"uri": "file:///", "uri": "file:///",
"languageId": "python3", "languageId": "python",
"version": 1, "version": 1,
"text": "" "text": ""
}, },
@ -45,21 +45,72 @@ didopen_notification = {
"params": { "params": {
"textDocument": { "textDocument": {
"uri": "file://<path>", "uri": "file://<path>",
"languageId": "python3", "languageId": "python",
"version": 1, "version": 1,
"text": "" "text": ""
} }
} }
} }
didchange_notification = {
"method": "textDocument/didChange",
"params": {
"textDocument": {
"uri": "file://<path>",
"languageId": "python",
"version": 1,
"text": ""
},
"contentChanges": [
{
"range": {
"start": {
"line": 1,
"character": 1,
},
"end": {
"line": 1,
"character": 1,
}
}
}
]
}
}
definition_query = {
# CompletionTriggerKind = 1 | 2 | 3;
# export const Invoked: 1 = 1;
# export const TriggerCharacter: 2 = 2;
# export const TriggerForIncompleteCompletions: 3 = 3;
completion_request = {
"method": "textDocument/completion",
"params": {
"textDocument": {
"uri": "file://",
"languageId": "python",
"version": 1,
"text": ""
},
"position": {
"line": 5,
"character": 12,
"offset": 0
},
"contet": {
"triggerKind": 3,
"triggerCharacter":
}
}
}
definition_request = {
"method": "textDocument/definition", "method": "textDocument/definition",
"params": { "params": {
"textDocument": { "textDocument": {
"uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py", "uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py",
"languageId": "python3", "languageId": "python",
"version": 1, "version": 1,
"text": "" "text": ""
}, },
@ -71,7 +122,7 @@ definition_query = {
} }
} }
references_query = { references_request = {
"method": "textDocument/references", "method": "textDocument/references",
"params": { "params": {
"context": { "context": {
@ -79,7 +130,7 @@ references_query = {
}, },
"textDocument": { "textDocument": {
"uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py", "uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py",
"languageId": "python3", "languageId": "python",
"version": 1, "version": 1,
"text": "" "text": ""
}, },
@ -92,12 +143,12 @@ references_query = {
} }
symbols_query = { symbols_request = {
"method": "textDocument/documentSymbol", "method": "textDocument/documentSymbol",
"params": { "params": {
"textDocument": { "textDocument": {
"uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py", "uri": "file:///home/abaddon/Coding/Projects/Active/Python_Projects/000_Usable/gtk/LSP-Manager/src/core/widgets/lsp_message_box.py",
"languageId": "python3", "languageId": "python",
"version": 1, "version": 1,
"text": "" "text": ""
} }

View File

@ -1,4 +1,5 @@
# Python imports # Python imports
import traceback
import os import os
import threading import threading
import time import time
@ -66,19 +67,21 @@ class LSPEndpointServer(Singleton):
start_time = time.perf_counter() start_time = time.perf_counter()
self._handle_ipc_message(conn, start_time) self._handle_ipc_message(conn, start_time)
except Exception as e: except Exception as e:
logger.debug( repr(e) ) # logger.debug( repr(e) )
logger.debug( traceback.print_exc() )
listener.close() listener.close()
def _handle_ipc_message(self, conn, start_time) -> None: def _handle_ipc_message(self, conn, start_time) -> None:
while True: while True:
msg = conn.recv() msg = conn.recv()
logger.debug(msg)
if "CLIENT|" in msg: if "CLIENT|" in msg:
data = msg.split("CLIENT|")[1].strip() data = msg.split("CLIENT|")[1].strip()
if data: if data:
data_str = base64.b64decode(data.encode("utf-8")).decode("utf-8") data_str = base64.b64decode(data.encode("utf-8")).decode("utf-8")
logger.debug(data_str)
json_blob = json.loads(data_str) json_blob = json.loads(data_str)
event_system.emit(json_blob["method"], (json_blob,)) event_system.emit(json_blob["method"], (json_blob,))
@ -145,4 +148,4 @@ class LSPEndpointServer(Singleton):
logger.error("LSP Socket no longer valid.... Removing.") logger.error("LSP Socket no longer valid.... Removing.")
os.unlink(self._ipc_address) os.unlink(self._ipc_address)
except Exception as e: except Exception as e:
logger.error( repr(e) ) logger.error( repr(e) )

View File

@ -109,13 +109,13 @@ class SettingsManager(StartCheckMixin, Singleton):
with open(self._LSP_CONFIG) as file: with open(self._LSP_CONFIG) as file:
self._lsp_config_data = json.load(file) self._lsp_config_data = json.load(file)
except Exception as e: except Exception as e:
print( f"Settings Manager: {self._LSP_CONFIG}\n\t\t{repr(e)}" ) print( f"Settings Manager: {self._LSP_CONFIG}\n\t\t{repr(e)}" )
try: try:
with open(self._LSP_INIT_CONFIG) as file: with open(self._LSP_INIT_CONFIG) as file:
self._lsp_init_data = json.load(file) self._lsp_init_data = json.load(file)
except Exception as e: except Exception as e:
print( f"Settings Manager: {self._LSP_INIT_CONFIG}\n\t\t{repr(e)}" ) print( f"Settings Manager: {self._LSP_INIT_CONFIG}\n\t\t{repr(e)}" )
self.settings: Settings = None self.settings: Settings = None
@ -162,7 +162,7 @@ class SettingsManager(StartCheckMixin, Singleton):
def get_ui_widgets_path(self) -> str: return self._UI_WIDEGTS_PATH def get_ui_widgets_path(self) -> str: return self._UI_WIDEGTS_PATH
def get_context_menu_data(self) -> str: return self._context_menu_data def get_context_menu_data(self) -> str: return self._context_menu_data
def get_lsp_config_data(self) -> str: return self._lsp_config_data def get_lsp_config_data(self) -> str: return self._lsp_config_data
def get_lsp_init_data(self) -> {}: return self._lsp_init_data def get_lsp_init_data(self) -> dict: return self._lsp_init_data
def get_app_pid(self) -> int: return self.pid def get_app_pid(self) -> int: return self.pid
def get_context_path(self) -> str: return self._CONTEXT_PATH def get_context_path(self) -> str: return self._CONTEXT_PATH
@ -172,7 +172,7 @@ class SettingsManager(StartCheckMixin, Singleton):
def get_home_config_path(self) -> str: return self._HOME_CONFIG_PATH def get_home_config_path(self) -> str: return self._HOME_CONFIG_PATH
def get_window_icon(self) -> str: return self._WINDOW_ICON def get_window_icon(self) -> str: return self._WINDOW_ICON
def get_home_path(self) -> str: return self._USER_HOME def get_home_path(self) -> str: return self._USER_HOME
def get_starting_files(self) -> []: return self._starting_files def get_starting_files(self) -> list: return self._starting_files
def is_trace_debug(self) -> str: return self._trace_debug def is_trace_debug(self) -> str: return self._trace_debug
def is_debug(self) -> str: return self._debug def is_debug(self) -> str: return self._debug
@ -197,7 +197,7 @@ class SettingsManager(StartCheckMixin, Singleton):
def set_debug(self, debug): def set_debug(self, debug):
self._debug = debug self._debug = debug
def set_is_starting_with_file(self, is_passed_in_file: False): def set_is_starting_with_file(self, is_passed_in_file: bool = False):
self._passed_in_file = is_passed_in_file self._passed_in_file = is_passed_in_file
def load_settings(self): def load_settings(self):
@ -212,4 +212,4 @@ class SettingsManager(StartCheckMixin, Singleton):
def save_settings(self): def save_settings(self):
with open(self._CONFIG_FILE, 'w') as outfile: with open(self._CONFIG_FILE, 'w') as outfile:
json.dump(self.settings.as_dict(), outfile, separators=(',', ':'), indent=4) json.dump(self.settings.as_dict(), outfile, separators=(',', ':'), indent=4)

View File

@ -61,4 +61,4 @@ class StartCheckMixin:
def _write_pid(self, pid): def _write_pid(self, pid):
with open(self._PID_FILE, "w") as _pid: with open(self._PID_FILE, "w") as _pid:
_pid.write(f"{pid}") _pid.write(f"{pid}")