chapters/24.markdown @ a16e1fecfe07 default tip

Be clear
author Steve Losh <steve@stevelosh.com>
date Mon, 27 Mar 2017 13:10:55 +0000
parents f09f87e10570
children (none)
Function Arguments
==================

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

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

Run the function:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :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:

    :::vim
    :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`.