diff options
Diffstat (limited to 'lsp-write.c')
-rw-r--r-- | lsp-write.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/lsp-write.c b/lsp-write.c index c1c846a..6c6d5a6 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -250,6 +250,68 @@ static void write_document_position(JSONWriter *o, LSPDocumentPosition pos) { write_key_position(o, "position", pos.pos); } + +static void json_reserialize_to(const JSON *json, JSONWriter *o, JSONValue val) { + switch (val.type) { + case JSON_UNDEFINED: + assert(false); + break; + case JSON_TRUE: + write_bool(o, true); + break; + case JSON_FALSE: + write_bool(o, false); + break; + case JSON_NULL: + write_null(o); + break; + case JSON_NUMBER: + write_number(o, val.val.number); + break; + case JSON_STRING: { + char *s = json_string_get_alloc(json, val.val.string); + write_string(o, s); + free(s); + } break; + case JSON_ARRAY: { + JSONArray array = val.val.array; + write_arr_start(o); + for (u32 i = 0; i < array.len; i++) { + JSONValue elem = json_array_get(json, array, i); + write_arr_elem(o); + json_reserialize_to(json, o, elem); + } + write_arr_end(o); + } break; + case JSON_OBJECT: { + JSONObject object = val.val.object; + write_obj_start(o); + JSONValue *keys = &json->values[object.items]; + JSONValue *values = keys + object.len; + for (u32 i = 0; i < object.len; i++) { + JSONValue key_val = keys[i]; + assert(key_val.type == JSON_STRING); + JSONString key = key_val.val.string; + JSONValue value = values[i]; + char *key_str = json_string_get_alloc(json, key); + write_key(o, key_str); + free(key_str); + json_reserialize_to(json, o, value); + } + write_obj_end(o); + } break; + } +} + +char *json_reserialize(const JSON *json, JSONValue value) { + StrBuilder builder = str_builder_new(); + JSONWriter writer = json_writer_new(NULL, &builder); + json_reserialize_to(json, &writer, value); + char *str = str_dup(builder.str); + str_builder_free(&builder); + return str; +} + static const char *lsp_request_method(LSPRequest *request) { switch (request->type) { case LSP_REQUEST_NONE: break; @@ -311,6 +373,8 @@ static const char *lsp_request_method(LSPRequest *request) { return "textDocument/rangeFormatting"; case LSP_REQUEST_FORMATTING: return "textDocument/formatting"; + case LSP_REQUEST_CODE_ACTION: + return "textDocument/codeAction"; } assert(0); return "$/ignore"; @@ -468,6 +532,24 @@ void write_request(LSP *lsp, LSPRequest *request, StrBuilder *builder) { write_key_obj_start(o, "publishDiagnostics"); write_key_bool(o, "codeDescriptionSupport", true); write_obj_end(o); + + write_key_obj_start(o, "codeAction"); + write_key_bool(o, "isPreferredSupport", true); + write_key_obj_start(o, "codeActionLiteralSupport"); + write_key_obj_start(o, "codeActionKind"); + write_key_arr_start(o, "valueSet"); + write_arr_elem_string(o, "quickfix"); + write_arr_elem_string(o, "refactor"); + write_arr_elem_string(o, "refactor.extract"); + write_arr_elem_string(o, "refactor.inline"); + write_arr_elem_string(o, "refactor.rewrite"); + write_arr_elem_string(o, "source"); + write_arr_elem_string(o, "source.organizeImports"); + write_arr_elem_string(o, "source.fixAll"); + write_arr_end(o); + write_obj_end(o); + write_obj_end(o); + write_obj_end(o); write_obj_end(o); write_key_obj_start(o, "workspace"); write_key_bool(o, "workspaceFolders", true); @@ -670,6 +752,23 @@ void write_request(LSP *lsp, LSPRequest *request, StrBuilder *builder) { } write_obj_end(o); } break; + case LSP_REQUEST_CODE_ACTION: { + LSPRequestCodeAction *code_action = &request->data.code_action; + write_key_obj_start(o, "params"); + write_key_obj_start(o, "textDocument"); + write_key_file_uri(o, "uri", code_action->document); + write_obj_end(o); + write_key_range(o, "range", code_action->range); + write_key_obj_start(o, "context"); + write_key_arr_start(o, "diagnostics"); + arr_foreach_ptr(code_action->raw_diagnostics, const LSPString, raw_diagnostic) { + write_arr_elem(o); + str_builder_append(o->builder, lsp_request_string(request, *raw_diagnostic)); + } + write_arr_end(o); + write_obj_end(o); + write_obj_end(o); + } break; } write_obj_end(o); |