lsp: Add support for create workspaceEdit resource operation

This commit is contained in:
Mathias Fussenegger
2021-03-18 11:07:06 +01:00
parent 5e401b693b
commit 191afb42be
3 changed files with 70 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',}, resourceOperations = {'rename', 'create',},
}; };
}; };
callHierarchy = { callHierarchy = {

View File

@@ -635,6 +635,18 @@ function M.rename(old_fname, new_fname, opts)
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
--- Applies a `WorkspaceEdit`. --- Applies a `WorkspaceEdit`.
--- ---
--@param workspace_edit (table) `WorkspaceEdit` --@param workspace_edit (table) `WorkspaceEdit`
@@ -648,8 +660,10 @@ function M.apply_workspace_edit(workspace_edit)
vim.uri_to_fname(change.newUri), vim.uri_to_fname(change.newUri),
change.options change.options
) )
elseif change.kind == 'create' then
create_file(change)
elseif change.kind then elseif change.kind then
-- TODO(ashkan) handle CreateFile/DeleteFile -- 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

@@ -1265,6 +1265,60 @@ describe('LSP', function()
return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false) return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false)
]], make_workspace_edit(edits), target_bufnr)) ]], make_workspace_edit(edits), target_bufnr))
end) end)
it('Supports file creation with CreateFile payload', function()
local tmpfile = helpers.tmpname()
os.remove(tmpfile) -- Should not exist, only interested in a tmpname
local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile)
local edit = {
documentChanges = {
{
kind = 'create',
uri = uri,
},
}
}
exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit)
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
end)
it('createFile does not touch file if it exists and ignoreIfExists is set', function()
local tmpfile = helpers.tmpname()
write_file(tmpfile, 'Dummy content')
local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile)
local edit = {
documentChanges = {
{
kind = 'create',
uri = uri,
options = {
ignoreIfExists = true,
},
},
}
}
exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit)
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
eq('Dummy content', read_file(tmpfile))
end)
it('createFile overrides file if overwrite is set', function()
local tmpfile = helpers.tmpname()
write_file(tmpfile, 'Dummy content')
local uri = exec_lua('return vim.uri_from_fname(...)', tmpfile)
local edit = {
documentChanges = {
{
kind = 'create',
uri = uri,
options = {
overwrite = true,
ignoreIfExists = true, -- overwrite must win over ignoreIfExists
},
},
}
}
exec_lua('vim.lsp.util.apply_workspace_edit(...)', edit)
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', tmpfile))
eq('', read_file(tmpfile))
end)
end) end)
describe('completion_list_to_complete_items', function() describe('completion_list_to_complete_items', function()