Commit: patch 9.2.0968: status line height is wrong after exchanging or rotating windows
Christian Brabandt <[email protected]>
| Newsgroups | gmane.editors.vim.devel |
|---|---|
| Message-ID | <[email protected]> |
patch 9.2.0968: status line height is wrong after exchanging or rotating windows Commit: https://github.com/vim/vim/commit/21e9249838018d5c06973ca17d0b51697b997d33 Author: Hirohito Higashi <[email protected]> Date: Tue Aug 18 17:52:21 2026 +0000 patch 9.2.0968: status line height is wrong after exchanging or rotating windows Problem: Exchanging windows with CTRL-W x or rotating them with CTRL-W r leaves a window with the status line height of the other one, so with 'statuslineopt' the windows in a row no longer line up. Solution: Keep the total height of each window when the status line height is exchanged, and compute the height needed for the status line of each window afterwards. closes: #21079 Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Signed-off-by: Hirohito Higashi <[email protected]> Signed-off-by: Christian Brabandt <[email protected]> diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim index ad182fcf3..0010bb182 100644 --- a/src/testdir/test_statusline.vim +++ b/src/testdir/test_statusline.vim @@ -894,6 +894,131 @@ func Test_statusline_click_multiple_regions() let &laststatus = save_ls endfunc +func StlExchangeEnter() + let &l:statusline = 'one%@two%@three' +endfunc + +func StlExchangeLeave() + setlocal statusline< +endfunc + +" Rows used by the status line of window "nr", derived from where the window +" ends on the screen. +func s:StlHeight(nr) + return &lines - &cmdheight - win_screenpos(a:nr)[0] - winheight(a:nr) + 1 +endfunc + +" Exchanging two windows keeps the status line height with the window. +func Test_statuslineopt_win_exchange() + let save_stlo = &statuslineopt + let save_stl = &statusline + let save_ls = &laststatus + set laststatus=2 + set statusline=global + set statuslineopt=maxheight:3 + + augroup TestStlExchange + autocmd! + autocmd WinEnter * call StlExchangeEnter() + autocmd WinLeave * call StlExchangeLeave() + augroup END + + new + only + call StlExchangeEnter() + vsplit + redraw + + " The current window needs three rows for its status line, the other one. + call assert_equal(1, winnr()) + call assert_equal(3, s:StlHeight(1)) + call assert_equal(1, s:StlHeight(2)) + + " Exchanging puts the cursor in the other window, which then is the one + " needing three rows. + wincmd x + redraw + call assert_equal(1, winnr()) + call assert_equal(3, s:StlHeight(1)) + call assert_equal(1, s:StlHeight(2)) + + augroup TestStlExchange + autocmd! + augroup END + augroup! TestStlExchange + delfunc StlExchangeEnter + delfunc StlExchangeLeave + only + bwipe! + let &laststatus = save_ls + let &statusline = save_stl + let &statuslineopt = save_stlo +endfunc + +" Exchanging two windows keeps a fixed status line height with the window. +func Test_statuslineopt_fixed_win_exchange() + let save_stlo = &statuslineopt + let save_ls = &laststatus + set laststatus=2 + + new + only + vsplit + setlocal statuslineopt=fixedheight,maxheight:3 + redraw + + " Only the current window has a local 'statuslineopt'. + call assert_equal(1, winnr()) + call assert_equal(3, s:StlHeight(1)) + call assert_equal(1, s:StlHeight(2)) + + " The window that was exchanged keeps needing three rows. + wincmd x + redraw + call assert_equal(1, winnr()) + call assert_equal(1, s:StlHeight(1)) + call assert_equal(3, s:StlHeight(2)) + + only + bwipe! + let &laststatus = save_ls + let &statuslineopt = save_stlo +endfunc + +" Rotating windows keeps a fixed status line height with the window. +func Test_statuslineopt_fixed_win_rotate() + let save_stlo = &statuslineopt + let save_ls = &laststatus + set laststatus=2 + + new + only + vsplit + setlocal statuslineopt=fixedheight,maxheight:3 + redraw + + call assert_equal(1, winnr()) + call assert_equal(3, s:StlHeight(1)) + call assert_equal(1, s:StlHeight(2)) + + " Rotating moves the window that needs three rows to the other position. + wincmd r + redraw + call assert_equal(1, s:StlHeight(1)) + call assert_equal(3, s:StlHeight(2)) + + " Rotating back restores it. + wincmd r + redraw + call assert_equal(3, s:StlHeight(1)) + call assert_equal(1, s:StlHeight(2)) + + only + bwipe! + let &laststatus = save_ls + let &statuslineopt = save_stlo +endfunc + " Click on a region in any row of a multi-line statusline (issue #20116). func Test_statusline_click_multiline() let save_mouse = &mouse diff --git a/src/version.c b/src/version.c index 047699420..0115e9423 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 968, /**/ 967, /**/ diff --git a/src/window.c b/src/window.c index 4d4cfab44..b2ed04e4d 100644 --- a/src/window.c +++ b/src/window.c @@ -1905,7 +1905,14 @@ win_exchange(long Prenum) else frame_append(frp2, wp->w_frame); } + // Keep the total height of each window the same, so that the frames keep + // their height; the status line height is computed below. temp = curwin->w_status_height; + if (temp != wp->w_status_height) + { + win_new_height(curwin, curwin->w_height + temp - wp->w_status_height); + win_new_height(wp, wp->w_height + wp->w_status_height - temp); + } curwin->w_status_height = wp->w_status_height; wp->w_status_height = temp; temp = curwin->w_vsep_width; @@ -1918,6 +1925,9 @@ win_exchange(long Prenum) frame_fix_width(wp); win_comp_pos(); // recompute window positions +#if defined(FEAT_STL_OPT) + frame_change_statusline_height(); +#endif if (wp->w_buffer != curbuf) reset_VIsual_and_resel(); @@ -1993,7 +2003,14 @@ win_rotate(int upwards, int count) } // exchange status height and vsep width of old and new last window + // Keep the total height of each window the same, so that the frames + // keep their height; the status line height is computed below. n = wp2->w_status_height; + if (n != wp1->w_status_height) + { + win_new_height(wp2, wp2->w_height + n - wp1->w_status_height); + win_new_height(wp1, wp1->w_height + wp1->w_status_height - n); + } wp2->w_status_height = wp1->w_status_height; wp1->w_status_height = n; frame_fix_height(wp1); @@ -2007,6 +2024,9 @@ win_rotate(int upwards, int count) // recompute w_winrow and w_wincol for all windows win_comp_pos(); } +#if defined(FEAT_STL_OPT) + frame_change_statusline_height(); +#endif redraw_all_later(UPD_NOT_VALID); } -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1wwOL3-00AXTN-5W%40256bit.org.