diff --git a/src/testdir/dumps/Test_laststatus_vsplit_row_height2_1.dump b/src/testdir/dumps/Test_laststatus_vsplit_row_height2_1.dump new file mode 100644 index 0000000000..12701b1ec4 --- /dev/null +++ b/src/testdir/dumps/Test_laststatus_vsplit_row_height2_1.dump @@ -0,0 +1,8 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@36||+1&&| +0&&@36 +|[+1&&|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1| |~+0#4040ff13&| @35 +| +1#0000000&@37|[|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_laststatus_vsplit_row_height3_1.dump b/src/testdir/dumps/Test_laststatus_vsplit_row_height3_1.dump new file mode 100644 index 0000000000..6d24637e32 --- /dev/null +++ b/src/testdir/dumps/Test_laststatus_vsplit_row_height3_1.dump @@ -0,0 +1,8 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@36||+1&&| +0&&@36 +|~+0#4040ff13&| @35||+1#0000000&|[|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1 +|[|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1| @37 +| +0&&@74 diff --git a/src/testdir/dumps/Test_laststatus_vsplit_row_height_1.dump b/src/testdir/dumps/Test_laststatus_vsplit_row_height_1.dump new file mode 100644 index 0000000000..86db528f77 --- /dev/null +++ b/src/testdir/dumps/Test_laststatus_vsplit_row_height_1.dump @@ -0,0 +1,8 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@36||+1&&| +0&&@36 +|[+1&&|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1| |[|N|o| |N|a|m|e|]| @9|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim index 1832a9790d..6ead70a1a7 100644 --- a/src/testdir/test_window_cmd.vim +++ b/src/testdir/test_window_cmd.vim @@ -2377,8 +2377,9 @@ endfunc " When shrinking a window and the only other window has 'winfixheight' " with 'winminheight'=0, freed rows must go to the wfh window. func Test_winfixheight_resize_wmh_zero() - set winminheight=0 laststatus=0 + CheckFeature quickfix + set winminheight=0 laststatus=0 let id1 = win_getid() copen let id2 = win_getid() @@ -2438,4 +2439,61 @@ func Test_winfixheight_resize_wmh_zero() set winminheight& laststatus& endfunc +" Test that setting 'laststatus' from 0 to 2 gives all windows in a vertical +" split (FR_ROW) the same height and correct status line position. +func Test_laststatus_vsplit_row_height() + CheckScreendump + + let lines =<< trim END + set ls=0 + vsplit + topleft new + wincmd _ + set ls=2 + END + call writefile(lines, 'XTestLaststatusVsplitRowHeight', 'D') + let buf = RunVimInTerminal('-S XTestLaststatusVsplitRowHeight', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_laststatus_vsplit_row_height_1', {}) + call StopVimInTerminal(buf) +endfunc + +" Test that when FR_ROW windows have different status line heights (due to +" window-local 'statuslineopt'), content heights compensate so that total +" rows are equal across the row. +func Test_laststatus_vsplit_row_height_mixed_stlo() + CheckScreendump + + let lines =<< trim END + set ls=0 + setlocal stlo=fixedheight,maxheight:2 + rightbelow vnew + topleft new + wincmd _ + set ls=2 + END + call writefile(lines, 'XTestLaststatusVsplitRowHeight2', 'D') + let buf = RunVimInTerminal('-S XTestLaststatusVsplitRowHeight2', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_laststatus_vsplit_row_height2_1', {}) + call StopVimInTerminal(buf) +endfunc + +" Same as above but with the stlo window on the right (second leaf in FR_ROW). +func Test_laststatus_vsplit_row_height_mixed_stlo_reversed() + CheckScreendump + + let lines =<< trim END + set ls=0 + leftabove vnew + wincmd p + setlocal stlo=fixedheight,maxheight:2 + topleft new + wincmd _ + set ls=2 + END + call writefile(lines, 'XTestLaststatusVsplitRowHeight3', 'D') + let buf = RunVimInTerminal('-S XTestLaststatusVsplitRowHeight3', #{rows: 8}) + call VerifyScreenDump(buf, 'Test_laststatus_vsplit_row_height3_1', {}) + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index d7c480a67c..c480833be6 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 190, /**/ 189, /**/ diff --git a/src/window.c b/src/window.c index 4b6626cc31..390c084fa6 100644 --- a/src/window.c +++ b/src/window.c @@ -7654,8 +7654,78 @@ last_status_rec(frame_T *fr, int statusline) else if (fr->fr_layout == FR_ROW) { // vertically split windows, set status line for each one - FOR_ALL_FRAMES(fp, fr->fr_child) - last_status_rec(fp, statusline); + if (!statusline) + { + FOR_ALL_FRAMES(fp, fr->fr_child) + last_status_rec(fp, statusline); + } + else + { + frame_T *fp2; + int max_stlh = 0; + int new_row_height; + + // Find the max status height needed across all leaf windows. + FOR_ALL_FRAMES(fp, fr->fr_child) + if (fp->fr_win != NULL && fp->fr_win->w_status_height == 0) + { + int h = statusline_height(fp->fr_win); + if (h > max_stlh) + max_stlh = h; + } + if (max_stlh == 0) + return; + + // Find a frame to take max_stlh lines from. + fp2 = fr; + while (fp2->fr_height - frame_minheight(fp2, NULL) < max_stlh) + { + if (fp2 == topframe) + { + emsg(_(e_not_enough_room)); + return; + } + if (fp2->fr_parent->fr_layout == FR_COL + && fp2->fr_prev != NULL) + fp2 = fp2->fr_prev; + else + fp2 = fp2->fr_parent; + } + + if (fp2 != fr) + { + frame_new_height(fp2, fp2->fr_height - max_stlh, + FALSE, FALSE, FALSE); + new_row_height = fr->fr_height + max_stlh; + } + else + new_row_height = fr->fr_height; + + // Set status and content heights for all leaves. + FOR_ALL_FRAMES(fp, fr->fr_child) + { + if (fp->fr_win != NULL) + { + wp = fp->fr_win; + if (wp->w_status_height == 0) + { + wp->w_status_height = statusline_height(wp); + win_new_height(wp, + new_row_height - wp->w_status_height); + frame_fix_height(wp); + comp_col(); + redraw_all_later(UPD_SOME_VALID); + if (abs(wp->w_height - wp->w_prev_height) == 1) + wp->w_prev_height = wp->w_height; + } + } + else + last_status_rec(fp, statusline); // nested frames + } + + fr->fr_height = new_row_height; + win_comp_pos(); + } } else {