fix(ui2): update spill indicator when appending to expanded cmdline #38715

Problem:  When messages are appended to an already expanded cmdline,
          the spilled lines indicator is not updated.
Solution: Remove early return for updating virtual text while cmdline is
          expanded, guard updating "msg" virt_text at callsite instead.
(cherry picked from commit 2663f51890)
This commit is contained in:
luukvbaal
2026-04-05 15:48:38 +02:00
committed by github-actions[bot]
parent 38b5cfc74a
commit bac7c3a996
2 changed files with 20 additions and 26 deletions

View File

@@ -86,12 +86,7 @@ end
---@param type 'last'|'msg'|'top'|'bot'
---@param tgt? 'cmd'|'msg'|'dialog'
local function set_virttext(type, tgt)
if
-- Cannot show with 0 'cmdheight' and delay for error.
(type == 'last' and (ui.cmdheight == 0 or M.virt.delayed))
-- Do not overwrite temporary spill indicator during expanded cmdline.
or (M.cmd_on_key and type == 'msg')
then
if type == 'last' and (ui.cmdheight == 0 or M.virt.delayed) then
return -- Don't show virtual text while cmdline is expanded or delaying for error.
end
@@ -184,7 +179,11 @@ local function set_virttext(type, tgt)
pad = pad - ((mode > 0 or col == 0) and 0 or math.min(M.cmd.last_col, scol))
end
table.insert(chunks, mode + 1, { (' '):rep(pad) })
set_virttext('msg') -- Readjust to new M.cmd.last_col or clear for mode.
-- Readjust to new M.cmd.last_col or clear for mode, but don't overwrite
-- locked spill indicator while cmdline is expanded for messages.
if not M.cmd_on_key then
set_virttext('msg')
end
end
local opts = { undo_restore = false, invalidate = true, id = M.virt.ids[type] }
@@ -321,6 +320,13 @@ function M.show_msg(tgt, kind, content, replace_last, append, id)
local opts = { end_row = row, end_col = col, invalidate = true, undo_restore = false }
M[tgt].ids[id] = M[tgt].ids[id] or {}
M[tgt].ids[id].extid = api.nvim_buf_set_extmark(buf, ui.ns, start_row, start_col, opts)
M.prev_id, M.prev_msg, M.dupe = id, msg, dupe
if tgt == 'cmd' or row == api.nvim_buf_line_count(buf) - 1 then
-- Place (x) indicator for repeated messages. Mainly to mitigate unnecessary
-- resizing of the message window, but also placed in the cmdline.
M.virt.msg[M.virt.idx.dupe][1] = dupe > 0 and { 0, ('(%d)'):format(dupe) } or nil
set_virttext('msg')
end
end
if tgt == 'msg' then
@@ -359,14 +365,6 @@ function M.show_msg(tgt, kind, content, replace_last, append, id)
M.set_pos(tgt)
end
if M[tgt] and (tgt == 'cmd' or row == api.nvim_buf_line_count(buf) - 1) then
-- Place (x) indicator for repeated messages. Mainly to mitigate unnecessary
-- resizing of the message window, but also placed in the cmdline.
M.virt.msg[M.virt.idx.dupe][1] = dupe > 0 and { 0, ('(%d)'):format(dupe) } or nil
M.prev_id, M.prev_msg, M.dupe = id, msg, dupe
set_virttext('msg')
end
-- Reset message state the next event loop iteration.
if not cmd_timer and (col > 0 or next(M.cmd.ids) ~= nil) then
cmd_timer = vim.defer_fn(function()
@@ -663,13 +661,12 @@ function M.set_pos(tgt)
or nil
api.nvim_win_set_config(win, cfg)
if tgt == 'cmd' and not M.cmd_on_key then
-- Temporarily expand the cmdline, until next key press.
local save_spill = M.virt.msg[M.virt.idx.spill][1]
if tgt == 'cmd' then
-- Dismiss temporarily expanded cmdline on next keypress and update spill indicator.
local spill = texth.all > cfg.height and (' [+%d]'):format(texth.all - cfg.height)
M.virt.msg[M.virt.idx.spill][1] = spill and { 0, spill } or nil
set_virttext('msg', 'cmd')
M.virt.msg[M.virt.idx.spill][1] = save_spill
M.virt.msg[M.virt.idx.spill][1] = { 0, (' [+%d]'):format(texth.all - ui.cmdheight) }
M.cmd_on_key = vim.on_key(cmd_on_key, ui.ns)
elseif tgt == 'dialog' and set_top_bot_spill() and #cfg.title[1][1] > 0 then
M.dialog_on_key = vim.on_key(dialog_on_key, M.dialog_on_key)

View File

@@ -80,11 +80,7 @@ describe('messages2', function()
]])
-- Any key press resizes the cmdline and updates the spill indicator.
feed('j')
screen:expect([[
^ |
{1:~ }|*12
foo [+29] |
]])
screen:expect({ any = { '+29' } })
command('echo "foo"')
-- New message clears spill indicator.
screen:expect([[
@@ -174,13 +170,14 @@ describe('messages2', function()
foo [+14] 2,1 All|
]])
feed('<BS><Esc>')
command('call nvim_echo([["foo\n"]]->repeat(&lines), 1, {})')
-- First multiline message expands cmdline, additional message updates spill indicator.
command('call nvim_echo([["foo\n"]]->repeat(&lines), 1, {}) | echo "bar"')
screen:expect([[
^x |
{1:~ }|*5
{3: }|
foo |*6
foo [+8] |
foo [+9] |
]])
-- Do enter the pager in normal mode.
feed('<CR>')