patch 8.2.5011: Replacing an autocommand requires several lines

Problem:    Replacing an autocommand requires several lines.
Solution:   Add the "replace" flag to autocmd_add(). (Yegappan Lakshmanan,
            closes #10473)
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index fb4532f..0ef7c4c 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -47,6 +47,28 @@
   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 @@
 		}
 
 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: >
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 29cc506..5b20ea3 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -940,13 +940,19 @@
 				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 @@
 		    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
diff --git a/src/autocmd.c b/src/autocmd.c
index 5bcf3ab..c9733ba 100644
--- a/src/autocmd.c
+++ b/src/autocmd.c
@@ -2766,6 +2766,7 @@
     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 @@
 
 	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 @@
 	}
 	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;
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index c6c5f21..e3df115 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -3413,6 +3413,18 @@
         \   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:')
diff --git a/src/version.c b/src/version.c
index 110535c..5ea047a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    5011,
+/**/
     5010,
 /**/
     5009,