mirror of
https://github.com/vim/vim.git
synced 2025-08-27 20:13:38 -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 res;
|
||||||
int save_msg_scroll = msg_scroll;
|
int save_msg_scroll = msg_scroll;
|
||||||
int save_State = State; // remember State when called
|
int save_State = State; // remember State when called
|
||||||
int prev_cmdpos = -1;
|
|
||||||
int some_key_typed = FALSE; // one of the keys was typed
|
int some_key_typed = FALSE; // one of the keys was typed
|
||||||
// mouse drag and release events are ignored, unless they are
|
// mouse drag and release events are ignored, unless they are
|
||||||
// preceded with a mouse down event
|
// preceded with a mouse down event
|
||||||
@ -1649,6 +1648,7 @@ getcmdline_int(
|
|||||||
int cmdline_type;
|
int cmdline_type;
|
||||||
int wild_type = 0;
|
int wild_type = 0;
|
||||||
int event_cmdlineleavepre_triggered = FALSE;
|
int event_cmdlineleavepre_triggered = FALSE;
|
||||||
|
char_u *prev_cmdbuff = NULL;
|
||||||
|
|
||||||
// one recursion level deeper
|
// one recursion level deeper
|
||||||
++depth;
|
++depth;
|
||||||
@ -1820,6 +1820,7 @@ getcmdline_int(
|
|||||||
{
|
{
|
||||||
int trigger_cmdlinechanged = TRUE;
|
int trigger_cmdlinechanged = TRUE;
|
||||||
int end_wildmenu;
|
int end_wildmenu;
|
||||||
|
int prev_cmdpos = ccline.cmdpos;
|
||||||
|
|
||||||
redir_off = TRUE; // Don't redirect the typed command.
|
redir_off = TRUE; // Don't redirect the typed command.
|
||||||
// Repeated, because a ":redir" inside
|
// Repeated, because a ":redir" inside
|
||||||
@ -1836,6 +1837,13 @@ getcmdline_int(
|
|||||||
// Trigger SafeState if nothing is pending.
|
// Trigger SafeState if nothing is pending.
|
||||||
may_trigger_safestate(xpc.xp_numfiles <= 0);
|
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
|
// Get a character. Ignore K_IGNORE and K_NOP, they should not do
|
||||||
// anything, such as stop completion.
|
// anything, such as stop completion.
|
||||||
do
|
do
|
||||||
@ -2566,7 +2574,10 @@ cmdline_not_changed:
|
|||||||
|
|
||||||
#ifdef FEAT_SEARCH_EXTRA
|
#ifdef FEAT_SEARCH_EXTRA
|
||||||
if (!is_state.incsearch_postponed)
|
if (!is_state.incsearch_postponed)
|
||||||
|
{
|
||||||
|
VIM_CLEAR(prev_cmdbuff);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cmdline_changed:
|
cmdline_changed:
|
||||||
@ -2578,15 +2589,17 @@ cmdline_changed:
|
|||||||
may_do_incsearch_highlighting(firstc, count, &is_state);
|
may_do_incsearch_highlighting(firstc, count, &is_state);
|
||||||
#endif
|
#endif
|
||||||
// Trigger CmdlineChanged autocommands.
|
// 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);
|
trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
|
||||||
|
|
||||||
|
VIM_CLEAR(prev_cmdbuff);
|
||||||
|
|
||||||
// Trigger CursorMovedC autocommands.
|
// Trigger CursorMovedC autocommands.
|
||||||
if (ccline.cmdpos != prev_cmdpos)
|
if (ccline.cmdpos != prev_cmdpos)
|
||||||
{
|
|
||||||
trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC);
|
trigger_cmd_autocmd(cmdline_type, EVENT_CURSORMOVEDC);
|
||||||
prev_cmdpos = ccline.cmdpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FEAT_RIGHTLEFT
|
#ifdef FEAT_RIGHTLEFT
|
||||||
if (cmdmsg_rl
|
if (cmdmsg_rl
|
||||||
@ -2695,6 +2708,8 @@ theend:
|
|||||||
restore_cmdline(&save_ccline);
|
restore_cmdline(&save_ccline);
|
||||||
else
|
else
|
||||||
ccline.cmdbuff = NULL;
|
ccline.cmdbuff = NULL;
|
||||||
|
|
||||||
|
vim_free(prev_cmdbuff);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4691,4 +4691,53 @@ func Test_pum_scroll_noselect()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -719,6 +719,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1571,
|
||||||
/**/
|
/**/
|
||||||
1570,
|
1570,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user