Skip to content

Commit bb393d8

Browse files
committed
patch 9.0.1039: using a <Cmd> mapping CmdlineChanged may be triggered twice
Problem: Using a <Cmd> mapping CmdlineChanged may be triggered twice. Solution: Count the number of times CmdlineChanged is triggered and avoid doing it twice. (closes #116820
1 parent ffa4e9b commit bb393d8

5 files changed

Lines changed: 23 additions & 4 deletions

File tree

src/autocmd.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,9 @@ apply_autocmds_group(
20682068
&& (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
20692069
goto BYPASS_AU;
20702070

2071+
if (event == EVENT_CMDLINECHANGED)
2072+
++aucmd_cmdline_changed_count;
2073+
20712074
/*
20722075
* Save the autocmd_* variables and info about the current buffer.
20732076
*/
@@ -2088,8 +2091,8 @@ apply_autocmds_group(
20882091
if (fname_io == NULL)
20892092
{
20902093
if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
2091-
|| event == EVENT_OPTIONSET
2092-
|| event == EVENT_MODECHANGED)
2094+
|| event == EVENT_OPTIONSET
2095+
|| event == EVENT_MODECHANGED)
20932096
autocmd_fname = NULL;
20942097
else if (fname != NULL && !ends_excmd(*fname))
20952098
autocmd_fname = fname;

src/ex_getln.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,11 +1785,13 @@ getcmdline_int(
17851785

17861786
if (c == K_COMMAND || c == K_SCRIPT_COMMAND)
17871787
{
1788-
int clen = ccline.cmdlen;
1788+
int cc_count = aucmd_cmdline_changed_count;
17891789

17901790
if (do_cmdkey_command(c, DOCMD_NOWAIT) == OK)
17911791
{
1792-
if (clen == ccline.cmdlen)
1792+
// Do not trigger CmdlineChanged below if the <Cmd> mapping
1793+
// already did that.
1794+
if (cc_count != aucmd_cmdline_changed_count)
17931795
trigger_cmdlinechanged = FALSE;
17941796
goto cmdline_changed;
17951797
}

src/globals.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,10 +1582,13 @@ EXTERN char_u last_mode[MODE_MAX_LENGTH] INIT(= "n"); // for ModeChanged event
15821582
EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":)
15831583
EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "."
15841584
EXTERN char_u *new_last_cmdline INIT(= NULL); // new value for last_cmdline
1585+
//
15851586
EXTERN char_u *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline
15861587
EXTERN int autocmd_fname_full; // autocmd_fname is full path
15871588
EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
15881589
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
1590+
EXTERN int aucmd_cmdline_changed_count INIT(= 0);
1591+
15891592
EXTERN int did_cursorhold INIT(= FALSE); // set when CursorHold t'gerd
15901593
EXTERN pos_T last_cursormoved // for CursorMoved event
15911594
# ifdef DO_INIT

src/testdir/test_autocmd.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,15 @@ func Test_Cmdline()
19081908
call assert_equal(':', g:entered)
19091909
au! CmdlineChanged
19101910

1911+
let g:log = []
1912+
cnoremap <F1> <Cmd>call setcmdline('ls')<CR>
1913+
autocmd CmdlineChanged : let g:log += [getcmdline()]
1914+
call feedkeys(":\<F1>", 'xt')
1915+
call assert_equal(['ls'], g:log)
1916+
unlet g:log
1917+
au! CmdlineChanged
1918+
cunmap <F1>
1919+
19111920
au! CmdlineEnter : let g:entered = expand('<afile>')
19121921
au! CmdlineLeave : let g:left = expand('<afile>')
19131922
let g:entered = 0

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ static char *(features[]) =
695695

696696
static int included_patches[] =
697697
{ /* Add new patch number below this line */
698+
/**/
699+
1039,
698700
/**/
699701
1038,
700702
/**/

0 commit comments

Comments
 (0)