# HG changeset patch # User Steve Losh # Date 1318564452 14400 # Node ID 055027714e9b31341368f21a66d19aaa46a08a92 # Parent 93d00f94217aa4059fffe5092117d89b6db8797e Function arguments. diff -r 93d00f94217a -r 055027714e9b chapters/23.markdown --- a/chapters/23.markdown Thu Oct 13 00:01:07 2011 -0400 +++ b/chapters/23.markdown Thu Oct 13 23:54:12 2011 -0400 @@ -8,13 +8,13 @@ :function meow() -You might think this would start defining a functione named `Meow`. +You might think this would start defining a function named `Meow`. Unfortunately this is not the case, and we've already run into one of Vimscript's quirks. **Vimscript functions *must* start with a capital letter if they are unscoped!** -Even if you *do* add a scope to a function (we'll talk about that in a bit) you +Even if you *do* add a scope to a function (we'll talk about that later) you may as well capitalize the first letter of function names anyway. Most Vimscript coders seem to do it, so don't break the convention. diff -r 93d00f94217a -r 055027714e9b chapters/24.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chapters/24.markdown Thu Oct 13 23:54:12 2011 -0400 @@ -0,0 +1,114 @@ +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 Python functions. + +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 Varg("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 "Yes". + +Exercises +--------- + +Read the first two paragraphs of `:help function-argument`. + +Read `:help local-variables`. diff -r 93d00f94217a -r 055027714e9b outline.org --- a/outline.org Thu Oct 13 00:01:07 2011 -0400 +++ b/outline.org Thu Oct 13 23:54:12 2011 -0400 @@ -23,9 +23,7 @@ ** DONE conditionals ** DONE comparisons ** DONE functions -** TODO function scoping -** TODO function varargs -** TODO functions (more) +** DONE function arguments ** TODO strings ** TODO string functions ** TODO normal! @@ -36,6 +34,7 @@ ** TODO dictionaries ** TODO paths ** TODO exceptions +** TODO functions again ** TODO command! * part 3 - creating a full plugin ** TODO intro and plugin layout