Learn Vimscript the Hard Way

Function Arguments

Vimscript functions can, of course, take arguments. Run the following commands:

:function DisplayName(name)
:  echom "Hello!  My name is:"
:  echom a:name
:endfunction

Run the function:

:call DisplayName("Your Name")

Vim will display two lines: Hello! My name is: and Your Name.

Notice the a: in the name of the variable that we passed to the echom command. This represents a variable scope, which we talked about in an earlier chapter.

Let's remove this scope prefix and see how Vim reacts. Run the following commands:

:function UnscopedDisplayName(name)
:  echom "Hello!  My name is:"
:  echom name
:endfunction
:call UnscopedDisplayName("Your Name")

This time Vim complains that it can't find the variable name.

When you write a Vimscript function that takes arguments you always need to prefix those arguments with a: when you use them to tell Vim that they're in the argument scope.

Varargs

Vimscript functions can optionally take variable-length argument lists like Javascript and Python. Run the following commands:

:function Varg(...)
:  echom a:0
:  echom a:1
:  echo a:000
:endfunction

:call Varg("a", "b")

This function shows us several things, so let's look at each one individually.

The ... in the function definition tells Vim that this function can take any number of arguments. This is like a *args argument in a Python function.

The first line of the function echoes the message a:0 and displays 2. When you define a function that takes a variable number of arguments in Vim, a:0 will be set to the number of extra arguments you were given. In this case we passed two arguments to Varg so Vim displayed 2.

The second line echoes a:1 which displays a. You can use a:1, a:2, etc to refer to each extra argument your function receives. If we had used a:2 Vim would have displayed "b".

The third line is a bit trickier. When a function has varargs, a:000 will be set to a list containing all the extra arguments that were passed. We haven't looked at lists quite yet, so don't worry about this too much. You can't use echom with a list, which is why we used echo instead for that line.

You can use varargs together with regular arguments too. Run the following commands:

:function Varg2(foo, ...)
:  echom a:foo
:  echom a:0
:  echom a:1
:  echo a:000
:endfunction

:call Varg2("a", "b", "c")

We can see that Vim puts "a" into the named argument a:foo, and the rest are put into the list of varargs.

Assignment

Try running the following commands:

:function Assign(foo)
:  let a:foo = "Nope"
:  echom a:foo
:endfunction

:call Assign("test")

Vim will throw an error, because you can't reassign argument variables. Now run these commands:

:function AssignGood(foo)
:  let foo_tmp = a:foo
:  let foo_tmp = "Yep"
:  echom foo_tmp
:endfunction

:call AssignGood("test")

This time the function works, and Vim displays Yep.

Exercises

Read the first two paragraphs of :help function-argument.

Read :help local-variables.