From aeebc5185171d29767097d5b6240134bc19cee48 Mon Sep 17 00:00:00 2001 From: CompileAndConquer <69109614+LorenzoPiombini@users.noreply.github.com> Date: Wed, 10 Dec 2025 00:32:51 -0500 Subject: [PATCH] fix(grid): assert crash during extreme resize layouts #36847 Problem: When the terminal shrinks, Neovim tries to recompute the layout and adjust every window so that the total width matches the new Columns. But in the scenario of numerous windows split horizontally, there is not enough space for all of them. The frame width (topframe->fr_width) never reaches the new Columns value, the logic tries to redistribute this negative space across child frames, but it triggers the assert. Solution: Skip this case in `win_update`. --- src/nvim/drawscreen.c | 6 ++++++ test/functional/ui/screen_basic_spec.lua | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 800572ae06..f3919ace58 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -1367,6 +1367,12 @@ static void draw_sep_connectors_win(win_T *wp) /// bot: from bot_start to last row (when scrolled up) static void win_update(win_T *wp) { + // Return early when the windows would overflow the shrunk terminal window + // avoiding invalid drawing an assert failure + if (wp->w_grid.target == &default_grid && wp->w_wincol >= Columns) { + return; + } + int top_end = 0; // Below last row of the top area that needs // updating. 0 when no top area updating. int mid_start = 999; // first row of the mid area that needs diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 295c40b9b6..b105a5296e 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -2,7 +2,7 @@ local t = require('test.testutil') local n = require('test.functional.testnvim')() local Screen = require('test.functional.ui.screen') -local set_session, clear = n.set_session, n.clear +local set_session, clear, assert_alive = n.set_session, n.clear, n.assert_alive local feed, command = n.feed, n.command local exec = n.exec local insert = n.insert @@ -646,6 +646,20 @@ local function screen_tests(linegrid) ]]) end) + it('does not crash when windows fill the screen #33883', function() + screen:try_resize(80, 20) + while true do + local ok = pcall(command, 'wincmd v') + if not ok then + break + end + end + + screen:try_resize(60, 20) + + assert_alive() + end) + it('clamps &cmdheight for current tabpage', function() command('set cmdheight=10 laststatus=2') screen:expect([[