fix(ui2): don't dismiss expanded messages for non-typed key #39247

Problem:  Invalid check for non-typed key to dismiss expanded cmdline.
          Unable to delay the timer that removes a message from the msg
          window.
Solution: Check for empty string instead of nil to determine whether a
          key is typed.
          Restart the timer if it expires while the user is in the msg
          window. Allow entering the msg window with a mouse click.
(cherry picked from commit faa7c15b5a)
This commit is contained in:
luukvbaal
2026-04-20 17:38:47 +02:00
committed by github-actions[bot]
parent 5ad64af44f
commit c6b5eb30de
3 changed files with 26 additions and 6 deletions
+1 -1
View File
@@ -88,7 +88,7 @@ function M.check_targets()
if not win or not floating then
-- Open a new window when closed or no longer floating (e.g. wincmd J).
local cfg = { col = 0, row = 1, width = 10000, height = 1, mouse = false, noautocmd = true }
local cfg = { col = 0, row = 1, width = 10000, height = 1, noautocmd = true }
cfg.focusable = false
cfg.style = 'minimal'
cfg.relative = 'laststatus'
+11 -5
View File
@@ -55,6 +55,12 @@ function M.msg:start_timer(buf, id)
self.ids[id].timer:stop()
end
self.ids[id].timer = vim.defer_fn(function()
-- Postpone message removal when user has entered the msg window.
if api.nvim_get_current_win() == ui.wins.msg then
M.msg:start_timer(buf, id)
return
end
local extid = api.nvim_buf_is_valid(buf) and self.ids[id] and self.ids[id].extid
local mark = extid and api.nvim_buf_get_extmark_by_id(buf, ui.ns, extid, { details = true })
self.ids[id] = nil
@@ -509,17 +515,17 @@ end
local typed_g = false
local cmd_on_key = function(key, typed)
typed = typed and fn.keytrans(typed)
-- Don't dismiss for non-typed keys and mouse movement. When 'g' is passed (typed
-- or mapped), wait until the next key to avoid flickering when the pager is opened.
if not typed_g and (not typed or typed == '<MouseMove>' or typed == 'g' or key == 'g') then
if not typed_g and (typed == '' or typed == '<MouseMove>' or typed == 'g' or key == 'g') then
typed_g = typed == 'g' or key == 'g'
return
end
vim.on_key(nil, ui.ns)
if typed == ':' then
if typed == ':' or ui.cmd.level > 0 then
return -- Keep expanded messages open until cmdline closes.
end
typed = fn.keytrans(typed)
-- Check if window was entered and reopen with original config.
local mode = not api.nvim_get_mode().mode:match('[it]')
@@ -594,7 +600,7 @@ local function enter_pager()
if was_cmdwin ~= '' then
api.nvim_command('quit')
elseif M.cmd_on_key then
api.nvim_feedkeys(vim.keycode('<Esc>'), 'n', false)
api.nvim_feedkeys(vim.keycode('<Esc>'), 't', false)
end
-- Cmdwin is closed one event iteration later so schedule in case it was open.
vim.schedule(function()
@@ -647,7 +653,7 @@ function M.set_pos(tgt)
cfg = { hide = false, relative = 'laststatus', col = 10000 } ---@type table
cfg.row, cfg.height, cfg.border = win_row_height_border(t, texth.all)
cfg.border = cfg.border and t ~= 'msg' and { '', top, '', '', '', '', '', '' } or nil
cfg.mouse = tgt == 'cmd' or nil
cfg.mouse = tgt == 'cmd' or t == 'msg' or nil
api.nvim_win_set_config(win, cfg)
if tgt == 'cmd' then
+14
View File
@@ -498,6 +498,20 @@ describe('messages2', function()
^typed append |
{9:E35: No previous regular expression} |
]])
-- Non-typed key doesn't dismiss expanded cmdline #39221
command('nnoremap b :ls!<cr>:b<space>')
feed('qb')
screen:expect([[
foo |
{1:~ }|*6
{3: }|
1 %a + "[No Name]" line 1 |
2u a "[Cmd]" line 0 |
3u a "[Dialog]" line 0 |
4u a "[Msg]" line 0 |
5u a "[Pager]" line 0 |
{16::}{15:b} ^ |
]])
end)
it('paging prompt dialog #35191', function()