mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
lsp: Add support for file rename via workspaceEdit
This commit is contained in:
parent
0ab88c2ea8
commit
5e401b693b
@ -749,6 +749,9 @@ function protocol.make_client_capabilities()
|
||||
};
|
||||
workspaceFolders = true;
|
||||
applyEdit = true;
|
||||
workspaceEdit = {
|
||||
resourceOperations = {'rename',},
|
||||
};
|
||||
};
|
||||
callHierarchy = {
|
||||
dynamicRegistration = false;
|
||||
|
@ -612,6 +612,29 @@ 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
|
||||
|
||||
|
||||
--- Applies a `WorkspaceEdit`.
|
||||
---
|
||||
--@param workspace_edit (table) `WorkspaceEdit`
|
||||
@ -619,8 +642,14 @@ 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 then
|
||||
-- TODO(ashkan) handle CreateFile/DeleteFile
|
||||
error(string.format("Unsupported change: %q", vim.inspect(change)))
|
||||
else
|
||||
M.apply_text_document_edit(change, idx)
|
||||
|
@ -11,6 +11,8 @@ local pesc = helpers.pesc
|
||||
local insert = helpers.insert
|
||||
local retry = helpers.retry
|
||||
local NIL = helpers.NIL
|
||||
local read_file = require('test.helpers').read_file
|
||||
local write_file = require('test.helpers').write_file
|
||||
|
||||
-- Use these to get access to a coroutine so that I can run async tests and use
|
||||
-- yield.
|
||||
@ -1309,6 +1311,72 @@ describe('LSP', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('lsp.util.rename', function()
|
||||
it('Can rename an existing file', function()
|
||||
local old = helpers.tmpname()
|
||||
write_file(old, 'Test content')
|
||||
local new = helpers.tmpname()
|
||||
os.remove(new) -- only reserve the name, file must not exist for the test scenario
|
||||
local lines = exec_lua([[
|
||||
local old = select(1, ...)
|
||||
local new = select(2, ...)
|
||||
vim.lsp.util.rename(old, new)
|
||||
|
||||
-- after rename the target file must have the contents of the source file
|
||||
local bufnr = vim.fn.bufadd(new)
|
||||
return vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
||||
]], old, new)
|
||||
eq({'Test content'}, lines)
|
||||
local exists = exec_lua('return vim.loop.fs_stat(...) ~= nil', old)
|
||||
eq(false, exists)
|
||||
exists = exec_lua('return vim.loop.fs_stat(...) ~= nil', new)
|
||||
eq(true, exists)
|
||||
os.remove(new)
|
||||
end)
|
||||
it('Does not rename file if target exists and ignoreIfExists is set or overwrite is false', function()
|
||||
local old = helpers.tmpname()
|
||||
write_file(old, 'Old File')
|
||||
local new = helpers.tmpname()
|
||||
write_file(new, 'New file')
|
||||
|
||||
exec_lua([[
|
||||
local old = select(1, ...)
|
||||
local new = select(2, ...)
|
||||
|
||||
vim.lsp.util.rename(old, new, { ignoreIfExists = true })
|
||||
]], old, new)
|
||||
|
||||
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', old))
|
||||
eq('New file', read_file(new))
|
||||
|
||||
exec_lua([[
|
||||
local old = select(1, ...)
|
||||
local new = select(2, ...)
|
||||
|
||||
vim.lsp.util.rename(old, new, { overwrite = false })
|
||||
]], old, new)
|
||||
|
||||
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', old))
|
||||
eq('New file', read_file(new))
|
||||
end)
|
||||
it('Does override target if overwrite is true', function()
|
||||
local old = helpers.tmpname()
|
||||
write_file(old, 'Old file')
|
||||
local new = helpers.tmpname()
|
||||
write_file(new, 'New file')
|
||||
exec_lua([[
|
||||
local old = select(1, ...)
|
||||
local new = select(2, ...)
|
||||
|
||||
vim.lsp.util.rename(old, new, { overwrite = true })
|
||||
]], old, new)
|
||||
|
||||
eq(false, exec_lua('return vim.loop.fs_stat(...) ~= nil', old))
|
||||
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', new))
|
||||
eq('Old file\n', read_file(new))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('lsp.util.locations_to_items', function()
|
||||
it('Convert Location[] to items', function()
|
||||
local expected = {
|
||||
|
Loading…
Reference in New Issue
Block a user