aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/util.lua
diff options
context:
space:
mode:
authorMichael Lingelbach <m.j.lbach@gmail.com>2021-03-18 12:27:16 -0700
committerGitHub <noreply@github.com>2021-03-18 12:27:16 -0700
commitf31b8dabfd999e49c98c736a49f168e27fba6a9b (patch)
tree1c949c17cf99f1b4e144ad8ae9aab33d122a9137 /runtime/lua/vim/lsp/util.lua
parent0ab88c2ea80caa7cda97b3a8479d0d32e4636ab6 (diff)
parent84213b5b9adfaaf133771432ca468cea8faa4cc9 (diff)
downloadrneovim-f31b8dabfd999e49c98c736a49f168e27fba6a9b.tar.gz
rneovim-f31b8dabfd999e49c98c736a49f168e27fba6a9b.tar.bz2
rneovim-f31b8dabfd999e49c98c736a49f168e27fba6a9b.zip
Merge pull request #14144 from mfussenegger/lsp-workspace-edit-rename
lsp: Add support for create,rename,delete workspaceEdit resourceOperations
Diffstat (limited to 'runtime/lua/vim/lsp/util.lua')
-rw-r--r--runtime/lua/vim/lsp/util.lua69
1 files changed, 67 insertions, 2 deletions
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 4b528d7090..6945d0f1ec 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -612,6 +612,62 @@ function M.text_document_completion_list_to_complete_items(result, prefix)
return matches
end
+
+--- Rename old_fname to new_fname
+--
+--@param opts (table)
+-- overwrite? bool
+-- ignoreIfExists? bool
+function M.rename(old_fname, new_fname, opts)
+ opts = opts or {}
+ local bufnr = vim.fn.bufadd(old_fname)
+ vim.fn.bufload(bufnr)
+ local target_exists = vim.loop.fs_stat(new_fname) ~= nil
+ if target_exists and not opts.overwrite or opts.ignoreIfExists then
+ vim.notify('Rename target already exists. Skipping rename.')
+ return
+ end
+ local ok, err = os.rename(old_fname, new_fname)
+ assert(ok, err)
+ api.nvim_buf_call(bufnr, function()
+ vim.cmd('saveas! ' .. vim.fn.fnameescape(new_fname))
+ end)
+end
+
+
+local function create_file(change)
+ local opts = change.options or {}
+ -- from spec: Overwrite wins over `ignoreIfExists`
+ local fname = vim.uri_to_fname(change.uri)
+ if not opts.ignoreIfExists or opts.overwrite then
+ local file = io.open(fname, 'w')
+ file:close()
+ end
+ vim.fn.bufadd(fname)
+end
+
+
+local function delete_file(change)
+ local opts = change.options or {}
+ local fname = vim.uri_to_fname(change.uri)
+ local stat = vim.loop.fs_stat(fname)
+ if opts.ignoreIfNotExists and not stat then
+ return
+ end
+ assert(stat, "Cannot delete not existing file or folder " .. fname)
+ local flags
+ if stat and stat.type == 'directory' then
+ flags = opts.recursive and 'rf' or 'd'
+ else
+ flags = ''
+ end
+ local bufnr = vim.fn.bufadd(fname)
+ local result = tonumber(vim.fn.delete(fname, flags))
+ assert(result == 0, 'Could not delete file: ' .. fname .. ', stat: ' .. vim.inspect(stat))
+ api.nvim_buf_delete(bufnr, { force = true })
+end
+
+
--- Applies a `WorkspaceEdit`.
---
--@param workspace_edit (table) `WorkspaceEdit`
@@ -619,8 +675,17 @@ end
function M.apply_workspace_edit(workspace_edit)
if workspace_edit.documentChanges then
for idx, change in ipairs(workspace_edit.documentChanges) do
- if change.kind then
- -- TODO(ashkan) handle CreateFile/RenameFile/DeleteFile
+ if change.kind == "rename" then
+ M.rename(
+ vim.uri_to_fname(change.oldUri),
+ vim.uri_to_fname(change.newUri),
+ change.options
+ )
+ elseif change.kind == 'create' then
+ create_file(change)
+ elseif change.kind == 'delete' then
+ delete_file(change)
+ elseif change.kind then
error(string.format("Unsupported change: %q", vim.inspect(change)))
else
M.apply_text_document_edit(change, idx)