]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.5011: Replacing an autocommand requires several lines v8.2.5011
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 24 May 2022 10:40:11 +0000 (11:40 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 24 May 2022 10:40:11 +0000 (11:40 +0100)
Problem:    Replacing an autocommand requires several lines.
Solution:   Add the "replace" flag to autocmd_add(). (Yegappan Lakshmanan,
            closes #10473)

runtime/doc/autocmd.txt
runtime/doc/builtin.txt
src/autocmd.c
src/testdir/test_autocmd.vim
src/version.c

index fb4532fc4e129d04c745df70d0e91aabd8c5441c..0ef7c4c67bcbd0e3a8cb2b221907471eaf80475f 100644 (file)
@@ -47,6 +47,28 @@ effects.  Be careful not to destroy your text.
   It's a good idea to use the same autocommands for the File* and Buf* events
   when possible.
 
+Recommended use:
+- Always use a group, so that it's easy to delete the autocommand.
+- Keep the command itself short, call a function to do more work.
+- Make it so that the script it is defined it can be sourced several times
+  without the autocommand being repeated.
+
+Example in Vim9 script: >
+   autocmd_add({replace: true,
+               group:   'DemoGroup',
+               event:   'BufEnter',
+               pattern: '*.txt',
+               cmd:     'call DemoBufEnter()'
+               })
+
+In legacy script: >
+   call autocmd_add(#{replace: v:true,
+                   \ group: 'DemoGroup',
+                   \ event: 'BufEnter',
+                   \ pattern: '*.txt',
+                   \ cmd: 'call DemoBufEnter()'
+                   \ })
+
 ==============================================================================
 2. Defining autocommands                               *autocmd-define*
 
@@ -83,7 +105,8 @@ triggered.
                }
 
 The |autocmd_add()| function can be used to add a list of autocmds and autocmd
-groups from a Vim script.
+groups from a Vim script.  It is preferred if you have anything that would
+require using `:execute` with `:autocmd`.
 
 Note: The ":autocmd" command can only be followed by another command when the
 '|' appears where the pattern is expected.  This works: >
index 29cc50627379b192562460a91a38f98721d22bfe..5b20ea3322224f3de715d5d14241cbbbbe8b6c9f 100644 (file)
@@ -940,13 +940,19 @@ autocmd_add({acmds})                                      *autocmd_add()*
                                If this group doesn't exist then it is
                                created.  If not specified or empty, then the
                                default group is used.
-                   nested      set to v:true to add a nested autocmd.
-                               Refer to |autocmd-nested|.
-                   once        set to v:true to add a autocmd which executes
-                               only once. Refer to |autocmd-once|.
+                   nested      boolean flag, set to v:true to add a nested
+                               autocmd.  Refer to |autocmd-nested|.
+                   once        boolean flag, set to v:true to add a autocmd
+                               which executes only once. Refer to
+                               |autocmd-once|.
                    pattern     autocmd pattern string. Refer to
                                |autocmd-patterns|.  If "bufnr" item is
                                present, then this item is ignored.
+                   replace     boolean flag, set to v:true to remove all the
+                               commands associated with the specified autocmd
+                               event and group and add the {cmd}.  This is
+                               useful to avoid adding the same command
+                               multiple times for a autocmd event in a group.
 
                Returns v:true on success and v:false on failure.
                Examples: >
@@ -1037,10 +1043,10 @@ autocmd_get([{opts}])                                   *autocmd_get()*
                    cmd         Command executed for this autocmd.
                    event       Autocmd event name.
                    group       Autocmd group name.
-                   nested      Set to v:true for a nested autocmd. See
-                               |autocmd-nested|.
-                   once        Set to v:true, if the autocmd will be executed
-                               only once. See |autocmd-once|.
+                   nested      Boolean flag, set to v:true for a nested
+                               autocmd. See |autocmd-nested|.
+                   once        Boolean flag, set to v:true, if the autocmd
+                               will be executed only once. See |autocmd-once|.
                    pattern     Autocmd pattern.  For a buffer-local
                                autocmd, this will be of the form "<buffer=n>".
                If there are multiple commands for an autocmd event in a
index 5bcf3ab56199839c4d339422cc0731bf7aa75b8a..c9733ba5d34848ef37c075c098d6b212d0ea6047 100644 (file)
@@ -2766,6 +2766,7 @@ autocmd_add_or_delete(typval_T *argvars, typval_T *rettv, int delete)
     char_u     *end;
     int                once;
     int                nested;
+    int                replace;                // replace the cmd for a group/event
     int                retval = VVAL_TRUE;
     int                save_augroup = current_augroup;
 
@@ -2877,6 +2878,9 @@ autocmd_add_or_delete(typval_T *argvars, typval_T *rettv, int delete)
 
        once = dict_get_bool(event_dict, (char_u *)"once", FALSE);
        nested = dict_get_bool(event_dict, (char_u *)"nested", FALSE);
+       // if 'replace' is true, then remove all the commands associated with
+       // this autocmd event/group and add the new command.
+       replace = dict_get_bool(event_dict, (char_u *)"replace", FALSE);
 
        cmd = dict_get_string(event_dict, (char_u *)"cmd", TRUE);
        if (cmd == NULL)
@@ -2903,8 +2907,8 @@ autocmd_add_or_delete(typval_T *argvars, typval_T *rettv, int delete)
        }
        else
        {
-           if (do_autocmd_event(event, pat, once, nested, cmd, delete, group,
-                                                                   0) == FAIL)
+           if (do_autocmd_event(event, pat, once, nested, cmd,
+                                       delete | replace, group, 0) == FAIL)
            {
                retval = VVAL_FALSE;
                break;
index c6c5f2172ca6c53b07fdf4a1a33e2a22005fcc91..e3df115a6d46b504e2aaa3a5cb258e125bc5d662 100644 (file)
@@ -3413,6 +3413,18 @@ func Test_autocmd_add()
         \   nested: v:false,  once: v:false, event: 'BufHidden'}],
         \   autocmd_get(#{group: 'TestAcSet'}))
 
+  " Test for replacing a cmd for an event in a group
+  call autocmd_delete([#{group: 'TestAcSet'}])
+  call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter',
+        \ pattern: '*.py', cmd: 'echo "bufenter"'}])
+  call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter',
+        \ pattern: '*.py', cmd: 'echo "bufenter"'}])
+  call assert_equal([
+        \ #{cmd: 'echo "bufenter"', group: 'TestAcSet', pattern: '*.py',
+        \   nested: v:false,  once: v:false, event: 'BufEnter'}],
+        \   autocmd_get(#{group: 'TestAcSet'}))
+
+  " Test for adding a command for an unsupported autocmd event
   let l = [#{group: 'TestAcSet', event: 'abc', pattern: '*.sh',
         \ cmd: 'echo "bufadd"'}]
   call assert_fails('call autocmd_add(l)', 'E216:')
index 110535c9b5f0b54be4a716883bd9dde5ef3e99cb..5ea047ac37944821cf4eb3017f78bdc3c91691e7 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    5011,
 /**/
     5010,
 /**/