lsp: Add support for delete workspaceEdit resource operation

This commit is contained in:
Mathias Fussenegger 2021-03-18 11:32:33 +01:00
parent 191afb42be
commit 84213b5b9a
3 changed files with 63 additions and 2 deletions

View File

@ -750,7 +750,7 @@ function protocol.make_client_capabilities()
workspaceFolders = true; workspaceFolders = true;
applyEdit = true; applyEdit = true;
workspaceEdit = { workspaceEdit = {
resourceOperations = {'rename', 'create',}, resourceOperations = {'rename', 'create', 'delete',},
}; };
}; };
callHierarchy = { callHierarchy = {

View File

@ -647,6 +647,27 @@ local function create_file(change)
end 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`. --- Applies a `WorkspaceEdit`.
--- ---
--@param workspace_edit (table) `WorkspaceEdit` --@param workspace_edit (table) `WorkspaceEdit`
@ -662,8 +683,9 @@ function M.apply_workspace_edit(workspace_edit)
) )
elseif change.kind == 'create' then elseif change.kind == 'create' then
create_file(change) create_file(change)
elseif change.kind == 'delete' then
delete_file(change)
elseif change.kind then elseif change.kind then
-- TODO(ashkan) handle DeleteFile
error(string.format("Unsupported change: %q", vim.inspect(change))) error(string.format("Unsupported change: %q", vim.inspect(change)))
else else
M.apply_text_document_edit(change, idx) M.apply_text_document_edit(change, idx)

View File

@ -1319,6 +1319,45 @@ describe('LSP', function()
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile)) eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
eq('', read_file(tmpfile)) eq('', read_file(tmpfile))
end) end)
it('DeleteFile delete file and buffer', function()
local tmpfile = helpers.tmpname()
write_file(tmpfile, 'Be gone')
local uri = exec_lua([[
local fname = select(1, ...)
local bufnr = vim.fn.bufadd(fname)
vim.fn.bufload(bufnr)
return vim.uri_from_fname(fname)
]], tmpfile)
local edit = {
documentChanges = {
{
kind = 'delete',
uri = uri,
}
}
}
eq(true, pcall(exec_lua, 'vim.lsp.util.apply_workspace_edit(...)', edit))
eq(false, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
eq(false, exec_lua('return vim.api.nvim_buf_is_loaded(vim.fn.bufadd(...))', tmpfile))
end)
it('DeleteFile fails if file does not exist and ignoreIfNotExists is false', function()
local tmpfile = helpers.tmpname()
os.remove(tmpfile)
local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile)
local edit = {
documentChanges = {
{
kind = 'delete',
uri = uri,
options = {
ignoreIfNotExists = false,
}
}
}
}
eq(false, pcall(exec_lua, 'vim.lsp.util.apply_workspace_edit(...)', edit))
eq(false, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
end)
end) end)
describe('completion_list_to_complete_items', function() describe('completion_list_to_complete_items', function()