Skip to content

Commit 55d4691

Browse files
committed
patch 8.1.0573: cannot redefine user command without ! in same script
Problem: Cannot redefine user command without ! in same script Solution: Allow redefining user command without ! in same script, like with functions.
1 parent 76ab4fd commit 55d4691

4 files changed

Lines changed: 59 additions & 13 deletions

File tree

runtime/doc/map.txt

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,14 +1223,19 @@ See |:verbose-cmd| for more information.
12231223
attributes (see below) are {attr}. If the command
12241224
already exists, an error is reported, unless a ! is
12251225
specified, in which case the command is redefined.
1226+
There is one exception: When sourcing a script again,
1227+
a command that was previously defined in that script
1228+
will be silently replaced.
1229+
12261230

12271231
:delc[ommand] {cmd} *:delc* *:delcommand* *E184*
12281232
Delete the user-defined command {cmd}.
12291233

12301234
:comc[lear] *:comc* *:comclear*
12311235
Delete all user-defined commands.
12321236

1233-
Command attributes
1237+
1238+
Command attributes ~
12341239

12351240
User-defined commands are treated by Vim just like any other Ex commands. They
12361241
can have arguments, or have a range specified. Arguments are subject to
@@ -1241,8 +1246,9 @@ There are a number of attributes, split into four categories: argument
12411246
handling, completion behavior, range handling, and special cases. The
12421247
attributes are described below, by category.
12431248

1244-
Argument handling *E175* *E176* *:command-nargs*
12451249

1250+
Argument handling ~
1251+
*E175* *E176* *:command-nargs*
12461252
By default, a user defined command will take no arguments (and an error is
12471253
reported if any are supplied). However, it is possible to specify that the
12481254
command can take arguments, using the -nargs attribute. Valid cases are:
@@ -1271,8 +1277,10 @@ defined, not where it is invoked! Example:
12711277
Executing script2.vim will result in "None" being echoed. Not what you
12721278
intended! Calling a function may be an alternative.
12731279

1274-
Completion behavior *:command-completion* *E179*
1275-
*E180* *E181* *:command-complete*
1280+
1281+
Completion behavior ~
1282+
*:command-completion* *E179* *E180* *E181*
1283+
*:command-complete*
12761284
By default, the arguments of user defined commands do not undergo completion.
12771285
However, by specifying one or the other of the following attributes, argument
12781286
completion can be enabled:
@@ -1317,9 +1325,9 @@ completion can be enabled:
13171325
Note: That some completion methods might expand environment variables.
13181326

13191327

1320-
Custom completion *:command-completion-custom*
1321-
*:command-completion-customlist*
1322-
*E467* *E468*
1328+
Custom completion ~
1329+
*:command-completion-custom*
1330+
*:command-completion-customlist* *E467* *E468*
13231331
It is possible to define customized completion schemes via the "custom,{func}"
13241332
or the "customlist,{func}" completion argument. The {func} part should be a
13251333
function with the following signature: >
@@ -1364,8 +1372,8 @@ the 'path' option: >
13641372
This example does not work for file names with spaces!
13651373

13661374

1367-
Range handling *E177* *E178* *:command-range*
1368-
*:command-count*
1375+
Range handling ~
1376+
*E177* *E178* *:command-range* *:command-count*
13691377
By default, user-defined commands do not accept a line number range. However,
13701378
it is possible to specify that the command does take a range (the -range
13711379
attribute), or that it takes an arbitrary count value, either in the line
@@ -1399,8 +1407,11 @@ Possible values are:
13991407
-addr=loaded_buffers Range for loaded buffers
14001408
-addr=windows Range for windows
14011409
-addr=tabs Range for tab pages
1410+
-addr=other other kind of range
14021411

1403-
Special cases *:command-bang* *:command-bar*
1412+
1413+
Special cases ~
1414+
*:command-bang* *:command-bar*
14041415
*:command-register* *:command-buffer*
14051416
There are some special cases as well:
14061417

@@ -1418,7 +1429,8 @@ replacement text separately.
14181429
Note that these arguments can be abbreviated, but that is a deprecated
14191430
feature. Use the full name for new scripts.
14201431

1421-
Replacement text
1432+
1433+
Replacement text ~
14221434

14231435
The replacement text for a user defined command is scanned for special escape
14241436
sequences, using <...> notation. Escape sequences are replaced with values

src/ex_docmd.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5869,9 +5869,13 @@ uc_add_command(
58695869

58705870
if (cmp == 0)
58715871
{
5872-
if (!force)
5872+
// Command can be replaced with "command!" and when sourcing the
5873+
// same script again, but only once.
5874+
if (!force && (cmd->uc_script_ctx.sc_sid != current_sctx.sc_sid
5875+
|| cmd->uc_script_ctx.sc_seq == current_sctx.sc_seq))
58735876
{
5874-
EMSG(_("E174: Command already exists: add ! to replace it"));
5877+
EMSG2(_("E174: Command already exists: add ! to replace it: %s"),
5878+
name);
58755879
goto fail;
58765880
}
58775881

src/testdir/test_usercommands.vim

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,34 @@ func Test_Ambiguous()
9090
delcommand Dothat
9191
endfunc
9292

93+
func Test_redefine_on_reload()
94+
call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists')
95+
call assert_equal(0, exists(':ExistingCommand'))
96+
source Xcommandexists
97+
call assert_equal(2, exists(':ExistingCommand'))
98+
" Redefining a command when reloading a script is OK.
99+
source Xcommandexists
100+
call assert_equal(2, exists(':ExistingCommand'))
101+
102+
" But redefining in another script is not OK.
103+
call writefile(['command ExistingCommand echo "yes"'], 'Xcommandexists2')
104+
call assert_fails('source Xcommandexists2', 'E174:')
105+
call delete('Xcommandexists2')
106+
107+
" And defining twice in one script is not OK.
108+
delcommand ExistingCommand
109+
call assert_equal(0, exists(':ExistingCommand'))
110+
call writefile([
111+
\ 'command ExistingCommand echo "yes"',
112+
\ 'command ExistingCommand echo "no"',
113+
\ ], 'Xcommandexists')
114+
call assert_fails('source Xcommandexists', 'E174:')
115+
call assert_equal(2, exists(':ExistingCommand'))
116+
117+
call delete('Xcommandexists')
118+
delcommand ExistingCommand
119+
endfunc
120+
93121
func Test_CmdUndefined()
94122
call assert_fails('Doit', 'E492:')
95123
au CmdUndefined Doit :command Doit let g:didit = 'yes'

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,8 @@ static char *(features[]) =
792792

793793
static int included_patches[] =
794794
{ /* Add new patch number below this line */
795+
/**/
796+
573,
795797
/**/
796798
572,
797799
/**/

0 commit comments

Comments
 (0)