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, { self.box_wins[box.id] = Snacks.win(Snacks.win.resolve(box, {
relative = is_root and (box.relative or "editor") or "win", relative = is_root and (box.relative or "editor") or "win",
focusable = false, focusable = false,
fixbuf = false,
enter = false, enter = false,
show = false, show = false,
resize = false, resize = false,
noautocmd = true, noautocmd = true,
backdrop = backdrop, backdrop = backdrop,
zindex = (self.opts.layout.zindex or 50) + box.depth, 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 }, w = { snacks_layout = true },
border = box.border, border = box.border,
})) }))

View file

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

View file

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

View file

@ -821,23 +821,28 @@ function M:show()
-- find another window to swap with -- find another window to swap with
local main ---@type number? local main ---@type number?
for _, win in ipairs(vim.api.nvim_list_wins()) do for _, win in ipairs(vim.api.nvim_list_wins()) do
local is_float = vim.api.nvim_win_get_config(win).relative ~= "" local win_buf = vim.api.nvim_win_get_buf(win)
if not is_float then local is_float = vim.api.nvim_win_get_config(win).zindex ~= nil
main = win if win ~= self.win and not is_float then
if win ~= self.win and vim.bo[vim.api.nvim_win_get_buf(win)].buftype == "" then if vim.bo[win_buf].buftype == "" then
main = win
break break
end end
end end
end end
if main then 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() 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.stopinsert()
vim.cmd("sbuffer " .. buf)
vim.api.nvim_win_close(self.win, true)
end) end)
end end
end, end,
@ -849,6 +854,13 @@ function M:show()
return self return self
end 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() function M:map()
if not self:buf_valid() then if not self:buf_valid() then
return return