neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 5871d267790987548d06e02afdd166e9e9c459e3
parent 6b6a4518c28c8d6e6b2f4cd4c33683c72f17411c
Author: luukvbaal <luukvbaal@gmail.com>
Date:   Tue, 24 Jun 2025 10:25:46 +0200

fix(autocmd): 'cmdheight' OptionSet with valid window grids (#34619)

Problem:  OptionSet autocmd emitted with invalid grids after entering
          tabpage with different 'cmdheight'.
Solution: First call `tabpage_check_windows()` before changing 'cmdheight'.
          Add a test that exercises the `vim._extui` cmdline.
Diffstat:
Msrc/nvim/window.c | 19+++++++++----------
Atest/functional/ui/cmdline2_spec.lua | 46++++++++++++++++++++++++++++++++++++++++++++++
Mtest/functional/ui/messages2_spec.lua | 2++
3 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/src/nvim/window.c b/src/nvim/window.c @@ -4441,18 +4441,17 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a use_tabpage(tp); - if (p_ch != curtab->tp_ch_used) { - // Use the stored value of p_ch, so that it can be different for each tab page. - // Handle other side-effects but avoid setting frame sizes, which are still correct. - OptInt new_ch = curtab->tp_ch_used; - curtab->tp_ch_used = p_ch; - command_frame_height = false; - set_option_value(kOptCmdheight, NUMBER_OPTVAL(new_ch), 0); - command_frame_height = true; - } - if (old_curtab != curtab) { tabpage_check_windows(old_curtab); + if (p_ch != curtab->tp_ch_used) { + // Use the stored value of p_ch, so that it can be different for each tab page. + // Handle other side-effects but avoid setting frame sizes, which are still correct. + OptInt new_ch = curtab->tp_ch_used; + curtab->tp_ch_used = p_ch; + command_frame_height = false; + set_option_value(kOptCmdheight, NUMBER_OPTVAL(new_ch), 0); + command_frame_height = true; + } } // We would like doing the TabEnter event first, but we don't have a diff --git a/test/functional/ui/cmdline2_spec.lua b/test/functional/ui/cmdline2_spec.lua @@ -0,0 +1,46 @@ +-- Tests for (protocol-driven) ui2, intended to replace the legacy message grid UI. + +local n = require('test.functional.testnvim')() +local Screen = require('test.functional.ui.screen') + +local clear, exec, exec_lua, feed = n.clear, n.exec, n.exec_lua, n.feed + +describe('cmdline2', function() + local screen + before_each(function() + clear() + screen = Screen.new() + screen:add_extra_attr_ids({ + [100] = { foreground = Screen.colors.Magenta1, bold = true }, + }) + exec_lua(function() + require('vim._extui').enable({}) + end) + end) + + it("no crash for invalid grid after 'cmdheight' OptionSet", function() + exec('tabnew | tabprev') + feed(':set ch=0') + screen:expect([[ + {5: }{100:2}{5: [No Name] }{24: [No Name] }{2: }{24:X}| + | + {1:~ }|*11 + {16::}{15:set} {16:ch}{15:=}0^ | + ]]) + feed('<CR>') + exec('tabnext') + screen:expect([[ + {24: [No Name] }{5: }{100:2}{5: [No Name] }{2: }{24:X}| + ^ | + {1:~ }|*11 + {16::}{15:set} {16:ch}{15:=}0 | + ]]) + exec('tabnext') + screen:expect([[ + {5: }{100:2}{5: [No Name] }{24: [No Name] }{2: }{24:X}| + ^ | + {1:~ }|*12 + ]]) + n.assert_alive() + end) +end) diff --git a/test/functional/ui/messages2_spec.lua b/test/functional/ui/messages2_spec.lua @@ -1,3 +1,5 @@ +-- Tests for (protocol-driven) ui2, intended to replace the legacy message grid UI. + local n = require('test.functional.testnvim')() local Screen = require('test.functional.ui.screen')