summaryrefslogtreecommitdiff
path: root/lsp-parse.c
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-29 11:36:33 -0500
committerpommicket <pommicket@gmail.com>2022-12-29 11:36:33 -0500
commit948decc409bac1e3671afc5d0212b4b35c669b4a (patch)
treeb3d8e128cbfe8928767786a46b91047ac1a5d346 /lsp-parse.c
parent1f9cd2a40d72d7982e8a9ff93e5ad432e14accc3 (diff)
more hover
Diffstat (limited to 'lsp-parse.c')
-rw-r--r--lsp-parse.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/lsp-parse.c b/lsp-parse.c
index 555a62a..7141485 100644
--- a/lsp-parse.c
+++ b/lsp-parse.c
@@ -73,8 +73,11 @@ static bool parse_range(LSP *lsp, const JSON *json, JSONValue range_value, LSPRa
JSONObject range_object = range_value.val.object;
JSONValue start = json_object_get(json, range_object, "start");
JSONValue end = json_object_get(json, range_object, "end");
- return parse_position(lsp, json, start, &range->start)
+ bool success = parse_position(lsp, json, start, &range->start)
&& parse_position(lsp, json, end, &range->end);
+ if (!success)
+ memset(range, 0, sizeof *range);
+ return success;
}
@@ -403,6 +406,55 @@ static bool parse_signature_help(LSP *lsp, const JSON *json, LSPResponse *respon
return true;
}
+static bool parse_hover(LSP *lsp, const JSON *json, LSPResponse *response) {
+ LSPResponseHover *hover = &response->data.hover;
+ JSONObject result = json_force_object(json_get(json, "result"));
+
+ JSONValue range = json_object_get(json, result, "range");
+ parse_range(lsp, json, range, &hover->range);
+
+ JSONValue contents = json_object_get(json, result, "contents");
+
+ switch (contents.type) {
+ case JSON_OBJECT:
+ case JSON_STRING:
+ // all good
+ break;
+ case JSON_ARRAY: {
+ JSONArray contents_array = contents.val.array;
+ if (contents_array.len == 0) {
+ // the server probably should have just returned result: null.
+ // but the spec doesn't seem to forbid this, so we'll handle it.
+ return true;
+ }
+ // it's giving us multiple strings, but we'll just show the first one
+ contents = json_array_get(json, contents_array, 0);
+ } break;
+ default:
+ lsp_set_error(lsp, "Bad contents field on textDocument/hover response.");
+ return false;
+ }
+
+ // contents should either be a MarkupContent or a MarkedString
+ // i.e. it is either a string or has a member `value: string`
+ JSONString contents_string = {0};
+ if (contents.type == JSON_STRING) {
+ contents_string = contents.val.string;
+ } else {
+ JSONObject contents_object = json_force_object(contents);
+ JSONValue value = json_object_get(json, contents_object, "value");
+ if (value.type == JSON_STRING) {
+ contents_string = value.val.string;
+ } else {
+ lsp_set_error(lsp, "Bad contents field on textDocument/hover response.");
+ return false;
+ }
+ }
+
+ hover->contents = lsp_response_add_json_string(response, json, contents_string);
+ return true;
+}
+
// fills request->id/id_string appropriately given the request's json
// returns true on success
static WarnUnusedResult bool parse_id(JSON *json, LSPRequest *request) {
@@ -539,6 +591,9 @@ static void process_message(LSP *lsp, JSON *json) {
case LSP_REQUEST_SIGNATURE_HELP:
add_to_messages = parse_signature_help(lsp, json, &response);
break;
+ case LSP_REQUEST_HOVER:
+ add_to_messages = parse_hover(lsp, json, &response);
+ break;
case LSP_REQUEST_INITIALIZE: {
// it's the response to our initialize request!
if (result.type == JSON_OBJECT) {