diff options
-rw-r--r-- | runtime/doc/map.txt | 26 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 9 | ||||
-rw-r--r-- | src/nvim/testdir/test_usercommands.vim | 28 |
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' |