mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
fix(lsp): ensure buffers are re-attached on rename (#16266)
If a LSP server sent a workspace edit containing a rename the buffers file name changed without the server receiving a close notification for the old buffer and without the client properly re-attaching on the new file. This affected `Move` code-actions in nvim-jdtls, but also `vim.lsp.buf.rename` on a class level.
This commit is contained in:
parent
2ef9d2a663
commit
ee3a58d42e
@ -472,7 +472,11 @@ local function text_document_did_open_handler(bufnr, client)
|
|||||||
|
|
||||||
-- Next chance we get, we should re-do the diagnostics
|
-- Next chance we get, we should re-do the diagnostics
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
vim.lsp.diagnostic.redraw(bufnr, client.id)
|
-- Protect against a race where the buffer disappears
|
||||||
|
-- between `did_open_handler` and the scheduled function firing.
|
||||||
|
if vim.api.nvim_buf_is_valid(bufnr) then
|
||||||
|
vim.lsp.diagnostic.redraw(bufnr, client.id)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -549,18 +549,29 @@ end
|
|||||||
-- ignoreIfExists? bool
|
-- ignoreIfExists? bool
|
||||||
function M.rename(old_fname, new_fname, opts)
|
function M.rename(old_fname, new_fname, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local bufnr = vim.fn.bufadd(old_fname)
|
|
||||||
vim.fn.bufload(bufnr)
|
|
||||||
local target_exists = vim.loop.fs_stat(new_fname) ~= nil
|
local target_exists = vim.loop.fs_stat(new_fname) ~= nil
|
||||||
if target_exists and not opts.overwrite or opts.ignoreIfExists then
|
if target_exists and not opts.overwrite or opts.ignoreIfExists then
|
||||||
vim.notify('Rename target already exists. Skipping rename.')
|
vim.notify('Rename target already exists. Skipping rename.')
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local oldbuf = vim.fn.bufadd(old_fname)
|
||||||
|
vim.fn.bufload(oldbuf)
|
||||||
|
|
||||||
|
-- The there may be pending changes in the buffer
|
||||||
|
api.nvim_buf_call(oldbuf, function()
|
||||||
|
vim.cmd('w!')
|
||||||
|
end)
|
||||||
|
|
||||||
local ok, err = os.rename(old_fname, new_fname)
|
local ok, err = os.rename(old_fname, new_fname)
|
||||||
assert(ok, err)
|
assert(ok, err)
|
||||||
api.nvim_buf_call(bufnr, function()
|
|
||||||
vim.cmd('saveas! ' .. vim.fn.fnameescape(new_fname))
|
local newbuf = vim.fn.bufadd(new_fname)
|
||||||
end)
|
for _, win in pairs(api.nvim_list_wins()) do
|
||||||
|
if api.nvim_win_get_buf(win) == oldbuf then
|
||||||
|
api.nvim_win_set_buf(win, newbuf)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
api.nvim_buf_delete(oldbuf, { force = true })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -1735,6 +1735,7 @@ describe('LSP', function()
|
|||||||
|
|
||||||
-- after rename the target file must have the contents of the source file
|
-- after rename the target file must have the contents of the source file
|
||||||
local bufnr = vim.fn.bufadd(new)
|
local bufnr = vim.fn.bufadd(new)
|
||||||
|
vim.fn.bufload(new)
|
||||||
return vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
return vim.api.nvim_buf_get_lines(bufnr, 0, -1, true)
|
||||||
]], old, new)
|
]], old, new)
|
||||||
eq({'Test content'}, lines)
|
eq({'Test content'}, lines)
|
||||||
|
Loading…
Reference in New Issue
Block a user