fix: renaming buffers doesn't interfere with directory hijack (#25)

This commit is contained in:
Steven Arcangeli 2023-01-10 22:08:59 -08:00
parent 80f64dd630
commit b4ccc16944
3 changed files with 45 additions and 15 deletions

View file

@ -556,7 +556,11 @@ M.setup = function(opts)
loading.set_loading(bufnr, true)
local function finish(new_url)
if new_url ~= params.file then
util.rename_buffer(bufnr, new_url)
if util.rename_buffer(bufnr, new_url) then
-- If the buffer was replaced then don't initialize it. It's dead. The replacement will
-- have BufReadCmd called for it
return
end
end
vim.cmd.doautocmd({ args = { "BufReadPre", params.file }, mods = { emsg_silent = true } })
view.initialize(bufnr)

View file

@ -87,12 +87,13 @@ end
---@param src_bufnr integer|string Buffer number or name
---@param dest_buf_name string
---@return boolean True if the buffer was replaced instead of renamed
M.rename_buffer = function(src_bufnr, dest_buf_name)
if type(src_bufnr) == "string" then
src_bufnr = vim.fn.bufadd(src_bufnr)
if not vim.api.nvim_buf_is_loaded(src_bufnr) then
vim.api.nvim_buf_delete(src_bufnr, {})
return
return false
end
end
@ -107,7 +108,7 @@ M.rename_buffer = function(src_bufnr, dest_buf_name)
if ok then
-- Renaming the buffer creates a new buffer with the old name. Find it and delete it.
vim.api.nvim_buf_delete(vim.fn.bufadd(bufname), {})
return
return false
end
end
@ -116,20 +117,25 @@ M.rename_buffer = function(src_bufnr, dest_buf_name)
if vim.bo[src_bufnr].buflisted then
vim.bo[dest_bufnr].buflisted = true
end
-- Find any windows with the old buffer and replace them
for _, winid in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_is_valid(winid) then
if vim.api.nvim_win_get_buf(winid) == src_bufnr then
vim.api.nvim_win_set_buf(winid, dest_bufnr)
-- If we're renaming a buffer that we're about to enter, this may be called before the buffer is
-- actually in the window. We need to wait to enter the buffer and _then_ replace it.
vim.schedule(function()
-- Find any windows with the old buffer and replace them
for _, winid in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_is_valid(winid) then
if vim.api.nvim_win_get_buf(winid) == src_bufnr then
vim.api.nvim_win_set_buf(winid, dest_bufnr)
end
end
end
end
if vim.bo[src_bufnr].modified then
local src_lines = vim.api.nvim_buf_get_lines(src_bufnr, 0, -1, true)
vim.api.nvim_buf_set_lines(dest_bufnr, 0, -1, true, src_lines)
end
-- Try to delete, but don't if the buffer has changes
pcall(vim.api.nvim_buf_delete, src_bufnr, {})
if vim.bo[src_bufnr].modified then
local src_lines = vim.api.nvim_buf_get_lines(src_bufnr, 0, -1, true)
vim.api.nvim_buf_set_lines(dest_bufnr, 0, -1, true, src_lines)
end
-- Try to delete, but don't if the buffer has changes
pcall(vim.api.nvim_buf_delete, src_bufnr, {})
end)
return true
end
---@param count integer

20
tests/regression_spec.lua Normal file
View file

@ -0,0 +1,20 @@
require("plenary.async").tests.add_to_env()
local test_util = require("tests.test_util")
a.describe("regression tests", function()
after_each(function()
test_util.reset_editor()
end)
-- see https://github.com/stevearc/oil.nvim/issues/25
a.it("can edit dirs that will be renamed to an existing buffer", function()
vim.cmd.edit({ args = { "README.md" } })
vim.cmd.vsplit()
vim.cmd.edit({ args = { "%:p:h" } })
assert.equals("oil", vim.bo.filetype)
vim.cmd.wincmd({ args = { "p" } })
assert.equals("markdown", vim.bo.filetype)
vim.cmd.edit({ args = { "%:p:h" } })
a.util.sleep(10)
assert.equals("oil", vim.bo.filetype)
end)
end)