How to pass arguments from :command to function?

Have to ask tough questions. I don't really have any solutions but here are my findings.

:command! -range -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>]

After running the following scenarios:

:MY
[0, 3, 3, -1, '']
:MY!
[1, 3, 3, -1, '']
:%MY
[0, 1, 10, 10, '']
:%MY 4
[0, 1, 10, 10, '4']
:MY 4
[0, 3, 3, -1, '4']
:%MY flag
[0, 1, 10, 10, 'flag']
:MY flag
[0, 3, 3, -1, 'flag']
:%MY 4 flag
[0, 1, 10, 10, '4 flag']

Now with -count instead of -range

:command! -count -bang -nargs=* MY echo [<bang>0, <line1>, <line2>, <count>, <q-args>]

Results:

:MY
[0, 3, 1, 0, '']
:MY!
[1, 3, 1, 0, '']
:%MY
[0, 1, 10, 10, '']
:%MY 4
[0, 1, 4, 4, '']
:MY 4
[0, 3, 4, 4, '']
:%MY flag
[0, 1, 10, 10, 'flag']
:MY flag
[0, 3, 1, 0, 'flag']
:%MY 4 flag
[0, 1, 4, 4, 'flag']

As you can see it doesn't easy. My suggestion would be to use -range with your command. And then parse the <q-args> looking for a number via \d\+.


For your complex custom command, you cannot rely solely on Vim's limited parsing options; you can have it handle the range with -range, but have to parse your combination of arguments yourself.

:command! -nargs=* -range -bang MyCMD <line1>,<line2>call MyFUNC(<bang>0, <q-args>)

Inside MyFUNC (which should probably be defined with :function MyFUNC( ... ) range to be invoked only once), split() the arguments on whitespace. Alternatively, you could define the function to use a variable number of arguments and use <f-args>, but note that the number of function arguments is limited (to 20 IIRC).

The <bang>0 is a nice trick to transform the bang into a boolean, which is usually what you need.

Tags:

Vim