]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0789: 'statuslineopt' status line too high after a window is minimized v9.2.0789
authorHirohito Higashi <h.east.727@gmail.com>
Sat, 18 Jul 2026 09:46:33 +0000 (09:46 +0000)
committerChristian Brabandt <cb@256bit.org>
Sat, 18 Jul 2026 09:46:33 +0000 (09:46 +0000)
Problem:  With a global 'statuslineopt' maxheight, the status line height is
          not reduced to what every window can afford.  After a window is put
          at its minimum height (e.g. CTRL-W_), setting 'statuslineopt' still
          gives a status line taller than the small window can display,
          instead of the best-effort height that fits all windows.
Solution: Let every window using the global 'statuslineopt' constrain the
          best-effort height, including windows at their minimum height.
          Correct a misleading test comment and add a test (Hirohito Higashi).

closes: #20772

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/dumps/Test_statuslineopt_wincmd_underscore_besteff_01.dump [new file with mode: 0644]
src/testdir/test_statuslineopt.vim
src/version.c
src/window.c

diff --git a/src/testdir/dumps/Test_statuslineopt_wincmd_underscore_besteff_01.dump b/src/testdir/dumps/Test_statuslineopt_wincmd_underscore_besteff_01.dump
new file mode 100644 (file)
index 0000000..47fd4e2
--- /dev/null
@@ -0,0 +1,14 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|~| @73
+|G+3#0000000&|A| @72
+| +0&&@74
+|G+1&&|A| @72
+| +0&&@74
index 653529e3566451a7c462c6a2b0251da9b548ed5f..c5519aa8b8c374de45615d300d6111a39966758d 100644 (file)
@@ -391,8 +391,8 @@ func Test_statuslineopt_wincmd_underscore()
   CheckScreendump
 
   " Test CTRL-W__ with global stlo maxheight:3 and multi-line statusline.
-  " After maximizing, the large window should keep stlh=3, not collapse to 1
-  " because the minimized other window constrained global_stlh.
+  " The height is computed when 'stlo' is set (a single window here, so 3).
+  " Splitting and maximizing do not recompute it, so both status lines stay 3.
   let lines =<< trim END
     set laststatus=2
     set statuslineopt=maxheight:3
@@ -408,6 +408,27 @@ func Test_statuslineopt_wincmd_underscore()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_statuslineopt_wincmd_underscore_besteff()
+  CheckScreendump
+
+  " Best effort when global 'stlo' is set after CTRL-W__ has minimized the
+  " other window.  That window only fits a 1-row status line, so the global
+  " height is reduced to 1 even though maxheight is 3.
+  let lines =<< trim END
+    set laststatus=2
+    set statusline=GA%@GB%@GC
+    new
+    wincmd _
+  END
+  call writefile(lines, 'XTest_statuslineopt_wincmd_underscore_besteff', 'D')
+
+  let buf = g:RunVimInTerminal('-S XTest_statuslineopt_wincmd_underscore_besteff', {'rows': 14})
+  call term_sendkeys(buf, ":set statuslineopt=maxheight:3\<CR>\<C-L>")
+  call VerifyScreenDump(buf, 'Test_statuslineopt_wincmd_underscore_besteff_01', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 def Test_statuslineopt_besteff_order()
   # Test the best-effort option update: keyword order is preserved and
   # duplicate maxheight: removed.
index 93e38b8a007b4f654ddc5e44a7c296b8c93386fc..86904555a277727dd6fbf47a51f196bfeb42b0a2 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    789,
 /**/
     788,
 /**/
index 89c890f0f4a04b9c68cb58689fce9f0edf75a00e..3933f4e88430bc3a217d5310426a28fb9b9d2815 100644 (file)
@@ -7830,10 +7830,9 @@ frame_find_global_stlh_rec(frame_T *frp, int h)
        win_T  *wp = frp->fr_win;
 
        // Only consider windows with a status line that use global stlo.
-       // Exclude windows at minimum height (w_height <= p_wmh): they can
-       // only afford 1 status line row anyway, and should not constrain
-       // the global stlh for larger windows (e.g. after CTRL-W__).
-       if (wp->w_height > p_wmh && wp->w_status_height > 0
+       // Every such window constrains the global height (best effort): the
+       // result is the largest height that still fits every window.
+       if (wp->w_height > 0 && wp->w_status_height > 0
                && *wp->w_p_stlo == NUL)
        {
            int win_free_height = frp->fr_height - WINBAR_HEIGHT(wp);