I am working on a VIM plugin that will require a certain level of complexity for handling arguments passed to a command.

:MyCommand -item=banana -command=ls\-ltra -pattern=./*

However, I am not sure how to handle this situation. I am aware of how arguments work in vimL, with the a:0 and a:000 and the <f-args> bits. But not sure how to do the splitting and filtering of the strings etc.

Ideally, I will be constructing a dictionary out of my arguments:

    'command':'ls -ltra',

Of course, there are other plugins out there that I can peak into and see how they have solved this issue to certain extend, yet still, any suggestions would be at a great help.

--- EDIT(1) ---

Here is a prototype:

function! MyCommand(...) abort
    " Total argument count.
    echo 'a:0 -> ' . a:0

    " Iterative lookup.
    " echo 'a:1   -> ' . a:1
    " echo 'a:2   -> ' . a:2
    " ... etc.
    let l:limit = a:0
    let l:counter = 1
    while l:limit >= l:counter
        exec 'echo ' . '"a:' . l:counter . '"' . '"->"' . 'a:' . l:counter
        let l:counter += 1

    " All arguments as a list.
    echo 'a:000:' 
    echo a:000

And this when run as:

:MyCommand -stage=build -task=do -command=ls\-ltr -pattern=./* -working-directory=/path/to/my/project

Produces the following output:

a:0 -> 5
a:1 -> -stage=build
a:2 -> -task=do
a:3 -> -command=ls\-ltr
a:4 -> -pattern=./*
a:5 -> -working-directory=/path/to/my/project
['-stage=build', '-task=do', '-command=ls\-ltr', '-pattern=./*', 'working-directory=/path/to/my/project']

So, I guess, the rest would be regex based checks and string processing to extract the right bits of information. Anything more efficient that should be done on the function and arguments handling side?

2 Answers 2


You should be able to do this simply by splitting the arg on an = and going through a for loop. Something like the following should work.

command! -nargs=+ MyCommand :call MyFunction(<f-args>)
let s:dictionary = {}

function! MyFunction(...)
   for arg in a:000
      let myList = split(arg, '=')
      let s:dictionary[myList[0]] = myList[1]
  • -nargs=+: Function must have at least one argument
  • <f-args>: Will pass white-space split arguments to MyFunction().
  • split(arg, '='): Splits each argument up on an = sign.

You also have some interesting substitution going on but I'll leave that as an exercise to the reader as I'm not sure exactly how you want it done. Suffice it to say you should be able to do these with the substitute() function.

See :help :command-nargs, :help <f-args>, :help split(), and :help substitute() for more info.

  • Yes. Thanks. So anything else such as checking if the arguments are constructed correctly, should be done with a series of regex/substitution style testing, right? For example, if the argument is constructed as -item=component and NOT as --item="component".
    – mbilyanov
    Commented Apr 18, 2017 at 15:55
  • I'm not the definitive resource on this, but that would be approach I would take. Some =~ test to make sure the inputs are correct as defined by you.
    – Tumbler41
    Commented Apr 18, 2017 at 16:04
  • The constructed dictionary should not be a script variable unless necessary. In this case, it seems more appropriate to use a local variable. IMHO, of course. Commented Apr 19, 2017 at 6:30

Merging back parameters like --foo="foo bar" requires manual work. Vim doesn't provide us anything to solve this issue.

I remember having started an experiment on the subject. Unfortunately, this is nothing more than that: an incomplete experiment: lh#command#Fargs2String()

  • 1
    Luc, this library of yours, it looks amazing! I did not have a chance to peak into it in great detail, but I can see so much work has been done around it. Thanks for sharing this.
    – mbilyanov
    Commented Apr 19, 2017 at 9:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.