Skip to content

Commit

Permalink
fix(lsp): kill buffers after renaming a directory
Browse files Browse the repository at this point in the history
  • Loading branch information
ivaaaan committed Mar 12, 2023
1 parent 29a43ef commit 2b20c70
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
48 changes: 38 additions & 10 deletions runtime/lua/vim/lsp/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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:https://', '')
if bufname:find(path) then
table.insert(buffers, v)
end
end
return buffers
end

--- Rename old_fname to new_fname
---
---@param opts (table)
Expand All @@ -755,25 +769,39 @@ 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

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
Expand Down
28 changes: 23 additions & 5 deletions test/functional/plugin/lsp_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2196,7 +2196,22 @@ describe('LSP', function()
eq(true, exists)
os.remove(new)
end)
it('Can rename a direcory', function()
it("Kills old buffer after renaming 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 oldbufnr = vim.fn.bufadd(old)
local new = select(2, ...)
vim.lsp.util.rename(old, new)
return vim.fn.bufloaded(oldbufnr)
]], old, new)
eq(0, lines)
os.remove(new)
end)
it('Can rename a directory', function()
-- only reserve the name, file must not exist for the test scenario
local old_dir = helpers.tmpname()
local new_dir = helpers.tmpname()
Expand All @@ -2205,16 +2220,19 @@ describe('LSP', function()

helpers.mkdir_p(old_dir)

local file = "file"
local file = 'file.txt'
write_file(old_dir .. pathsep .. file, 'Test content')

exec_lua([[
local lines = exec_lua([[
local old_dir = select(1, ...)
local new_dir = select(2, ...)
local pathsep = select(3, ...)
local oldbufnr = vim.fn.bufadd(old_dir .. pathsep .. 'file')
vim.lsp.util.rename(old_dir, new_dir)
]], old_dir, new_dir)

return vim.fn.bufloaded(oldbufnr)
]], old_dir, new_dir, pathsep)
eq(0, lines)
eq(false, exec_lua('return vim.loop.fs_stat(...) ~= nil', old_dir))
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', new_dir))
eq(true, exec_lua('return vim.loop.fs_stat(...) ~= nil', new_dir .. pathsep .. file))
Expand Down

0 comments on commit 2b20c70

Please sign in to comment.