Skip to content

Commit cc7306e

Browse files
authored
fix: open integration when the window is small (#25)
1 parent d00b2cf commit cc7306e

3 files changed

Lines changed: 83 additions & 28 deletions

File tree

‎lua/zen/init.lua‎

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -281,22 +281,30 @@ local function reposition_stack(position)
281281
heights[win] = vim.api.nvim_win_get_height(win)
282282
end
283283

284-
if position == "top" then
285-
vim.api.nvim_win_set_config(windows[1], { split = "above", win = -1 })
286-
for i = 2, #windows do
287-
vim.api.nvim_win_set_config(windows[i], { split = "below", win = windows[i - 1] })
288-
end
289-
else
290-
vim.api.nvim_win_set_config(windows[#windows], { split = "below", win = -1 })
291-
for i = #windows - 1, 1, -1 do
292-
vim.api.nvim_win_set_config(windows[i], { split = "above", win = windows[i + 1] })
284+
-- Some Neovim versions raise `E242: Can't split a window while closing
285+
-- another` when this runs from a handler that fires midway through a window
286+
-- close (e.g. `WinClosed` recreating a side buffer, whose `BufWinEnter`
287+
-- reaches here before the original close has unwound). Guard the splits so
288+
-- that refusal cannot abort the surrounding close handler; the reposition is
289+
-- re-run by that handler once the offending close has settled.
290+
pcall(function()
291+
if position == "top" then
292+
vim.api.nvim_win_set_config(windows[1], { split = "above", win = -1 })
293+
for i = 2, #windows do
294+
vim.api.nvim_win_set_config(windows[i], { split = "below", win = windows[i - 1] })
295+
end
296+
else
297+
vim.api.nvim_win_set_config(windows[#windows], { split = "below", win = -1 })
298+
for i = #windows - 1, 1, -1 do
299+
vim.api.nvim_win_set_config(windows[i], { split = "above", win = windows[i + 1] })
300+
end
293301
end
294-
end
295302

296-
for _, win in ipairs(windows) do
297-
vim.api.nvim_win_set_height(win, heights[win])
298-
vim.api.nvim_win_set_width(win, vim.o.columns)
299-
end
303+
for _, win in ipairs(windows) do
304+
vim.api.nvim_win_set_height(win, heights[win])
305+
vim.api.nvim_win_set_width(win, vim.o.columns)
306+
end
307+
end)
300308
end
301309

302310
---@param position "top" | "bottom"
@@ -369,6 +377,9 @@ local function setup(options)
369377
vim.api.nvim_create_autocmd("CursorMoved", {
370378
-- TODO: use pattern for better perf
371379
callback = function(args)
380+
if vim.o.columns <= get_main_width() then
381+
return
382+
end
372383
if is_buff_integration(args.buf) then
373384
local buf_info = vim.fn.getbufinfo(args.buf)
374385

‎tests/scripts/init_with_zen_small.lua‎

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,8 @@ require("trouble").setup({ open_no_results = true })
99
require("fyler").setup({})
1010
require("neotest").setup({ adapters = {} })
1111
require("zen").setup({
12-
top = {
13-
{ filetype = "fugitive" },
14-
},
15-
bottom = {
16-
{ filetype = "trouble" },
17-
},
18-
left = {
19-
{ filetype = "*", min_width = 46 },
20-
{ filetype = "fyler_finder" },
21-
},
22-
right = {
23-
{ filetype = "*", min_width = 46 },
24-
{ filetype = "neotest-summary" },
25-
},
12+
top = { { filetype = "fugitive" } },
13+
bottom = { { filetype = "trouble" } },
14+
left = { { filetype = "fyler_finder" } },
15+
right = { { filetype = "neotest-summary" } },
2616
})

‎tests/test_integrations.lua‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ T["left integration"]["opening an integration should close the existing integrat
6161
})
6262
end
6363

64+
T["left integration"]["opening an integration on a small window"] = function()
65+
child.restart({ "-u", "tests/scripts/init_with_zen_small.lua" })
66+
67+
child.cmd("Fyler kind=split_left_most")
68+
69+
Helpers.expect.layout(child, {
70+
type = "row",
71+
children = {
72+
{ type = "leaf", filetype = "fyler_finder", buftype = "acwrite", width = 35, height = 50 },
73+
{ type = "leaf", filetype = "", buftype = "", width = 104, height = 50 },
74+
},
75+
})
76+
end
77+
6478
T["top integration"] = MiniTest.new_set({})
6579

6680
T["top integration"]["opening"] = function()
@@ -202,6 +216,46 @@ for _, case in ipairs({ { name = "above", }, { name = "below", } }) do
202216
end
203217
end
204218

219+
T["top integration"]["closing a git commit keeps the top and bottom stacks intact"] = function()
220+
-- Regression: creating a commit in fugitive and then closing the gitcommit
221+
-- window used to abort the reposition handlers with `E242: Can't split a
222+
-- window while closing another`, because recreating a side buffer on
223+
-- `WinClosed` re-enters `reposition_stack` mid-close. The close must leave
224+
-- the fugitive (top) and trouble (bottom) stacks intact instead.
225+
child.lua([[
226+
local tmpdir = vim.fn.tempname()
227+
vim.fn.mkdir(tmpdir, "p")
228+
vim.fn.system({ "git", "init", tmpdir })
229+
vim.fn.system({ "git", "-C", tmpdir, "config", "user.name", "Test" })
230+
vim.fn.system({ "git", "-C", tmpdir, "config", "user.email", "test@test.com" })
231+
vim.fn.system({ "git", "-C", tmpdir, "commit", "--allow-empty", "-m", "initial" })
232+
vim.fn.writefile({ "hello" }, tmpdir .. "/file")
233+
vim.cmd("edit " .. tmpdir .. "/file")
234+
]])
235+
236+
child.cmd("Git")
237+
child.cmd("Trouble diagnostics")
238+
child.cmd("wincmd t")
239+
child.cmd("Git commit --allow-empty")
240+
child.cmd("q")
241+
242+
Helpers.expect.layout(child, {
243+
type = "col",
244+
children = {
245+
{ type = "leaf", filetype = "fugitive", buftype = "nowrite", width = 240, height = 25 },
246+
{
247+
type = "row",
248+
children = {
249+
{ type = "leaf", filetype = "zen-left", buftype = "nofile", width = 46, height = 13 },
250+
{ type = "leaf", filetype = "", buftype = "", width = 146, height = 13 },
251+
{ type = "leaf", filetype = "zen-right", buftype = "nofile", width = 46, height = 13 },
252+
},
253+
},
254+
{ type = "leaf", filetype = "trouble", buftype = "nofile", width = 240, height = 10 },
255+
},
256+
})
257+
end
258+
205259
T["bottom integration"] = MiniTest.new_set({})
206260

207261
T["bottom integration"]["opening"] = function()

0 commit comments

Comments
 (0)