diff options
author | pommicket <pommicket@gmail.com> | 2023-08-07 07:19:56 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-08-07 07:19:56 -0400 |
commit | b146279b48f6a4f4bea8946cb3f0f1f5cc5a9985 (patch) | |
tree | 70069f2f622f3b6190fa1effcfb9ce9e14d8f94b /ide-rename-symbol.c | |
parent | bdbce6fe3c647616d22867bbc82e011c91231dd3 (diff) |
handle more complicated renames
Diffstat (limited to 'ide-rename-symbol.c')
-rw-r--r-- | ide-rename-symbol.c | 132 |
1 files changed, 83 insertions, 49 deletions
diff --git a/ide-rename-symbol.c b/ide-rename-symbol.c index 6f320ae..01f3106 100644 --- a/ide-rename-symbol.c +++ b/ide-rename-symbol.c @@ -120,72 +120,106 @@ void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) { return; } + if (response->error) { + ted_error(ted, "%s", response->error); + goto cleanup; + + } + const LSPResponseRename *data = &response->data.rename; LSP *lsp = ted_get_lsp_by_id(ted, rs->request_id.lsp); if (!lsp) { // LSP crashed or something - return; + goto cleanup; } - bool perform_changes = true; arr_foreach_ptr(data->changes, const LSPWorkspaceChange, change) { - if (change->type != LSP_CHANGE_EDIT) { - // TODO(eventually) : support these - ted_error(ted, "rename is too complicated for ted to perform."); - perform_changes = false; + if (change->type == LSP_CHANGE_DELETE && change->data.delete.recursive) { + ted_error(ted, "refusing to perform rename because it involves a recurisve deletion\n" + "I'm too scared to go through with this"); + goto cleanup; } } - if (perform_changes) { - - arr_foreach_ptr(data->changes, const LSPWorkspaceChange, change) { - switch (change->type) { - case LSP_CHANGE_EDIT: { - const LSPWorkspaceChangeEdit *change_data = &change->data.edit; - const char *path = lsp_document_path(lsp, change_data->document); - if (!ted_open_file(ted, path)) goto done; - - TextBuffer *buffer = ted_get_buffer_with_file(ted, path); - if (!buffer->will_chain_edits) { - // chain all edits together so they can be undone with one ctrl+z - buffer_start_edit_chain(buffer); - } - - if (!buffer) { - // this should never happen since we just - // successfully opened it - assert(0); - goto done; - } - - - const LSPTextEdit *edit = &change_data->edit; - BufferPos start = buffer_pos_from_lsp(buffer, edit->range.start); - BufferPos end = buffer_pos_from_lsp(buffer, edit->range.end); - buffer_delete_chars_between(buffer, start, end); - buffer_insert_utf8_at_pos(buffer, start, lsp_response_string(response, edit->new_text)); - - } - break; - case LSP_CHANGE_RENAME: - case LSP_CHANGE_DELETE: - case LSP_CHANGE_CREATE: + arr_foreach_ptr(data->changes, const LSPWorkspaceChange, change) { + switch (change->type) { + case LSP_CHANGE_EDIT: { + const LSPWorkspaceChangeEdit *change_data = &change->data.edit; + const char *path = lsp_document_path(lsp, change_data->document); + if (!ted_open_file(ted, path)) goto done; + + TextBuffer *buffer = ted_get_buffer_with_file(ted, path); + if (!buffer->will_chain_edits) { + // chain all edits together so they can be undone with one ctrl+z + buffer_start_edit_chain(buffer); + } + + if (!buffer) { + // this should never happen since we just + // successfully opened it assert(0); + goto done; + } + + + const LSPTextEdit *edit = &change_data->edit; + BufferPos start = buffer_pos_from_lsp(buffer, edit->range.start); + BufferPos end = buffer_pos_from_lsp(buffer, edit->range.end); + buffer_delete_chars_between(buffer, start, end); + buffer_insert_utf8_at_pos(buffer, start, lsp_response_string(response, edit->new_text)); + + } + break; + case LSP_CHANGE_RENAME: { + const LSPWorkspaceChangeRename *rename = &change->data.rename; + const char *old = lsp_document_path(lsp, rename->old); + const char *new = lsp_document_path(lsp, rename->new); + FsType new_type = fs_path_type(new); + if (new_type == FS_DIRECTORY) { + ted_error(ted, "Aborting rename since it's asking to overwrite a directory."); + goto done; + } + + if (rename->ignore_if_exists && new_type != FS_NON_EXISTENT) { break; } - } - done: - - // end all edit chains in all buffers - // they're almost definitely all created by us - for (u16 i = 0; i < TED_MAX_BUFFERS; ++i) { - if (ted->buffers_used[i]) { - TextBuffer *buffer = &ted->buffers[i]; - buffer_end_edit_chain(buffer); + if (!rename->overwrite && new_type != FS_NON_EXISTENT) { + ted_error(ted, "Aborting rename since it would overwrite a file."); + goto done; } + os_rename_overwrite(old, new); + if (ted_close_buffer_with_file(ted, old)) + ted_open_file(ted, new); + } break; + case LSP_CHANGE_DELETE: { + const LSPWorkspaceChangeDelete *delete = &change->data.delete; + const char *path = lsp_document_path(lsp, delete->document); + remove(path); + ted_close_buffer_with_file(ted, path); + } break; + case LSP_CHANGE_CREATE: { + const LSPWorkspaceChangeCreate *create = &change->data.create; + const char *path = lsp_document_path(lsp, create->document); + FILE *fp = fopen(path, create->overwrite ? "wb" : "ab"); + if (fp) fclose(fp); + ted_open_file(ted, path); + } break; } } + done: + + // end all edit chains in all buffers + // they're almost definitely all created by us + for (u16 i = 0; i < TED_MAX_BUFFERS; ++i) { + if (ted->buffers_used[i]) { + TextBuffer *buffer = &ted->buffers[i]; + buffer_end_edit_chain(buffer); + } + } + + ted_save_all(ted); + cleanup: rename_symbol_clear(ted); if (menu_is_open(ted, MENU_RENAME_SYMBOL)) menu_close(ted); |