fix(win): better handling of alien buffers opening in managed windows. See #886

This commit is contained in:
Folke Lemaitre 2025-02-03 10:41:14 +01:00
parent 604c603dfa
commit c8430fdd8d
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
4 changed files with 31 additions and 16 deletions

View file

@ -102,14 +102,13 @@ function M.new(opts)
self.box_wins[box.id] = Snacks.win(Snacks.win.resolve(box, {
relative = is_root and (box.relative or "editor") or "win",
focusable = false,
fixbuf = false,
enter = false,
show = false,
resize = false,
noautocmd = true,
backdrop = backdrop,
zindex = (self.opts.layout.zindex or 50) + box.depth,
bo = { filetype = "snacks_layout_box" },
bo = { filetype = "snacks_layout_box", buftype = "nofile" },
w = { snacks_layout = true },
border = box.border,
}))

View file

@ -47,7 +47,6 @@ function M.new(opts, main)
enter = false,
width = 0,
height = 0,
fixbuf = false,
on_win = function()
self.item = nil
self:reset()
@ -185,12 +184,17 @@ function M:clear(buf)
vim.api.nvim_buf_clear_namespace(buf, ns_loc, 0, -1)
end
---@param buf number
function M:set_buf(buf)
self.win:set_buf(buf)
end
function M:reset()
if not self.win:valid() then
return
end
if self.win.scratch_buf and vim.api.nvim_buf_is_valid(self.win.scratch_buf) then
vim.api.nvim_win_set_buf(self.win.win, self.win.scratch_buf)
self.win:set_buf(self.win.scratch_buf)
else
self.win:scratch()
end
@ -217,7 +221,7 @@ function M:scratch()
vim.o.eventignore = "all"
vim.bo[buf].filetype = "snacks_picker_preview"
vim.o.eventignore = ei
vim.api.nvim_win_set_buf(self.win.win, buf)
self.win:set_buf(buf)
self.win:map()
self:wo({ number = false, relativenumber = false, signcolumn = "no" })
return buf

View file

@ -74,7 +74,7 @@ function M.file(ctx)
local name = vim.api.nvim_buf_get_name(ctx.item.buf)
name = uv.fs_stat(name) and vim.fn.fnamemodify(name, ":t") or name
ctx.preview:set_title(name)
vim.api.nvim_win_set_buf(ctx.win, ctx.item.buf)
ctx.preview:set_buf(ctx.item.buf)
else
local path = Snacks.picker.util.path(ctx.item)
if not path then

View file

@ -821,23 +821,28 @@ function M:show()
-- find another window to swap with
local main ---@type number?
for _, win in ipairs(vim.api.nvim_list_wins()) do
local is_float = vim.api.nvim_win_get_config(win).relative ~= ""
if not is_float then
main = win
if win ~= self.win and vim.bo[vim.api.nvim_win_get_buf(win)].buftype == "" then
local win_buf = vim.api.nvim_win_get_buf(win)
local is_float = vim.api.nvim_win_get_config(win).zindex ~= nil
if win ~= self.win and not is_float then
if vim.bo[win_buf].buftype == "" then
main = win
break
end
end
end
if main then
vim.api.nvim_win_set_buf(self.win, self.buf)
vim.api.nvim_win_set_buf(main, buf)
vim.api.nvim_set_current_win(main)
vim.cmd.stopinsert()
else
-- no main window found, so close this window
vim.api.nvim_win_set_buf(self.win, self.buf)
vim.schedule(function()
if not self:valid() then
return
end
vim.api.nvim_win_set_buf(self.win, self.buf)
vim.api.nvim_win_set_buf(main, buf)
vim.api.nvim_set_current_win(main)
vim.cmd.stopinsert()
vim.cmd("sbuffer " .. buf)
vim.api.nvim_win_close(self.win, true)
end)
end
end,
@ -849,6 +854,13 @@ function M:show()
return self
end
---@param buf number
function M:set_buf(buf)
assert(self:valid(), "Window is not valid")
self.buf = buf
vim.api.nvim_win_set_buf(self.win, buf)
end
function M:map()
if not self:buf_valid() then
return