From d30d91f3a49e19e61473b74e42adf68e9215220d Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Tue, 27 Jan 2026 00:18:51 +0100 Subject: fix(ui): only internal messages are unsafe #37462 Problem: Fast context for msg_show event inhibits vim.ui_attach from displaying a stream of messages from a single command. Solution: Remove fast context from msg_show events emitted as a result of explicit API/command calls. The fast context was originally introduced to prevent issues with internal messages. --- runtime/lua/vim/_extui.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/_extui.lua') diff --git a/runtime/lua/vim/_extui.lua b/runtime/lua/vim/_extui.lua index f9da5629d5..4d72325dd5 100644 --- a/runtime/lua/vim/_extui.lua +++ b/runtime/lua/vim/_extui.lua @@ -38,17 +38,19 @@ ext.msg = require('vim._extui.messages') ext.cmd = require('vim._extui.cmdline') local M = {} -local function ui_callback(event, ...) +local function ui_callback(redraw_msg, event, ...) local handler = ext.msg[event] or ext.cmd[event] ext.check_targets() handler(...) - -- Cmdline mode and non-empty showcmd requires an immediate redraw. - if ext.cmd[event] or event == 'msg_showcmd' and select(1, ...)[1] then + -- Cmdline mode, non-fast message and non-empty showcmd require an immediate redraw. + if ext.cmd[event] or redraw_msg or (event == 'msg_showcmd' and select(1, ...)[1]) then + ext.redrawing = true api.nvim__redraw({ flush = handler ~= ext.cmd.cmdline_hide or nil, cursor = handler == ext.cmd[event] and true or nil, win = handler == ext.cmd[event] and ext.wins.cmd or nil, }) + ext.redrawing = false end end local scheduled_ui_callback = vim.schedule_wrap(ui_callback) @@ -86,10 +88,11 @@ function M.enable(opts) if not (ext.msg[event] or ext.cmd[event]) then return end - if vim.in_fast_event() then - scheduled_ui_callback(event, ...) + -- Ensure cmdline is placed after a scheduled message in block mode. + if vim.in_fast_event() or (event == 'cmdline_show' and ext.cmd.srow > 0) then + scheduled_ui_callback(false, event, ...) else - ui_callback(event, ...) + ui_callback(event == 'msg_show', event, ...) end return true end) -- cgit