I often see vim function with function definition written like this:

function! MyFunction(...)
" function body...
endfunction

What does the ... do within the function?

Explaination

It means variadic arguments (see :h ...). To get all the extra arguments as a list, you use a:000. To get the i'th extra arguments use a:i where i is the integer (equivalent to a:000[i-1]). a:0 represents the number of extra arguments a:0 == len(a:000)

Example

To check whether an extra argument is supplied you do

if a:0
    let arg1 = a:1  " let a:000[0]
else
    let arg1 = arg1_default
endif

More conveniently, the previous snippet is equivalent to (Note that the second parameter is 0 to denote the first element in the list a:000)

let arg1 = get(a:000, 0, arg1_default)

Forward the variadic parameters

Some times you may need to forward the variadic parameters to another function using the same order. For example, if MyFunc should call s:MyFuncImpl with all the variadic parameters passed, you can do the following in MyFunc

call call('s:MyFuncImpl', a:000)

Here the first call is the command call, see :h :call, the second call is a function, see :h call().

Handle a large amount of extra arguments

Personally, if the potential number of extra arguments is large or when I anticipate to have more and more extra arguments to the function when the plugin evolves, I will use a single dict to represent the extra arguments. So I use the following pattern

function! MyFunc(x, y, ...)
    let opts   = get(a:000, 0, {})
    let method = get(opts, 'method', 'default')
    let buf    = get(opts, 'buf', buf('%'))
    " other statements
endfunction

Here, the function get can deal with both list and dict. Now, you call it using call MyFunc(x, y, {'method': 'best'}) if method is different from the default and buf should use the default. This makes the function more adaptable and more readable.

  • @JohnFredFadrigalan If you are satisfied with this answer, please remember to mark it as "accepted" with the green button under the vote button: that will allow future users to know your question has an answer which could help them. – statox yesterday

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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