From c6c348471d0ee4b87188c62bb7cc918d84dbd654 Mon Sep 17 00:00:00 2001 From: luukvbaal Date: Mon, 6 Apr 2026 19:15:46 +0200 Subject: [PATCH] fix(cmdline): 'inccommand' preview after setcmdline() #38795 Problem: 'inccommand' preview is not executed after setcmdline(), and as a result cmdline_show event is emitted when redrawing is not allowed (5b6477be). Solution: Call command_line_changed() when ccline.cmdbuff_replaced is set (by setcmdline()). (cherry picked from commit 135478702985f470a3d503f197a7f57c17d962a3) --- src/nvim/ex_getln.c | 9 +++++++-- test/functional/ui/cmdline2_spec.lua | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 05d424ceb2..5a355ffe1c 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1324,6 +1324,10 @@ static int command_line_execute(VimState *state, int key) if (display_tick > display_tick_saved && s->is_state.did_incsearch) { may_do_incsearch_highlighting(s->firstc, s->count, &s->is_state); } + // If f_setcmdline() changed the cmdline treat it as such. + if (ccline.cmdbuff_replaced) { + command_line_changed(s); + } // nvim_select_popupmenu_item() can be called from the handling of // K_EVENT, K_COMMAND, or K_LUA. @@ -2893,8 +2897,9 @@ static int command_line_changed(CommandLineState *s) } } - if (ccline.cmdpos != s->prev_cmdpos - || (s->prev_cmdbuff != NULL && strcmp(s->prev_cmdbuff, ccline.cmdbuff) != 0)) { + if (!ccline.cmdbuff_replaced + && (ccline.cmdpos != s->prev_cmdpos + || (s->prev_cmdbuff != NULL && strcmp(s->prev_cmdbuff, ccline.cmdbuff) != 0))) { // Trigger CmdlineChanged autocommands. do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); } diff --git a/test/functional/ui/cmdline2_spec.lua b/test/functional/ui/cmdline2_spec.lua index 402700c88d..00d56fd504 100644 --- a/test/functional/ui/cmdline2_spec.lua +++ b/test/functional/ui/cmdline2_spec.lua @@ -237,6 +237,32 @@ describe('cmdline2', function() {16::}{15:call} {25:Foo}{16:()}^ | ]]) end) + + it('updated after setcmdline() #38764', function() + -- Also check that command-preview is updated. + exec('call setline(1, "foo")') + feed(':%s/foo') + screen:expect([[ + {10:foo} | + {1:~ }|*12 + {16::}%{15:s}{16:/foo^ } | + ]]) + exec_lua(function() + _G.events = {} + vim.api.nvim_create_autocmd({ 'CmdlineChanged', 'CursorMovedC' }, { + callback = function(ev) + _G.events[ev.event] = (_G.events[ev.event] or 0) + 1 + end, + }) + end) + exec('call setcmdline("%s/fo")') + screen:expect([[ + {10:fo}o | + {1:~ }|*12 + {16::}%{15:s}{16:/fo^ } | + ]]) + t.eq({ CmdlineChanged = 1, CursorMovedC = 1 }, exec_lua('return _G.events')) + end) end) describe('cmdline2', function()