commit 8c7bbfba3d025954c4a74d53766392cd89202497
parent f807e5c9175b2a453aa64aea1b2d00a887d011df
Author: luukvbaal <luukvbaal@gmail.com>
Date: Mon, 2 Feb 2026 16:54:26 +0100
fix(ui2): callbacks reference stale message-window handles #37673
Problem: Scheduled callbacks reference potentially outdated window
handles e.g. after switching tabpage.
Solution: Use ext.wins which stores the updated window handles.
Diffstat:
2 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/runtime/lua/vim/_extui/messages.lua b/runtime/lua/vim/_extui/messages.lua
@@ -496,10 +496,10 @@ function M.set_pos(type)
return
end
vim.schedule(function()
- local entered = api.nvim_get_current_win() == win
+ local entered = api.nvim_get_current_win() == ext.wins.cmd
cmd_on_key = nil
- if api.nvim_win_is_valid(win) then
- api.nvim_win_close(win, true)
+ if api.nvim_win_is_valid(ext.wins.cmd) then
+ api.nvim_win_close(ext.wins.cmd, true)
end
ext.check_targets()
-- Show or clear the message depending on if the pager was opened.
@@ -566,15 +566,15 @@ function M.set_pos(type)
-- Cmdwin is actually closed one event iteration later so schedule in case it was open.
vim.schedule(function()
- api.nvim_set_current_win(win)
+ api.nvim_set_current_win(ext.wins.pager)
-- Make pager relative to cmdwin when it is opened, restore when it is closed.
api.nvim_create_autocmd({ 'WinEnter', 'CmdwinEnter', 'CmdwinLeave' }, {
callback = function(ev)
- if api.nvim_win_is_valid(win) then
+ if api.nvim_win_is_valid(ext.wins.pager) then
local cfg = ev.event == 'CmdwinLeave' and config
or ev.event == 'WinEnter' and { hide = true }
or { relative = 'win', win = 0, row = 0, col = 0 }
- api.nvim_win_set_config(win, cfg)
+ api.nvim_win_set_config(ext.wins.pager, cfg)
end
return ev.event == 'WinEnter'
end,
diff --git a/test/functional/ui/messages2_spec.lua b/test/functional/ui/messages2_spec.lua
@@ -102,11 +102,28 @@ describe('messages2', function()
{1:~ }|*12
^R 1,1 All|
]])
- feed('-')
+ feed('-<Esc>')
screen:expect([[
- x^ |
+ ^x |
{1:~ }|*12
- 1,2 All|
+ 1,1 All|
+ ]])
+ -- Switching tabpage closes expanded cmdline #37659.
+ command('tabnew | echo "foo\nbar"')
+ screen:expect([[
+ {24: + [No Name] }{5: }{100:2}{5: [No Name] }{2: }{24:X}|
+ ^ |
+ {1:~ }|*9
+ {3: }|
+ foo |
+ bar |
+ ]])
+ feed('gt')
+ screen:expect([[
+ {5: + [No Name] }{24: [No Name] }{2: }{24:X}|
+ ^x |
+ {1:~ }|*11
+ foo [+1] 1,1 All|
]])
end)