From 37275ad25635624161c3b51bc81cbd431a200e0c Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 30 Dec 2022 22:31:37 -0500 Subject: textDocument/references request --- ide-hover.c | 1 + lsp-parse.c | 21 +++++++++++++++++++++ lsp-write.c | 15 +++++++++++++++ lsp.c | 7 +++++++ lsp.h | 14 ++++++++++++++ main.c | 5 +++-- 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/ide-hover.c b/ide-hover.c index 80f2a09..77aec96 100644 --- a/ide-hover.c +++ b/ide-hover.c @@ -12,6 +12,7 @@ static bool get_hover_position(Ted *ted, LSPDocumentPosition *pos, TextBuffer ** TextBuffer *buffer = NULL; if (ted_get_mouse_buffer_pos(ted, &buffer, &mouse_pos)) { LSP *l = buffer_lsp(buffer); + if (!l) return false; if (pos) *pos = buffer_pos_to_lsp_document_position(buffer, mouse_pos); if (pbuffer) *pbuffer = buffer; if (lsp) *lsp = l; diff --git a/lsp-parse.c b/lsp-parse.c index 7a0c630..719b8c6 100644 --- a/lsp-parse.c +++ b/lsp-parse.c @@ -164,6 +164,12 @@ static void parse_capabilities(LSP *lsp, const JSON *json, JSONObject capabiliti cap->highlight_support = true; } + // check for textDocument/references support + JSONValue references_value = json_object_get(json, capabilities, "referencesProvider"); + if (references_value.type != JSON_UNDEFINED && references_value.type != JSON_FALSE) { + cap->references_support = true; + } + // check for textDocument/rename support JSONValue rename_value = json_object_get(json, capabilities, "renameProvider"); if (rename_value.type != JSON_UNDEFINED && rename_value.type != JSON_FALSE) { @@ -792,6 +798,18 @@ static bool parse_highlight(LSP *lsp, const JSON *json, LSPResponse *response) { return true; } +static bool parse_references(LSP *lsp, const JSON *json, LSPResponse *response) { + LSPResponseReferences *refs = &response->data.references; + JSONArray result = json_force_array(json_get(json, "result")); + for (u32 r = 0; r < result.len; ++r) { + JSONValue location_in = json_array_get(json, result, r); + LSPLocation *location_out = arr_addp(refs->locations); + if (!parse_location(lsp, json, location_in, location_out)) + return false; + } + return true; +} + static void process_message(LSP *lsp, JSON *json) { #if 0 @@ -847,6 +865,9 @@ static void process_message(LSP *lsp, JSON *json) { case LSP_REQUEST_HIGHLIGHT: add_to_messages = parse_highlight(lsp, json, &response); break; + case LSP_REQUEST_REFERENCES: + add_to_messages = parse_references(lsp, json, &response); + break; case LSP_REQUEST_WORKSPACE_SYMBOLS: add_to_messages = parse_workspace_symbols(lsp, json, &response); break; diff --git a/lsp-write.c b/lsp-write.c index 3255ec0..3c2c11a 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -271,6 +271,8 @@ static const char *lsp_request_method(LSPRequest *request) { return "textDocument/signatureHelp"; case LSP_REQUEST_HOVER: return "textDocument/hover"; + case LSP_REQUEST_REFERENCES: + return "textDocument/references"; case LSP_REQUEST_DEFINITION: return "textDocument/definition"; case LSP_REQUEST_HIGHLIGHT: @@ -552,6 +554,19 @@ static void write_request(LSP *lsp, LSPRequest *request) { write_document_position(o, hl->position); write_obj_end(o); } break; + case LSP_REQUEST_REFERENCES: { + const LSPRequestReferences *refs = &request->data.references; + write_key_obj_start(o, "params"); + write_document_position(o, refs->position); + write_key_obj_start(o, "context"); + // why is this includeDeclaration thing which has nothing to do with context + // why is it in an object called context + // there's no other members of the ReferenceContext interface. just this. + // why, LSP, why + write_key_bool(o, "includeDeclaration", refs->include_declaration); + write_obj_end(o); + write_obj_end(o); + } break; case LSP_REQUEST_RENAME: { const LSPRequestRename *rename = &request->data.rename; write_key_obj_start(o, "params"); diff --git a/lsp.c b/lsp.c index 23b1023..81cb4c9 100644 --- a/lsp.c +++ b/lsp.c @@ -52,6 +52,7 @@ static void lsp_request_free(LSPRequest *r) { case LSP_REQUEST_SIGNATURE_HELP: case LSP_REQUEST_HOVER: case LSP_REQUEST_DEFINITION: + case LSP_REQUEST_REFERENCES: case LSP_REQUEST_HIGHLIGHT: case LSP_REQUEST_DID_CLOSE: case LSP_REQUEST_WORKSPACE_FOLDERS: @@ -107,6 +108,9 @@ static void lsp_response_free(LSPResponse *r) { case LSP_REQUEST_HIGHLIGHT: arr_free(r->data.highlight.highlights); break; + case LSP_REQUEST_REFERENCES: + arr_free(r->data.references.locations); + break; default: break; } @@ -182,6 +186,8 @@ static bool lsp_supports_request(LSP *lsp, const LSPRequest *request) { return cap->rename_support; case LSP_REQUEST_HIGHLIGHT: return cap->highlight_support; + case LSP_REQUEST_REFERENCES: + return cap->references_support; } assert(0); return false; @@ -214,6 +220,7 @@ static bool request_type_is_notification(LSPRequestType type) { case LSP_REQUEST_SIGNATURE_HELP: case LSP_REQUEST_HOVER: case LSP_REQUEST_DEFINITION: + case LSP_REQUEST_REFERENCES: case LSP_REQUEST_RENAME: case LSP_REQUEST_WORKSPACE_SYMBOLS: case LSP_REQUEST_WORKSPACE_FOLDERS: diff --git a/lsp.h b/lsp.h index d52c20b..6b8cc9b 100644 --- a/lsp.h +++ b/lsp.h @@ -53,6 +53,7 @@ typedef enum { LSP_REQUEST_HOVER, // textDocument/hover LSP_REQUEST_DEFINITION, // textDocument/definition LSP_REQUEST_HIGHLIGHT, // textDocument/documentHighlight + LSP_REQUEST_REFERENCES, // textDocument/references LSP_REQUEST_RENAME, // textDocument/rename LSP_REQUEST_WORKSPACE_SYMBOLS, // workspace/symbol LSP_REQUEST_DID_CHANGE_WORKSPACE_FOLDERS, // workspace/didChangeWorkspaceFolders @@ -153,6 +154,11 @@ typedef struct { LSPDocumentPosition position; } LSPRequestHighlight; +typedef struct { + LSPDocumentPosition position; + bool include_declaration; +} LSPRequestReferences; + typedef struct { char *query; } LSPRequestWorkspaceSymbols; @@ -162,6 +168,7 @@ typedef struct { char *new_name; } LSPRequestRename; + typedef struct { LSPDocumentID *removed; // dynamic array LSPDocumentID *added; // dynamic array @@ -182,6 +189,7 @@ typedef struct { LSPRequestHover hover; LSPRequestDefinition definition; LSPRequestHighlight highlight; + LSPRequestReferences references; LSPRequestWorkspaceSymbols workspace_symbols; // LSP_REQUEST_SHOW_MESSAGE or LSP_REQUEST_LOG_MESSAGE LSPRequestMessage message; @@ -350,6 +358,10 @@ typedef struct { LSPHighlight *highlights; } LSPResponseHighlight; +typedef struct { + LSPLocation *locations; +} LSPResponseReferences; + typedef enum { #define LSP_SYMBOL_TAG_MIN 1 LSP_SYMBOL_TAG_DEPRECATED = 1 @@ -432,6 +444,7 @@ typedef struct { LSPResponseWorkspaceSymbols workspace_symbols; LSPResponseRename rename; LSPResponseHighlight highlight; + LSPResponseReferences references; } data; } LSPResponse; @@ -460,6 +473,7 @@ typedef struct { // (but jdtls and gopls do) bool workspace_folders_support; bool rename_support; + bool references_support; } LSPCapabilities; typedef struct LSP { diff --git a/main.c b/main.c index b1bb6e5..3e947ae 100644 --- a/main.c +++ b/main.c @@ -1,10 +1,11 @@ /* @TODO: +- find usages (textDocument/references) - clip highlight to buffer rect - different highlight colors +- --help, --version +- framerate-cap setting - highlight-enabled, and highlight-auto -- more LSP stuff: - - find usages (textDocument/references) - handle multiple symbols with same name in go-to-definition menu - :go-to-cursor-definition - test full unicode position handling -- cgit v1.2.3