diff options
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 16 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 54 |
3 files changed, 70 insertions, 2 deletions
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 187aad7684..085ca7b4a1 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -750,7 +750,7 @@ function protocol.make_client_capabilities() workspaceFolders = true; applyEdit = true; workspaceEdit = { - resourceOperations = {'rename',}, + resourceOperations = {'rename', 'create',}, }; }; callHierarchy = { diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 601a6ae8ca..82fd77ea90 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -635,6 +635,18 @@ function M.rename(old_fname, new_fname, opts) 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`. --- --@param workspace_edit (table) `WorkspaceEdit` @@ -648,8 +660,10 @@ function M.apply_workspace_edit(workspace_edit) vim.uri_to_fname(change.newUri), change.options ) + elseif change.kind == 'create' then + create_file(change) elseif change.kind then - -- TODO(ashkan) handle CreateFile/DeleteFile + -- TODO(ashkan) handle DeleteFile error(string.format("Unsupported change: %q", vim.inspect(change))) else M.apply_text_document_edit(change, idx) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 2fd9934e7d..eb8f5e8824 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -1265,6 +1265,60 @@ describe('LSP', function() return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false) ]], make_workspace_edit(edits), target_bufnr)) 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) describe('completion_list_to_complete_items', function() |