fix: remove winfixheight from dapui panes, let user resize freely
winfixheight was locking Breakpoints, Console, Scopes, etc. to their configured heights, fighting any attempt to manually resize. That's hostile to user agency — someone with many breakpoints wants a taller Breakpoints pane; someone tailing log output wants a taller Console. pin_dapui_sizes still runs ONCE per M.enter to set the initial proportions (25% each sidebar pane, 8-or-20% Console). After that, user is free to drag splits, :resize, etc. and those sticks. Removed the WinResized handler entirely (it was the aggressive re-pinner that made user resizes bounce back). The VimResized handler stays but only recreates bars that got killed by shrink; it no longer re-pins dapui sizes. Trade-off: tiny-equalizer-style `wincmd =` plugins will now successfully equalize during debug mode, but since we've already told the user to disable that plugin, it's acceptable. Bar windows themselves (status + legend) KEEP winfixheight because they're chrome, not data — users shouldn't be resizing a status bar, and locking them down prevents accidental drift. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 file changed
+15
-41
+15
-41
@@ -522,12 +522,12 @@ local function open_bars()
|
|||||||
render_bars()
|
render_bars()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Pin dapui pane heights. Console gets its configured size. Sidebar
|
-- Set dapui pane heights to their initial proportions. Called ONCE
|
||||||
-- panes get explicit equal distribution with any rounding remainder
|
-- per M.enter, after dapui.open(). No winfixheight — the user is free
|
||||||
-- going to the LAST pane (Breakpoints) so it's never smaller than its
|
-- to manually resize panes (bigger Breakpoints list, taller Console to
|
||||||
-- neighbors. winfixheight locks each pane against future rearrangements.
|
-- tail long output, etc.) and their resize sticks because we don't
|
||||||
|
-- fight subsequent WinResized events. Initial sizing only.
|
||||||
local function pin_dapui_sizes()
|
local function pin_dapui_sizes()
|
||||||
-- gather one window per dapui pane filetype
|
|
||||||
local pane_wins = {}
|
local pane_wins = {}
|
||||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
if vim.api.nvim_buf_is_valid(buf) then
|
if vim.api.nvim_buf_is_valid(buf) then
|
||||||
@@ -542,16 +542,14 @@ local function pin_dapui_sizes()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Console
|
-- Console to configured height
|
||||||
if pane_wins.dapui_console then
|
if pane_wins.dapui_console then
|
||||||
local target = config.opts.console_height
|
local target = config.opts.console_height
|
||||||
or math.max(8, math.floor(vim.o.lines * 0.2))
|
or math.max(8, math.floor(vim.o.lines * 0.2))
|
||||||
pcall(vim.api.nvim_win_set_height, pane_wins.dapui_console, target)
|
pcall(vim.api.nvim_win_set_height, pane_wins.dapui_console, target)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sidebar: explicit equal distribution. Compute total current height
|
-- Sidebar panes distributed equally (residual to Breakpoints)
|
||||||
-- of the four sidebar panes and divide evenly, handing any remainder
|
|
||||||
-- to Breakpoints (last pane) so it's never smaller than the others.
|
|
||||||
local order = { "dapui_stacks", "dapui_scopes", "dapui_watches", "dapui_breakpoints" }
|
local order = { "dapui_stacks", "dapui_scopes", "dapui_watches", "dapui_breakpoints" }
|
||||||
local present = {}
|
local present = {}
|
||||||
local total = 0
|
local total = 0
|
||||||
@@ -570,11 +568,6 @@ local function pin_dapui_sizes()
|
|||||||
pcall(vim.api.nvim_win_set_height, w, h)
|
pcall(vim.api.nvim_win_set_height, w, h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- winfixheight on everything
|
|
||||||
for _, w in pairs(pane_wins) do
|
|
||||||
pcall(function() vim.wo[w].winfixheight = true end)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function close_bars()
|
local function close_bars()
|
||||||
@@ -589,11 +582,11 @@ local function close_bars()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function reposition_bars()
|
local function reposition_bars()
|
||||||
-- Splits auto-track VimResized via winfixheight; re-render the bar
|
-- Just re-render bar content. We intentionally DON'T re-pin dapui
|
||||||
-- content and re-pin dapui sizes so plugins like focus.nvim that
|
-- sizes here — the user may have manually resized panes, and
|
||||||
-- auto-resize on focus change can't permanently skew the layout.
|
-- fighting their resize on every event is a worse UX than occasional
|
||||||
|
-- layout drift.
|
||||||
render_bars()
|
render_bars()
|
||||||
pin_dapui_sizes()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ─── dap-ui setup ────────────────────────────────────────────────────────────
|
-- ─── dap-ui setup ────────────────────────────────────────────────────────────
|
||||||
@@ -1085,44 +1078,25 @@ function M.enter()
|
|||||||
if active then M._install_for_buf(args.buf) end
|
if active then M._install_for_buf(args.buf) end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
-- On editor resize:
|
-- On editor resize: if a bar got killed by shrink-below-minimum,
|
||||||
-- 1) if any bar got killed by a shrink-below-minimum, recreate it
|
-- recreate it. Do NOT re-pin dapui sizes — whatever the user
|
||||||
-- 2) re-pin dapui pane sizes (defensive against any plugin — our
|
-- (or nvim's shrink/expand redistribution) arrived at is respected.
|
||||||
-- own, another's, or nvim's own shrink-recovery — that might
|
|
||||||
-- have skewed the layout).
|
|
||||||
-- Deferred via vim.schedule so we run AFTER other plugins' handlers.
|
|
||||||
vim.api.nvim_create_autocmd("VimResized", {
|
vim.api.nvim_create_autocmd("VimResized", {
|
||||||
group = group,
|
group = group,
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
if not active then return end
|
if not active then return end
|
||||||
-- recreate missing bars
|
|
||||||
if not (sbar_win and vim.api.nvim_win_is_valid(sbar_win)) then
|
if not (sbar_win and vim.api.nvim_win_is_valid(sbar_win)) then
|
||||||
sbar_win, sbar_buf = nil, nil
|
sbar_win, sbar_buf = nil, nil
|
||||||
end
|
end
|
||||||
if not (cbar_win and vim.api.nvim_win_is_valid(cbar_win)) then
|
if not (cbar_win and vim.api.nvim_win_is_valid(cbar_win)) then
|
||||||
cbar_win, cbar_buf = nil, nil
|
cbar_win, cbar_buf = nil, nil
|
||||||
end
|
end
|
||||||
open_bars() -- idempotent; only creates what's missing
|
open_bars() -- idempotent; only creates what's missing
|
||||||
pin_dapui_sizes()
|
|
||||||
render_bars()
|
render_bars()
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
-- WinResized catches mouse-drag resizes and plugin-driven wincmd=
|
|
||||||
-- that don't fire VimResized. Guarded against self-recursion.
|
|
||||||
vim.api.nvim_create_autocmd("WinResized", {
|
|
||||||
group = group,
|
|
||||||
callback = function()
|
|
||||||
if M._pinning then return end
|
|
||||||
vim.schedule(function()
|
|
||||||
if not active then return end
|
|
||||||
M._pinning = true
|
|
||||||
pin_dapui_sizes()
|
|
||||||
M._pinning = false
|
|
||||||
end)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
if vim.api.nvim_buf_is_loaded(buf) then M._install_for_buf(buf) end
|
if vim.api.nvim_buf_is_loaded(buf) then M._install_for_buf(buf) end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in new issue
Block a user