From a11545e25cf2f65047158cc1fd7ed5a0f11a9fa0 Mon Sep 17 00:00:00 2001 From: pommicket Date: Tue, 27 Dec 2022 14:25:38 -0500 Subject: handle window/showMessageRequest (hopefully) --- lsp-parse.c | 60 ++++++++++++++++++++++++++++++++++++++++-------------------- lsp-write.c | 3 +++ lsp.h | 24 ++++++++++++------------ main.c | 2 +- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/lsp-parse.c b/lsp-parse.c index 979569e..a6e932e 100644 --- a/lsp-parse.c +++ b/lsp-parse.c @@ -297,6 +297,27 @@ static WarnUnusedResult bool parse_id(JSON *json, LSPRequest *request) { return false; } +// handles window/showMessage, window/logMessage, and window/showMessageRequest parameters +static bool parse_window_message(LSP *lsp, const JSON *json, LSPRequestMessage *m) { + JSONObject params = json_force_object(json_get(json, "params")); + JSONValue type = json_object_get(json, params, "type"); + JSONValue message = json_object_get(json, params, "message"); + if (!lsp_expect_number(lsp, type, "MessageType")) + return false; + if (!lsp_expect_string(lsp, message, "message string")) + return false; + + int mtype = (int)type.val.number; + if (mtype < 1 || mtype > 4) { + lsp_set_error(lsp, "Bad MessageType: %g", type.val.number); + return false; + } + + m->type = (LSPWindowMessageType)mtype; + m->message = json_string_get_alloc(json, message.val.string); + return true; +} + // returns true if `request` was actually filled with a request. static bool parse_server2client_request(LSP *lsp, JSON *json, LSPRequest *request) { JSONValue method_value = json_get(json, "method"); @@ -308,34 +329,29 @@ static bool parse_server2client_request(LSP *lsp, JSON *json, LSPRequest *reques if (streq(method, "window/showMessage")) { request->type = LSP_REQUEST_SHOW_MESSAGE; - goto window_message; - } else if (streq(method, "window/logMessage")) { - request->type = LSP_REQUEST_LOG_MESSAGE; - window_message:; - JSONValue type = json_get(json, "params.type"); - JSONValue message = json_get(json, "params.message"); - if (!lsp_expect_number(lsp, type, "MessageType")) - return false; - if (!lsp_expect_string(lsp, message, "message string")) - return false; - - int mtype = (int)type.val.number; - if (mtype < 1 || mtype > 4) { - lsp_set_error(lsp, "Bad MessageType: %g", type.val.number); + return parse_window_message(lsp, json, &request->data.message); + } else if (streq(method, "window/showMessageRequest")) { + // we'll deal with the repsonse right here + LSPResponse response = {0}; + LSPRequest *r = &response.request; + r->type = LSP_REQUEST_SHOW_MESSAGE; + if (!parse_id(json, request)) { + debug_println("Bad ID in window/showMessageRequest request. This shouldn't happen."); return false; } + lsp_send_response(lsp, &response); - LSPRequestMessage *m = &request->data.message; - m->type = (LSPWindowMessageType)mtype; - m->message = json_string_get_alloc(json, message.val.string); - return true; + request->type = LSP_REQUEST_SHOW_MESSAGE; + return parse_window_message(lsp, json, &request->data.message); + } else if (streq(method, "window/logMessage")) { + request->type = LSP_REQUEST_LOG_MESSAGE; + return parse_window_message(lsp, json, &request->data.message); } else if (streq(method, "workspace/workspaceFolders")) { // we can deal with this request right here LSPResponse response = {0}; request = &response.request; request->type = LSP_REQUEST_WORKSPACE_FOLDERS; if (!parse_id(json, request)) { - // we can't even send an error response since we have no ID. debug_println("Bad ID in workspace/workspaceFolders request. This shouldn't happen."); return false; } @@ -343,8 +359,10 @@ static bool parse_server2client_request(LSP *lsp, JSON *json, LSPRequest *reques return false; } else if (str_has_prefix(method, "$/") || str_has_prefix(method, "telemetry/")) { // we can safely ignore this + } else if (streq(method, "textDocument/publishDiagnostics")) { + // currently ignored } else { - lsp_set_error(lsp, "Unrecognized request method: %s", method); + debug_println("Unrecognized request method: %s", method); } return false; } @@ -431,6 +449,8 @@ static void process_message(LSP *lsp, JSON *json) { message->type = LSP_REQUEST; message->u.request = request; SDL_UnlockMutex(lsp->messages_mutex); + } else { + lsp_request_free(&request); } } else { lsp_set_error(lsp, "Bad message from server (no result, no method)."); diff --git a/lsp-write.c b/lsp-write.c index f633c2e..ecffe76 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -512,6 +512,9 @@ static void write_response(LSP *lsp, LSPResponse *response) { write_workspace_folders(o, lsp->workspace_folders); SDL_UnlockMutex(lsp->workspace_folders_mutex); break; + case LSP_REQUEST_SHOW_MESSAGE: + write_null(o); + break; default: // this is not a valid client-to-server response. assert(0); diff --git a/lsp.h b/lsp.h index 7fce761..5452dc2 100644 --- a/lsp.h +++ b/lsp.h @@ -25,20 +25,20 @@ typedef enum { LSP_REQUEST_NONE, // client-to-server - LSP_REQUEST_INITIALIZE, - LSP_REQUEST_INITIALIZED, - LSP_REQUEST_SHUTDOWN, - LSP_REQUEST_EXIT, - LSP_REQUEST_DID_OPEN, - LSP_REQUEST_DID_CLOSE, - LSP_REQUEST_DID_CHANGE, - LSP_REQUEST_COMPLETION, - LSP_REQUEST_DID_CHANGE_WORKSPACE_FOLDERS, + LSP_REQUEST_INITIALIZE, // initialize + LSP_REQUEST_INITIALIZED, // initialized + LSP_REQUEST_SHUTDOWN, // shutdown + LSP_REQUEST_EXIT, // exit + LSP_REQUEST_DID_OPEN, // textDocument/didOpen + LSP_REQUEST_DID_CLOSE, // textDocument/didClose + LSP_REQUEST_DID_CHANGE, // textDocument/didChange + LSP_REQUEST_COMPLETION, // textDocument/completion + LSP_REQUEST_DID_CHANGE_WORKSPACE_FOLDERS, // workspace/didChangeWorkspaceFolders // server-to-client - LSP_REQUEST_SHOW_MESSAGE, - LSP_REQUEST_LOG_MESSAGE, - LSP_REQUEST_WORKSPACE_FOLDERS, // NOTE: this is handled directly in lsp-parse.c (because it only needs information from the LSP struct) + LSP_REQUEST_SHOW_MESSAGE, // window/showMessage and window/showMessageRequest + LSP_REQUEST_LOG_MESSAGE, // window/logMessage + LSP_REQUEST_WORKSPACE_FOLDERS, // workspace/workspaceFolders - NOTE: this is handled directly in lsp-parse.c (because it only needs information from the LSP struct) } LSPRequestType; typedef struct { diff --git a/main.c b/main.c index 492bc8c..fc32768 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,5 @@ /* @TODO: -- handle window/showMessageRequest - https://github.com/typescript-language-server/typescript-language-server - NOTE: This supports javascript. - We should also add a typescript language (but just use javascript syntax highlighting for now) @@ -13,6 +12,7 @@ - go to definition using LSP - find usages - that thing where it shows you the current function argument +- check if there are any other non-optional/nice-to-have-support-for server-to-client requests - do something with lsp->error - document lsp.h and lsp.c. - maximum queue size for requests/responses just in case? -- cgit v1.2.3