aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/map.txt26
-rw-r--r--src/nvim/ex_docmd.c9
-rw-r--r--src/nvim/testdir/test_usercommands.vim28
3 files changed, 52 insertions, 11 deletions
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index ed31ecc42e..a2b7aca4fd 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1162,6 +1162,10 @@ See |:verbose-cmd| for more information.
attributes (see below) are {attr}. If the command
already exists, an error is reported, unless a ! is
specified, in which case the command is redefined.
+ There is one exception: When sourcing a script again,
+ a command that was previously defined in that script
+ will be silently replaced.
+
:delc[ommand] {cmd} *:delc* *:delcommand* *E184*
Delete the user-defined command {cmd}.
@@ -1169,7 +1173,8 @@ See |:verbose-cmd| for more information.
:comc[lear] *:comc* *:comclear*
Delete all user-defined commands.
-Command attributes
+
+Command attributes ~
User-defined commands are treated by Vim just like any other Ex commands. They
can have arguments, or have a range specified. Arguments are subject to
@@ -1180,8 +1185,9 @@ There are a number of attributes, split into four categories: argument
handling, completion behavior, range handling, and special cases. The
attributes are described below, by category.
-Argument handling *E175* *E176* *:command-nargs*
+Argument handling ~
+ *E175* *E176* *:command-nargs*
By default, a user defined command will take no arguments (and an error is
reported if any are supplied). However, it is possible to specify that the
command can take arguments, using the -nargs attribute. Valid cases are:
@@ -1257,9 +1263,9 @@ completion can be enabled:
Note: That some completion methods might expand environment variables.
-Custom completion *:command-completion-custom*
- *:command-completion-customlist*
- *E467* *E468*
+Custom completion ~
+ *:command-completion-custom*
+ *:command-completion-customlist* *E467* *E468*
It is possible to define customized completion schemes via the "custom,{func}"
or the "customlist,{func}" completion argument. The {func} part should be a
function with the following signature: >
@@ -1304,8 +1310,8 @@ the 'path' option: >
This example does not work for file names with spaces!
-Range handling *E177* *E178* *:command-range*
- *:command-count*
+Range handling ~
+ *E177* *E178* *:command-range* *:command-count*
By default, user-defined commands do not accept a line number range. However,
it is possible to specify that the command does take a range (the -range
attribute), or that it takes an arbitrary count value, either in the line
@@ -1342,7 +1348,8 @@ Possible values are:
-addr=other other kind of range
-Special cases *:command-bang* *:command-bar*
+Special cases ~
+ *:command-bang* *:command-bar*
*:command-register* *:command-buffer*
There are some special cases as well:
@@ -1360,7 +1367,8 @@ replacement text separately.
Note that these arguments can be abbreviated, but that is a deprecated
feature. Use the full name for new scripts.
-Replacement text
+
+Replacement text ~
The replacement text for a user defined command is scanned for special escape
sequences, using <...> notation. Escape sequences are replaced with values
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 5bf6aa73c6..608b7dc94c 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5026,8 +5026,13 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
}
if (cmp == 0) {
- if (!force) {
- EMSG(_("E174: Command already exists: add ! to replace it"));
+ // Command can be replaced with "command!" and when sourcing the
+ // same script again, but only once.
+ if (!force
+ && (cmd->uc_script_ctx.sc_sid != current_sctx.sc_sid
+ || cmd->uc_script_ctx.sc_seq == current_sctx.sc_seq)) {
+ EMSG2(_("E174: Command already exists: add ! to replace it: %s"),
+ name);
goto fail;
}
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
index 2c7cb7bab7..fdd3a9abeb 100644
--- a/src/nvim/testdir/test_usercommands.vim
+++ b/src/nvim/testdir/test_usercommands.vim
@@ -184,6 +184,34 @@ func Test_Ambiguous()
call assert_fails("\x4ei\041", 'E492: Not an editor command: Ni!')
endfunc
+func Test_redefine_on_reload()
+ call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists')
+ call assert_equal(0, exists(':ExistingCommand'))
+ source Xcommandexists
+ call assert_equal(2, exists(':ExistingCommand'))
+ " Redefining a command when reloading a script is OK.
+ source Xcommandexists
+ call assert_equal(2, exists(':ExistingCommand'))
+
+ " But redefining in another script is not OK.
+ call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists2')
+ call assert_fails('source Xcommandexists2', 'E174:')
+ call delete('Xcommandexists2')
+
+ " And defining twice in one script is not OK.
+ delcommand ExistingCommand
+ call assert_equal(0, exists(':ExistingCommand'))
+ call writefile([
+ \ 'command ExistingCommand echo "yes"',
+ \ 'command ExistingCommand echo "no"',
+ \ ], 'Xcommandexists')
+ call assert_fails('source Xcommandexists', 'E174:')
+ call assert_equal(2, exists(':ExistingCommand'))
+
+ call delete('Xcommandexists')
+ delcommand ExistingCommand
+endfunc
+
func Test_CmdUndefined()
call assert_fails('Doit', 'E492:')
au CmdUndefined Doit :command Doit let g:didit = 'yes'