From b2bb60d70a449b5ce8041ed27df7c1248fea17d8 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Sat, 18 Jul 2026 06:33:38 -0500 Subject: [PATCH] fix(ui2): avoid ModeChanged in message window #40788 --- runtime/lua/vim/_core/ui2/messages.lua | 5 +++-- test/functional/ui/messages2_spec.lua | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/runtime/lua/vim/_core/ui2/messages.lua b/runtime/lua/vim/_core/ui2/messages.lua index 922c05c44b..92bca8a60c 100644 --- a/runtime/lua/vim/_core/ui2/messages.lua +++ b/runtime/lua/vim/_core/ui2/messages.lua @@ -486,7 +486,8 @@ function M.msg_show(kind, content, replace_last, _, append, id, trigger) M.cmd.ids, M.cmd.prev_msg = {}, '' elseif tgt == 'pager' then -- Position cursor at start of first or last message at bottom of window. - fn.win_execute(ui.wins.pager, 'norm! ' .. (enter_pager and 'gg0' or 'G0zb')) + local lnum = enter_pager and 1 or api.nvim_buf_line_count(ui.bufs.pager) + api.nvim_win_set_cursor(ui.wins.pager, { lnum, 0 }) end end end @@ -718,7 +719,7 @@ function M.set_pos(tgt) M.dialog_on_key = vim.on_key(dialog_on_key, M.dialog_on_key) elseif tgt == 'msg' then -- Ensure last line is visible and first line is at top of window. - fn.win_execute(ui.wins.msg, 'norm! Gzb') + api.nvim_win_set_cursor(ui.wins.msg, { api.nvim_buf_line_count(ui.bufs.msg), 0 }) elseif tgt == 'pager' and not in_pager then enter_pager() end diff --git a/test/functional/ui/messages2_spec.lua b/test/functional/ui/messages2_spec.lua index 30acb62925..fdb996c11c 100644 --- a/test/functional/ui/messages2_spec.lua +++ b/test/functional/ui/messages2_spec.lua @@ -994,6 +994,19 @@ describe('messages2', function() ]]) end) + it('msg window timer does not trigger ModeChanged #40780', function() + exec_lua(function() + require('vim._core.ui2').enable({ msg = { targets = 'msg', msg = { timeout = 50 } } }) + end) + command('let g:modechanged = []') + command([[autocmd ModeChanged i:n call add(g:modechanged, copy(v:event))]]) + command([[echo "a" | echo "b" | startinsert]]) + screen:sleep(100) + t.eq({}, n.eval('g:modechanged')) + feed('') + t.eq({ { old_mode = 'i', new_mode = 'n' } }, n.eval('g:modechanged')) + end) + it('configured targets per kind', function() exec_lua(function() local targets = { echo = 'msg', list_cmd = 'pager', bufwrite = 'cmd', lua_print = 'cmd' }