diff options
Diffstat (limited to 'lsp-parse.c')
-rw-r--r-- | lsp-parse.c | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/lsp-parse.c b/lsp-parse.c index 1d84408..3834cd0 100644 --- a/lsp-parse.c +++ b/lsp-parse.c @@ -681,23 +681,84 @@ static bool parse_server2client_request(LSP *lsp, JSON *json, LSPRequest *reques } static bool parse_workspace_edit(LSP *lsp, LSPResponse *response, const JSON *json, JSONObject object, LSPWorkspaceEdit *edit) { - JSONObject changes = json_object_get_object(json, object, "changes"); + // the `changes` member is for changes to already-open documents + { + JSONObject changes = json_object_get_object(json, object, "changes"); + for (u32 c = 0; c < changes.len; ++c) { + JSONValue uri = json_object_key(json, changes, c); + JSONArray edits = json_force_array(json_object_value(json, changes, c)); + LSPDocumentID document = 0; + if (!parse_document_uri(lsp, json, uri, &document)) + return false; + for (u32 e = 0; e < edits.len; ++e) { + LSPWorkspaceChange *change = arr_addp(edit->changes); + change->type = LSP_CHANGE_EDIT; + change->data.edit.document = document; + JSONValue text_edit = json_array_get(json, edits, e); + if (!parse_text_edit(lsp, response, json, text_edit, &change->data.edit.edit)) + return false; + } + } + } + // the `documentChanges` member is for changes to other documents + JSONArray changes = json_object_get_array(json, object, "documentChanges"); for (u32 c = 0; c < changes.len; ++c) { - JSONValue uri = json_object_key(json, changes, c); - JSONArray edits = json_force_array(json_object_value(json, changes, c)); - LSPDocumentID document = 0; - if (!parse_document_uri(lsp, json, uri, &document)) - return false; - for (u32 e = 0; e < edits.len; ++e) { - LSPWorkspaceChange *change = arr_addp(edit->changes); - change->type = LSP_CHANGE_EDIT; - change->data.edit.document = document; - JSONValue text_edit = json_array_get(json, edits, e); - if (!parse_text_edit(lsp, response, json, text_edit, &change->data.edit.edit)) + JSONObject change = json_array_get_object(json, changes, c); + JSONValue kind = json_object_get(json, change, "kind"); + if (kind.type == JSON_UNDEFINED) { + // change is a TextDocumentEdit + JSONObject text_document = json_object_get_object(json, change, "textDocument"); + LSPDocumentID document=0; + if (!parse_document_uri(lsp, json, json_object_get(json, text_document, "uri"), &document)) return false; + JSONArray edits = json_object_get_array(json, change, "edits"); + for (u32 e = 0; e < edits.len; ++e) { + LSPWorkspaceChange *out = arr_addp(edit->changes); + out->type = LSP_CHANGE_EDIT; + out->data.edit.document = document; + JSONValue text_edit = json_array_get(json, edits, e); + if (!parse_text_edit(lsp, response, json, text_edit, &out->data.edit.edit)) + return false; + } + } else if (kind.type == JSON_STRING) { + char kind_str[32]={0}; + json_string_get(json, kind.val.string, kind_str, sizeof kind_str); + LSPWorkspaceChange *out = arr_addp(edit->changes); + if (streq(kind_str, "create")) { + out->type = LSP_CHANGE_CREATE; + LSPWorkspaceChangeCreate *create = &out->data.create; + if (!parse_document_uri(lsp, json, json_object_get(json, change, "uri"), &create->document)) + return false; + JSONObject options = json_object_get_object(json, change, "options"); + create->ignore_if_exists = json_object_get_bool(json, options, "ignoreIfExists", false); + create->overwrite = json_object_get_bool(json, options, "overwrite", false); + } else if (streq(kind_str, "rename")) { + out->type = LSP_CHANGE_RENAME; + LSPWorkspaceChangeRename *rename = &out->data.rename; + if (!parse_document_uri(lsp, json, json_object_get(json, change, "oldUri"), &rename->old)) + return false; + if (!parse_document_uri(lsp, json, json_object_get(json, change, "newUri"), &rename->new)) + return false; + JSONObject options = json_object_get_object(json, change, "options"); + rename->ignore_if_exists = json_object_get_bool(json, options, "ignoreIfExists", false); + rename->overwrite = json_object_get_bool(json, options, "overwrite", false); + } else if (streq(kind_str, "delete")) { + out->type = LSP_CHANGE_DELETE; + LSPWorkspaceChangeDelete *delete = &out->data.delete; + if (!parse_document_uri(lsp, json, json_object_get(json, change, "uri"), &delete->document)) + return false; + JSONObject options = json_object_get_object(json, change, "options"); + delete->ignore_if_not_exists = json_object_get_bool(json, options, "ignoreIfNotExists", false); + delete->recursive = json_object_get_bool(json, options, "recursive", false); + } else { + lsp_set_error(lsp, "Bad kind of workspace operation: '%s'", kind_str); + } + } else { + lsp_set_error(lsp, "Bad type for (TextDocumentEdit | CreateFile | RenameFile | DeleteFile).kind: %s", + json_type_to_str(kind.type)); } } - todo : the other thing + return true; } |