]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1039: using a <Cmd> mapping CmdlineChanged may be triggered twice v9.0.1039
authorBram Moolenaar <Bram@vim.org>
Fri, 9 Dec 2022 12:21:50 +0000 (12:21 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 9 Dec 2022 12:21:50 +0000 (12:21 +0000)
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

src/autocmd.c
src/ex_getln.c
src/globals.h
src/testdir/test_autocmd.vim
src/version.c

index aca990cb51f1619be23487ad39317099517b2c6b..20c5afa74415651041af9a6160233fdc7e7e90a4 100644 (file)
@@ -2068,6 +2068,9 @@ apply_autocmds_group(
                && (event == EVENT_WINLEAVE || event == EVENT_BUFLEAVE)))
        goto BYPASS_AU;
 
+    if (event == EVENT_CMDLINECHANGED)
+       ++aucmd_cmdline_changed_count;
+
     /*
      * Save the autocmd_* variables and info about the current buffer.
      */
@@ -2088,8 +2091,8 @@ apply_autocmds_group(
     if (fname_io == NULL)
     {
        if (event == EVENT_COLORSCHEME || event == EVENT_COLORSCHEMEPRE
-                                                  || event == EVENT_OPTIONSET
-                                                  || event == EVENT_MODECHANGED)
+                                                || event == EVENT_OPTIONSET
+                                                || event == EVENT_MODECHANGED)
            autocmd_fname = NULL;
        else if (fname != NULL && !ends_excmd(*fname))
            autocmd_fname = fname;
index 4bd200d33f889f3fb4267e5a480710d8bf46cdfb..0eb7d86c108572011179ba7f0c1fd4432a16416c 100644 (file)
@@ -1785,11 +1785,13 @@ getcmdline_int(
 
        if (c == K_COMMAND || c == K_SCRIPT_COMMAND)
        {
-           int     clen = ccline.cmdlen;
+           int     cc_count = aucmd_cmdline_changed_count;
 
            if (do_cmdkey_command(c, DOCMD_NOWAIT) == OK)
            {
-               if (clen == ccline.cmdlen)
+               // Do not trigger CmdlineChanged below if the <Cmd> mapping
+               // already did that.
+               if (cc_count != aucmd_cmdline_changed_count)
                    trigger_cmdlinechanged = FALSE;
                goto cmdline_changed;
            }
index 8fb4340b163a54e4ca02207701a910aba005836c..ced28baed55295aa8c99f9f78b6530df4ec1f93a 100644 (file)
@@ -1582,10 +1582,13 @@ EXTERN char_u   last_mode[MODE_MAX_LENGTH] INIT(= "n"); // for ModeChanged event
 EXTERN char_u  *last_cmdline INIT(= NULL); // last command line (for ":)
 EXTERN char_u  *repeat_cmdline INIT(= NULL); // command line for "."
 EXTERN char_u  *new_last_cmdline INIT(= NULL); // new value for last_cmdline
+                                               //
 EXTERN char_u  *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline
 EXTERN int     autocmd_fname_full;          // autocmd_fname is full path
 EXTERN int     autocmd_bufnr INIT(= 0);     // fnum for <abuf> on cmdline
 EXTERN char_u  *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
+EXTERN int     aucmd_cmdline_changed_count INIT(= 0);
+
 EXTERN int     did_cursorhold INIT(= FALSE); // set when CursorHold t'gerd
 EXTERN pos_T   last_cursormoved              // for CursorMoved event
 # ifdef DO_INIT
index 8103382fbf19cc1fb60bdee43c57d5b1a55283f3..1eb7bb0414cd4974e1897f62df7825406f0d73d1 100644 (file)
@@ -1908,6 +1908,15 @@ func Test_Cmdline()
   call assert_equal(':', g:entered)
   au! CmdlineChanged
 
+  let g:log = []
+  cnoremap <F1> <Cmd>call setcmdline('ls')<CR>
+  autocmd CmdlineChanged : let g:log += [getcmdline()]
+  call feedkeys(":\<F1>", 'xt')
+  call assert_equal(['ls'], g:log)
+  unlet g:log
+  au! CmdlineChanged
+  cunmap <F1>
+
   au! CmdlineEnter : let g:entered = expand('<afile>')
   au! CmdlineLeave : let g:left = expand('<afile>')
   let g:entered = 0
index aac1cc977922193d0131de0b2c1bde9fb2f7a710..bfa0c5df2e7de0e63951d87412af4ba66c75afc6 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1039,
 /**/
     1038,
 /**/