mirror of
https://github.com/vim/vim.git
synced 2025-08-26 20:03:41 -04:00
patch 9.1.1571: CmdlineChanged triggered to often
Problem: The CmdlineChanged event was firing unnecessarily, even when the command line's content hadn't actually changed. Solution: I've added a check to compare the command-line buffer's state before and after key processing. The `CmdlineChanged` event now only triggers if the buffer's contents are genuinely different (Girish Palya). closes: #17803 Signed-off-by: Girish Palya <girishji@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
1afe8c3a4d
commit
239c4e4abe
@ -1633,7 +1633,6 @@ getcmdline_int(
|
||||
int res;
|
||||
int save_msg_scroll = msg_scroll;
|
||||
int save_State = State; // remember State when called
|
||||
int prev_cmdpos = -1;
|
||||
int some_key_typed = FALSE; // one of the keys was typed
|
||||
// mouse drag and release events are ignored, unless they are
|
||||
// preceded with a mouse down event
|
||||
@ -1649,6 +1648,7 @@ getcmdline_int(
|
||||
int cmdline_type;
|
||||
int wild_type = 0;
|
||||
int event_cmdlineleavepre_triggered = FALSE;
|
||||
char_u *prev_cmdbuff = NULL;
|
||||
|
||||
// one recursion level deeper
|
||||
++depth;
|
||||
@ -1820,6 +1820,7 @@ getcmdline_int(
|
||||
{
|
||||
int trigger_cmdlinechanged = TRUE;
|
||||
int end_wildmenu;
|
||||
int prev_cmdpos = ccline.cmdpos;
|
||||
|
||||
redir_off = TRUE; // Don't redirect the typed command.
|
||||
// Repeated, because a ":redir" inside
|
||||
@ -1836,6 +1837,13 @@ getcmdline_int(
|
||||
// Trigger SafeState if nothing is pending.
|
||||
may_trigger_safestate(xpc.xp_numfiles <= 0);
|
||||
|
||||
if (ccline.cmdbuff != NULL)
|
||||
{
|
||||
prev_cmdbuff = vim_strnsave(ccline.cmdbuff, ccline.cmdpos);
|
||||
if (prev_cmdbuff == NULL)
|
||||
goto returncmd;
|
||||
}
|
||||
|
||||
// Get a character. Ignore K_IGNORE and K_NOP, they should not do
|
||||
// anything, such as stop completion.
|
||||
do
|
||||
@ -2566,7 +2574,10 @@ cmdline_not_changed:
|
||||
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
if (!is_state.incsearch_postponed)
|
||||
{
|
||||
VIM_CLEAR(prev_cmdbuff);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
cmdline_changed:
|
||||
@ -2578,15 +2589,17 @@ cmdline_changed:
|
||||
may_do_incsearch_highlighting(firstc, count, &is_state);
|
||||
#endif
|
||||
// Trigger CmdlineChanged autocommands.
|
||||
if (trigger_cmdlinechanged)
|
||||
if (trigger_cmdlinechanged
|
||||
&& (ccline.cmdpos != prev_cmdpos
|
||||
|| (prev_cmdbuff != NULL && STRNCMP(prev_cmdbuff,
|
||||
ccline.cmdbuff, prev_cmdpos) != 0)))
|
||||
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
|
||||
|
||||
VIM_CLEAR(prev_cmdbuff);
|
||||
|
||||
// Trigger CursorMovedC autocommands.
|
||||
if (ccline.cmdpos != prev_cmdpos)
|
||||
{
|
||||
trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC);
|
||||
prev_cmdpos = ccline.cmdpos;
|
||||
}
|
||||
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
if (cmdmsg_rl
|
||||
@ -2695,6 +2708,8 @@ theend:
|
||||
restore_cmdline(&save_ccline);
|
||||
else
|
||||
ccline.cmdbuff = NULL;
|
||||
|
||||
vim_free(prev_cmdbuff);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
@ -4691,4 +4691,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
|
||||
|
@ -719,6 +719,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1571,
|
||||
/**/
|
||||
1570,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user