Merge pull request #35015 from zeertzjq/vim-9.1.1571

vim-patch:9.1.{1571,1573}: CmdlineChanged triggered to often
This commit is contained in:
zeertzjq
2025-07-21 07:53:54 +08:00
committed by GitHub
2 changed files with 65 additions and 3 deletions

View File

@@ -134,6 +134,7 @@ typedef struct {
int save_msg_scroll;
int save_State; // remember State when called
int prev_cmdpos;
char *prev_cmdbuff;
char *save_p_icm;
bool some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
@@ -1013,6 +1014,7 @@ theend:
ccline.cmdbuff = NULL;
}
xfree(s->prev_cmdbuff);
return (uint8_t *)p;
}
@@ -1020,6 +1022,9 @@ static int command_line_check(VimState *state)
{
CommandLineState *s = (CommandLineState *)state;
s->prev_cmdpos = ccline.cmdpos;
XFREE_CLEAR(s->prev_cmdbuff);
redir_off = true; // Don't redirect the typed command.
// Repeated, because a ":redir" inside
// completion may switch it on.
@@ -1029,6 +1034,10 @@ static int command_line_check(VimState *state)
// that occurs while typing a command should
// cause the command not to be executed.
if (ccline.cmdbuff != NULL) {
s->prev_cmdbuff = xmemdupz(ccline.cmdbuff, (size_t)ccline.cmdpos);
}
// Trigger SafeState if nothing is pending.
may_trigger_safestate(s->xpc.xp_numfiles <= 0);
@@ -2288,7 +2297,6 @@ static void may_trigger_cursormovedc(CommandLineState *s)
{
if (ccline.cmdpos != s->prev_cmdpos) {
trigger_cmd_autocmd(s->cmdline_type, EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos;
ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos);
}
}
@@ -2296,6 +2304,7 @@ static void may_trigger_cursormovedc(CommandLineState *s)
static int command_line_not_changed(CommandLineState *s)
{
may_trigger_cursormovedc(s);
s->prev_cmdpos = ccline.cmdpos;
// Incremental searches for "/" and "?":
// Enter command_line_not_changed() when a character has been read but the
// command line did not change. Then we only search and redraw if something
@@ -2772,8 +2781,12 @@ static void do_autocmd_cmdlinechanged(int firstc)
static int command_line_changed(CommandLineState *s)
{
// Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
if (ccline.cmdpos != s->prev_cmdpos
|| (s->prev_cmdbuff != NULL
&& strncmp(s->prev_cmdbuff, ccline.cmdbuff, (size_t)s->prev_cmdpos) != 0)) {
// Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
}
may_trigger_cursormovedc(s);

View File

@@ -4719,4 +4719,53 @@ func Test_pum_scroll_noselect()
call StopVimInTerminal(buf)
endfunc
" CmdlineChanged shouldn't trigger if command-line text is unchanged
func Test_cmdline_changed()
let g:cmdchg_count = 0
let g:cmdprefix = ''
augroup test_CmdlineAugrp | autocmd!
autocmd CmdlineChanged * if getcmdline() =~ g:cmdprefix | let g:cmdchg_count += 1 | endif
augroup END
new
set wildmenu
set wildmode=full
let g:cmdprefix = 'echomsg'
let g:cmdchg_count = 0
call feedkeys(":echomsg\<Tab>", "tx")
call assert_equal(1, g:cmdchg_count) " once only for 'g', not again for <Tab>
let g:cmdchg_count = 0
let g:cmdprefix = 'echo'
call feedkeys(":ech\<Tab>", "tx")
call assert_equal(1, g:cmdchg_count) " (once for 'h' and) once for 'o'
set wildmode=noselect,full
let g:cmdchg_count = 0
let g:cmdprefix = 'ech'
call feedkeys(":ech\<Tab>", "tx")
call assert_equal(1, g:cmdchg_count) " once for 'h', not again for <tab>
command! -nargs=+ -complete=custom,TestComplete Test echo
func TestComplete(arglead, cmdline, cursorpos)
return "AbC"
endfunc
set wildoptions=fuzzy wildmode=full
let g:cmdchg_count = 0
let g:cmdprefix = 'Test \(AbC\|abc\)'
call feedkeys(":Test abc\<Tab>", "tx")
call assert_equal(2, g:cmdchg_count) " once for 'c', again for 'AbC'
bw!
set wildmode& wildmenu& wildoptions&
augroup test_CmdlineAugrp | autocmd! | augroup END
unlet g:cmdchg_count
unlet g:cmdprefix
delfunc TestComplete
delcommand Test
endfunc
" vim: shiftwidth=2 sts=2 expandtab