From 4f7879dff0f0dc22ddf4cb2a2095b88605a3bab0 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 14 Mar 2023 13:08:37 +0100 Subject: fix(lsp): kill buffers after renaming a directory #22618 Problem: When LSP client renames a directory, opened buffers in the edfitor are not renamed or closed. Then `:wall` shows errors. https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/util.lua#L776 works correctly if you try to rename a single file, but doesn't delete old buffers with `old_fname` is a dir. Solution: Update the logic in runtime/lua/vim/lsp/util.lua:rename() Fixes #22617 --- runtime/lua/vim/lsp/util.lua | 48 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'runtime/lua/vim') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 82c9e3bc87..48faddfce1 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -743,6 +743,20 @@ local function bufwinid(bufnr) end end +--- Get list of buffers for a directory +---@private +local function get_dir_bufs(path) + path = path:gsub('([^%w])', '%%%1') + local buffers = {} + for _, v in ipairs(vim.api.nvim_list_bufs()) do + local bufname = vim.api.nvim_buf_get_name(v):gsub('buffer://', '') + if bufname:find(path) then + table.insert(buffers, v) + end + end + return buffers +end + --- Rename old_fname to new_fname --- ---@param opts (table) @@ -755,12 +769,22 @@ function M.rename(old_fname, new_fname, opts) vim.notify('Rename target already exists. Skipping rename.') return end - local oldbuf = vim.fn.bufadd(old_fname) - vim.fn.bufload(oldbuf) - -- The there may be pending changes in the buffer - if vim.fn.isdirectory(old_fname) == 0 then - api.nvim_buf_call(oldbuf, function() + local oldbufs = {} + local win = nil + + if vim.fn.isdirectory(old_fname) == 1 then + oldbufs = get_dir_bufs(old_fname) + else + local oldbuf = vim.fn.bufadd(old_fname) + table.insert(oldbufs, oldbuf) + win = bufwinid(oldbuf) + end + + for _, b in ipairs(oldbufs) do + vim.fn.bufload(b) + -- The there may be pending changes in the buffer + api.nvim_buf_call(b, function() vim.cmd('w!') end) end @@ -768,12 +792,16 @@ function M.rename(old_fname, new_fname, opts) local ok, err = os.rename(old_fname, new_fname) assert(ok, err) - local newbuf = vim.fn.bufadd(new_fname) - local win = bufwinid(oldbuf) - if win then - api.nvim_win_set_buf(win, newbuf) + if vim.fn.isdirectory(new_fname) == 0 then + local newbuf = vim.fn.bufadd(new_fname) + if win then + api.nvim_win_set_buf(win, newbuf) + end + end + + for _, b in ipairs(oldbufs) do + api.nvim_buf_delete(b, {}) end - api.nvim_buf_delete(oldbuf, { force = true }) end ---@private -- cgit