diff options
| author | Albert Cervin <albert@acervin.com> | 2025-11-21 23:38:54 +0100 |
|---|---|---|
| committer | Albert Cervin <albert@acervin.com> | 2025-11-21 23:38:54 +0100 |
| commit | 5019b312d999f4f9c6a6acee1f047b9587c06f79 (patch) | |
| tree | caa5bac2ffda56978dc097aab7887622d439af5a /src/main/lsp | |
| parent | 715165b53f055b785e005984038bcae8d88142db (diff) | |
| download | dged-5019b312d999f4f9c6a6acee1f047b9587c06f79.tar.gz dged-5019b312d999f4f9c6a6acee1f047b9587c06f79.tar.xz dged-5019b312d999f4f9c6a6acee1f047b9587c06f79.zip | |
Add support for documentChanges in LSP
These should ideally be paired with setting the capability on
initialize, but for now, the parsing support is there at least for
LSP servers that ignore it (like pylsp).
Diffstat (limited to 'src/main/lsp')
| -rw-r--r-- | src/main/lsp/types.c | 59 | ||||
| -rw-r--r-- | src/main/lsp/types.h | 8 |
2 files changed, 67 insertions, 0 deletions
diff --git a/src/main/lsp/types.c b/src/main/lsp/types.c index bd87377..870ca3d 100644 --- a/src/main/lsp/types.c +++ b/src/main/lsp/types.c @@ -6,8 +6,10 @@ #include "dged/buffer.h" #include "dged/display.h" +#include "dged/json.h" #include "dged/path.h" #include "dged/s8.h" +#include "dged/vec.h" struct s8 initialize_params_to_json(struct initialize_params *params) { char *cwd = getcwd(NULL, 0); @@ -730,6 +732,46 @@ static void changes_from_json(struct s8 key, struct json_value *json, VEC_PUSH(vec, pair); } +static void document_change_from_json(uint64_t id, struct json_value *value, + void *userdata) { + (void)id; + text_document_edit_vec *vec = (text_document_edit_vec *)userdata; + + if (value->type != Json_Object) { + return; + } + + struct json_object *obj = value->value.object; + + struct json_value *text_doc = json_get(obj, s8("textDocument")); + + struct versioned_text_document_identifier doc_id = {0}; + + if (text_doc != NULL && text_doc->type == Json_Object) { + struct json_object *text_doc_object = text_doc->value.object; + struct json_value *uri = json_get(text_doc_object, s8("uri")); + if (uri != NULL && uri->type == Json_String) { + doc_id.uri = unescape_json_string(uri->value.string); + } + + struct json_value *version = json_get(text_doc_object, s8("version")); + if (version != NULL && version->type == Json_Number) { + doc_id.version = uri->value.number; + } + } else { + return; + } + + struct json_value *edits = json_get(obj, s8("edits")); + if (edits == NULL || edits->type != Json_Array) { + return; + } + + struct text_document_edit edit = {.text_document = doc_id, + .edits = text_edits_from_json(edits)}; + VEC_PUSH(vec, edit); +} + struct workspace_edit workspace_edit_from_json(struct json_value *json) { struct workspace_edit edit; struct json_object *obj = json->value.object; @@ -747,6 +789,16 @@ struct workspace_edit workspace_edit_from_json(struct json_value *json) { VEC_INIT(&edit.changes, 0); } + struct json_value *document_changes = json_get(obj, s8("documentChanges")); + if (document_changes != NULL && document_changes->type == Json_Array) { + struct json_array *doc_changes_arr = document_changes->value.array; + VEC_INIT(&edit.document_changes, json_array_len(doc_changes_arr)); + json_array_foreach(doc_changes_arr, &edit.document_changes, + document_change_from_json); + } else { + VEC_INIT(&edit.document_changes, 0); + } + return edit; } @@ -759,6 +811,13 @@ void workspace_edit_free(struct workspace_edit *edit) { VEC_DESTROY(&pair->edits); } VEC_DESTROY(&edit->changes); + + VEC_FOR_EACH(&edit->document_changes, struct text_document_edit * doc_edit) { + versioned_text_document_identifier_free(&doc_edit->text_document); + text_edits_free(doc_edit->edits); + } + + VEC_DESTROY(&edit->document_changes); } uint32_t diag_severity_color(enum diagnostic_severity severity) { diff --git a/src/main/lsp/types.h b/src/main/lsp/types.h index 7b6ba1a..e7423b6 100644 --- a/src/main/lsp/types.h +++ b/src/main/lsp/types.h @@ -181,8 +181,16 @@ struct text_edit_pair { typedef VEC(struct text_edit_pair) change_vec; +struct text_document_edit { + struct versioned_text_document_identifier text_document; + text_edit_vec edits; +}; + +typedef VEC(struct text_document_edit) text_document_edit_vec; + struct workspace_edit { change_vec changes; + text_document_edit_vec document_changes; }; struct lsp_command { |
