diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c index 835fdcf7d0..e03cffd1ca 100644 --- a/src/nvim/drawscreen.c +++ b/src/nvim/drawscreen.c @@ -290,9 +290,23 @@ void screen_resize(int width, int height) Rows = height; Columns = width; check_screensize(); - int max_p_ch = Rows - min_rows() + 1; - if (!ui_has(kUIMessages) && p_ch > 0 && p_ch > max_p_ch) { - p_ch = max_p_ch ? max_p_ch : 1; + if (!ui_has(kUIMessages)) { + // clamp 'cmdheight' + int max_p_ch = Rows - min_rows(curtab) + 1; + if (p_ch > 0 && p_ch > max_p_ch) { + p_ch = MAX(max_p_ch, 1); + curtab->tp_ch_used = p_ch; + } + // clamp 'cmdheight' for other tab pages + FOR_ALL_TABS(tp) { + if (tp == curtab) { + continue; // already set above + } + int max_tp_ch = Rows - min_rows(tp) + 1; + if (tp->tp_ch_used > 0 && tp->tp_ch_used > max_tp_ch) { + tp->tp_ch_used = MAX(max_tp_ch, 1); + } + } } height = Rows; width = Columns; diff --git a/src/nvim/option.c b/src/nvim/option.c index 6da9635479..fd0ac375a6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1977,8 +1977,8 @@ static const char *did_set_cmdheight(optset_T *args) { OptInt old_value = args->os_oldval.number; - if (p_ch > Rows - min_rows() + 1) { - p_ch = Rows - min_rows() + 1; + if (p_ch > Rows - min_rows(curtab) + 1) { + p_ch = Rows - min_rows(curtab) + 1; } // if p_ch changed value, change the command line height diff --git a/src/nvim/window.c b/src/nvim/window.c index d92b2ab601..79c3ce9304 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -7065,17 +7065,17 @@ int last_stl_height(bool morewin) } /// Return the minimal number of rows that is needed on the screen to display -/// the current number of windows. -int min_rows(void) +/// the current number of windows for the given tab page. +int min_rows(tabpage_T *tp) FUNC_ATTR_NONNULL_ALL { if (firstwin == NULL) { // not initialized yet return MIN_LINES; } - int total = frame_minheight(curtab->tp_topframe, NULL); + int total = frame_minheight(tp->tp_topframe, NULL); total += tabline_height() + global_stl_height(); - if (p_ch > 0) { - total += 1; // count the room for the command line + if ((tp == curtab ? p_ch : tp->tp_ch_used) > 0) { + total++; // count the room for the command line } return total; } @@ -7091,12 +7091,12 @@ int min_rows_for_all_tabpages(void) int total = 0; FOR_ALL_TABS(tp) { int n = frame_minheight(tp->tp_topframe, NULL); + if ((tp == curtab ? p_ch : tp->tp_ch_used) > 0) { + n++; // count the room for the command line + } total = MAX(total, n); } total += tabline_height() + global_stl_height(); - if (p_ch > 0) { - total += 1; // count the room for the command line - } return total; } diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index f39e9ecc33..666d98c3b2 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -645,6 +645,59 @@ local function screen_tests(linegrid) | ]]) end) + + it('clamps &cmdheight for current tabpage', function() + command('set cmdheight=10 laststatus=2') + screen:expect([[ + ^ | + {0:~ }|*2 + {1:[No Name] }| + |*10 + ]]) + screen:try_resize(53, 8) + screen:expect([[ + ^ | + {1:[No Name] }| + |*6 + ]]) + eq(6, api.nvim_get_option_value('cmdheight', {})) + end) + + it('clamps &cmdheight for another tabpage #31380', function() + command('tabnew') + command('set cmdheight=9 laststatus=2') + screen:expect([[ + {4: [No Name] }{2: [No Name] }{3: }{4:X}| + ^ | + {0:~ }|*2 + {1:[No Name] }| + |*9 + ]]) + command('tabprev') + screen:expect([[ + {2: [No Name] }{4: [No Name] }{3: }{4:X}| + ^ | + {0:~ }|*10 + {1:[No Name] }| + | + ]]) + screen:try_resize(53, 8) + screen:expect([[ + {2: [No Name] }{4: [No Name] }{3: }{4:X}| + ^ | + {0:~ }|*4 + {1:[No Name] }| + | + ]]) + command('tabnext') + screen:expect([[ + {4: [No Name] }{2: [No Name] }{3: }{4:X}| + ^ | + {1:[No Name] }| + |*5 + ]]) + eq(5, api.nvim_get_option_value('cmdheight', {})) + end) end) describe('press enter', function()