| *userfunc.txt* For Vim version 9.0. Last change: 2022 Sep 09 |
| |
| |
| VIM REFERENCE MANUAL by Bram Moolenaar |
| |
| |
| Defining and using functions. |
| |
| This is introduced in section |41.7| of the user manual. |
| |
| 1. Defining a fuction |define-function| |
| 2. Calling a fuction |:call| |
| 3. Cleaning up in a function |:defer| |
| 4. Automatically loading functions |autoload-functions| |
| |
| ============================================================================== |
| |
| 1. Defining a function ~ |
| *define-function* |
| New functions can be defined. These can be called just like builtin |
| functions. The function executes a sequence of Ex commands. Normal mode |
| commands can be executed with the |:normal| command. |
| |
| The function name must start with an uppercase letter, to avoid confusion with |
| builtin functions. To prevent from using the same name in different scripts |
| make them script-local. If you do use a global function then avoid obvious, |
| short names. A good habit is to start the function name with the name of the |
| script, e.g., "HTMLcolor()". |
| |
| In legacy script it is also possible to use curly braces, see |
| |curly-braces-names|. |
| |
| The |autoload| facility is useful to define a function only when it's called. |
| |
| *local-function* |
| A function local to a legacy script must start with "s:". A local script |
| function can only be called from within the script and from functions, user |
| commands and autocommands defined in the script. It is also possible to call |
| the function from a mapping defined in the script, but then |<SID>| must be |
| used instead of "s:" when the mapping is expanded outside of the script. |
| There are only script-local functions, no buffer-local or window-local |
| functions. |
| |
| In |Vim9| script functions are local to the script by default, prefix "g:" to |
| define a global function. |
| |
| *:fu* *:function* *E128* *E129* *E123* *E454* |
| :fu[nction] List all functions and their arguments. |
| |
| :fu[nction] {name} List function {name}. |
| {name} can also be a |Dictionary| entry that is a |
| |Funcref|: > |
| :function dict.init |
| |
| :fu[nction] /{pattern} List functions with a name matching {pattern}. |
| Example that lists all functions ending with "File": > |
| :function /File$ |
| < |
| *:function-verbose* |
| When 'verbose' is non-zero, listing a function will also display where it was |
| last defined. Example: > |
| |
| :verbose function SetFileTypeSH |
| function SetFileTypeSH(name) |
| Last set from /usr/share/vim/vim-7.0/filetype.vim |
| < |
| See |:verbose-cmd| for more information. |
| |
| *E124* *E125* *E853* *E884* |
| :fu[nction][!] {name}([arguments]) [range] [abort] [dict] [closure] |
| Define a new function by the name {name}. The body of |
| the function follows in the next lines, until the |
| matching |:endfunction|. |
| *E1267* |
| The name must be made of alphanumeric characters and |
| '_', and must start with a capital or "s:" (see |
| above). Note that using "b:" or "g:" is not allowed. |
| (since patch 7.4.260 E884 is given if the function |
| name has a colon in the name, e.g. for "foo:bar()". |
| Before that patch no error was given). |
| |
| {name} can also be a |Dictionary| entry that is a |
| |Funcref|: > |
| :function dict.init(arg) |
| < "dict" must be an existing dictionary. The entry |
| "init" is added if it didn't exist yet. Otherwise [!] |
| is required to overwrite an existing function. The |
| result is a |Funcref| to a numbered function. The |
| function can only be used with a |Funcref| and will be |
| deleted if there are no more references to it. |
| *E127* *E122* |
| When a function by this name already exists and [!] is |
| not used an error message is given. There is one |
| exception: When sourcing a script again, a function |
| that was previously defined in that script will be |
| silently replaced. |
| When [!] is used, an existing function is silently |
| replaced. Unless it is currently being executed, that |
| is an error. |
| NOTE: Use ! wisely. If used without care it can cause |
| an existing function to be replaced unexpectedly, |
| which is hard to debug. |
| NOTE: In Vim9 script script-local functions cannot be |
| deleted or redefined. |
| |
| For the {arguments} see |function-argument|. |
| |
| *:func-range* *a:firstline* *a:lastline* |
| When the [range] argument is added, the function is |
| expected to take care of a range itself. The range is |
| passed as "a:firstline" and "a:lastline". If [range] |
| is excluded, ":{range}call" will call the function for |
| each line in the range, with the cursor on the start |
| of each line. See |function-range-example|. |
| The cursor is still moved to the first line of the |
| range, as is the case with all Ex commands. |
| *:func-abort* |
| When the [abort] argument is added, the function will |
| abort as soon as an error is detected. |
| *:func-dict* |
| When the [dict] argument is added, the function must |
| be invoked through an entry in a |Dictionary|. The |
| local variable "self" will then be set to the |
| dictionary. See |Dictionary-function|. |
| *:func-closure* *E932* |
| When the [closure] argument is added, the function |
| can access variables and arguments from the outer |
| scope. This is usually called a closure. In this |
| example Bar() uses "x" from the scope of Foo(). It |
| remains referenced even after Foo() returns: > |
| :function! Foo() |
| : let x = 0 |
| : function! Bar() closure |
| : let x += 1 |
| : return x |
| : endfunction |
| : return funcref('Bar') |
| :endfunction |
| |
| :let F = Foo() |
| :echo F() |
| < 1 > |
| :echo F() |
| < 2 > |
| :echo F() |
| < 3 |
| |
| *function-search-undo* |
| The last used search pattern and the redo command "." |
| will not be changed by the function. This also |
| implies that the effect of |:nohlsearch| is undone |
| when the function returns. |
| |
| *:endf* *:endfunction* *E126* *E193* *W22* *E1151* |
| :endf[unction] [argument] |
| The end of a function definition. Best is to put it |
| on a line by its own, without [argument]. |
| |
| [argument] can be: |
| | command command to execute next |
| \n command command to execute next |
| " comment always ignored |
| anything else ignored, warning given when |
| 'verbose' is non-zero |
| The support for a following command was added in Vim |
| 8.0.0654, before that any argument was silently |
| ignored. |
| |
| To be able to define a function inside an `:execute` |
| command, use line breaks instead of |:bar|: > |
| :exe "func Foo()\necho 'foo'\nendfunc" |
| < |
| *:delf* *:delfunction* *E131* *E933* *E1084* |
| :delf[unction][!] {name} |
| Delete function {name}. |
| {name} can also be a |Dictionary| entry that is a |
| |Funcref|: > |
| :delfunc dict.init |
| < This will remove the "init" entry from "dict". The |
| function is deleted if there are no more references to |
| it. |
| With the ! there is no error if the function does not |
| exist. |
| *:retu* *:return* *E133* |
| :retu[rn] [expr] Return from a function. When "[expr]" is given, it is |
| evaluated and returned as the result of the function. |
| If "[expr]" is not given, the number 0 is returned. |
| When a function ends without an explicit ":return", |
| the number 0 is returned. |
| In a :def function *E1095* is given if unreachable |
| code follows after the `:return`. |
| In legacy script there is no check for unreachable |
| lines, thus there is no warning if commands follow |
| `:return`. |
| |
| If the ":return" is used after a |:try| but before the |
| matching |:finally| (if present), the commands |
| following the ":finally" up to the matching |:endtry| |
| are executed first. This process applies to all |
| nested ":try"s inside the function. The function |
| returns at the outermost ":endtry". |
| |
| *function-argument* *a:var* |
| An argument can be defined by giving its name. In the function this can then |
| be used as "a:name" ("a:" for argument). |
| *a:0* *a:1* *a:000* *E740* *...* |
| Up to 20 arguments can be given, separated by commas. After the named |
| arguments an argument "..." can be specified, which means that more arguments |
| may optionally be following. In the function the extra arguments can be used |
| as "a:1", "a:2", etc. "a:0" is set to the number of extra arguments (which |
| can be 0). "a:000" is set to a |List| that contains these arguments. Note |
| that "a:1" is the same as "a:000[0]". |
| *E742* *E1090* |
| The a: scope and the variables in it cannot be changed, they are fixed. |
| However, if a composite type is used, such as |List| or |Dictionary| , you can |
| change their contents. Thus you can pass a |List| to a function and have the |
| function add an item to it. If you want to make sure the function cannot |
| change a |List| or |Dictionary| use |:lockvar|. |
| |
| It is also possible to define a function without any arguments. You must |
| still supply the () then. |
| |
| It is allowed to define another function inside a function body. |
| |
| *optional-function-argument* |
| You can provide default values for positional named arguments. This makes |
| them optional for function calls. When a positional argument is not |
| specified at a call, the default expression is used to initialize it. |
| This only works for functions declared with `:function` or `:def`, not for |
| lambda expressions |expr-lambda|. |
| |
| Example: > |
| function Something(key, value = 10) |
| echo a:key .. ": " .. a:value |
| endfunction |
| call Something('empty') "empty: 10" |
| call Something('key', 20) "key: 20" |
| |
| The argument default expressions are evaluated at the time of the function |
| call, not definition. Thus it is possible to use an expression which is |
| invalid the moment the function is defined. The expressions are also only |
| evaluated when arguments are not specified during a call. |
| *none-function_argument* |
| You can pass |v:none| to use the default expression. Note that this means you |
| cannot pass v:none as an ordinary value when an argument has a default |
| expression. |
| |
| Example: > |
| function Something(a = 10, b = 20, c = 30) |
| endfunction |
| call Something(1, v:none, 3) " b = 20 |
| < |
| *E989* |
| Optional arguments with default expressions must occur after any mandatory |
| arguments. You can use "..." after all optional named arguments. |
| |
| It is possible for later argument defaults to refer to prior arguments, |
| but not the other way around. They must be prefixed with "a:", as with all |
| arguments. |
| |
| Example that works: > |
| :function Okay(mandatory, optional = a:mandatory) |
| :endfunction |
| Example that does NOT work: > |
| :function NoGood(first = a:second, second = 10) |
| :endfunction |
| < |
| When not using "...", the number of arguments in a function call must be at |
| least equal to the number of mandatory named arguments. When using "...", the |
| number of arguments may be larger than the total of mandatory and optional |
| arguments. |
| |
| *local-variables* |
| Inside a function local variables can be used. These will disappear when the |
| function returns. Global variables need to be accessed with "g:". |
| Inside functions local variables are accessed without prepending anything. |
| But you can also prepend "l:" if you like. This is required for some reserved |
| names, such as "count". |
| |
| Example: > |
| :function Table(title, ...) |
| : echohl Title |
| : echo a:title |
| : echohl None |
| : echo a:0 .. " items:" |
| : for s in a:000 |
| : echon ' ' .. s |
| : endfor |
| :endfunction |
| |
| This function can then be called with: > |
| call Table("Table", "line1", "line2") |
| call Table("Empty Table") |
| |
| To return more than one value, return a |List|: > |
| :function Compute(n1, n2) |
| : if a:n2 == 0 |
| : return ["fail", 0] |
| : endif |
| : return ["ok", a:n1 / a:n2] |
| :endfunction |
| |
| This function can then be called with: > |
| :let [success, div] = Compute(102, 6) |
| :if success == "ok" |
| : echo div |
| :endif |
| < |
| ============================================================================== |
| |
| 2. Calling a function ~ |
| *:cal* *:call* *E107* |
| :[range]cal[l] {name}([arguments]) |
| Call a function. The name of the function and its arguments |
| are as specified with `:function`. Up to 20 arguments can be |
| used. The returned value is discarded. |
| In |Vim9| script using `:call` is optional, these two lines do |
| the same thing: > |
| call SomeFunc(arg) |
| SomeFunc(arg) |
| < Without a range and for functions that accept a range, the |
| function is called once. When a range is given the cursor is |
| positioned at the start of the first line before executing the |
| function. |
| When a range is given and the function doesn't handle it |
| itself, the function is executed for each line in the range, |
| with the cursor in the first column of that line. The cursor |
| is left at the last line (possibly moved by the last function |
| call). The arguments are re-evaluated for each line. Thus |
| this works: |
| *function-range-example* > |
| :function Mynumber(arg) |
| : echo line(".") .. " " .. a:arg |
| :endfunction |
| :1,5call Mynumber(getline(".")) |
| < |
| The "a:firstline" and "a:lastline" are defined anyway, they |
| can be used to do something different at the start or end of |
| the range. |
| |
| Example of a function that handles the range itself: > |
| |
| :function Cont() range |
| : execute (a:firstline + 1) .. "," .. a:lastline .. 's/^/\t\\ ' |
| :endfunction |
| :4,8call Cont() |
| < |
| This function inserts the continuation character "\" in front |
| of all the lines in the range, except the first one. |
| |
| When the function returns a composite value it can be further |
| dereferenced, but the range will not be used then. Example: > |
| :4,8call GetDict().method() |
| < Here GetDict() gets the range but method() does not. |
| |
| *E117* |
| When a function cannot be found the error "E117: Unknown function" will be |
| given. If the function was using an autoload path or an autoload import and |
| the script is a |Vim9| script, this may also be caused by the function not |
| being exported. |
| |
| *E132* |
| The recursiveness of user functions is restricted with the |'maxfuncdepth'| |
| option. |
| |
| It is also possible to use `:eval`. It does not support a range, but does |
| allow for method chaining, e.g.: > |
| eval GetList()->Filter()->append('$') |
| |
| A function can also be called as part of evaluating an expression or when it |
| is used as a method: > |
| let x = GetList() |
| let y = GetList()->Filter() |
| |
| ============================================================================== |
| |
| 3. Cleaning up in a function ~ |
| *:defer* |
| :defer {func}({args}) Call {func} when the current function is done. |
| {args} are evaluated here. |
| |
| Quite often a command in a function has a global effect, which must be undone |
| when the function finishes. Handling this in all kinds of situations can be a |
| hassle. Especially when an unexpected error is encountered. This can be done |
| with `try` / `finally` blocks, but this gets complicated when there is more |
| than one. |
| |
| A much simpler solution is using `defer`. It schedules a function call when |
| the function is returning, no matter if there is an error. Example: > |
| func Filter(text) abort |
| call writefile(a:text, 'Tempfile') |
| call system('filter < Tempfile > Outfile') |
| call Handle('Outfile') |
| call delete('Tempfile') |
| call delete('Outfile') |
| endfunc |
| |
| Here 'Tempfile' and 'Outfile' will not be deleted if something causes the |
| function to abort. `:defer` can be used to avoid that: > |
| func Filter(text) abort |
| call writefile(a:text, 'Tempfile') |
| defer delete('Tempfile') |
| defer delete('Outfile') |
| call system('filter < Tempfile > Outfile') |
| call Handle('Outfile') |
| endfunc |
| |
| Note that deleting "Outfile" is scheduled before calling system(), since it |
| can be created even when `system()` fails. |
| |
| The deferred functions are called in reverse order, the last one added is |
| executed first. A useless example: > |
| func Useless() abort |
| for s in range(3) |
| defer execute('echomsg "number ' .. s .. '"') |
| endfor |
| endfunc |
| |
| Now `:messages` shows: |
| number 2 |
| number 1 |
| number 0 |
| |
| Any return value of the deferred function is discarded. The function cannot |
| be followed by anything, such as "->func" or ".member". Currently `:defer |
| GetArg()->TheFunc()` does not work, it may work in a later version. |
| |
| Errors are reported but do not cause aborting execution of deferred functions. |
| |
| No range is accepted. The function can be a partial with extra arguments, but |
| not with a dictionary. *E1300* |
| |
| ============================================================================== |
| |
| 4. Automatically loading functions ~ |
| *autoload-functions* |
| When using many or large functions, it's possible to automatically define them |
| only when they are used. There are two methods: with an autocommand and with |
| the "autoload" directory in 'runtimepath'. |
| |
| In |Vim9| script there is also an autoload mechanism for imported scripts, see |
| |import-autoload|. |
| |
| |
| Using an autocommand ~ |
| |
| This is introduced in the user manual, section |51.4|. |
| |
| The autocommand is useful if you have a plugin that is a long Vim script file. |
| You can define the autocommand and quickly quit the script with `:finish`. |
| That makes Vim startup faster. The autocommand should then load the same file |
| again, setting a variable to skip the `:finish` command. |
| |
| Use the FuncUndefined autocommand event with a pattern that matches the |
| function(s) to be defined. Example: > |
| |
| :au FuncUndefined BufNet* source ~/vim/bufnetfuncs.vim |
| |
| The file "~/vim/bufnetfuncs.vim" should then define functions that start with |
| "BufNet". Also see |FuncUndefined|. |
| |
| |
| Using an autoload script ~ |
| *autoload* *E746* |
| This is introduced in the user manual, section |52.2|. |
| |
| Using a script in the "autoload" directory is simpler, but requires using |
| exactly the right file name. A function that can be autoloaded has a name |
| like this: > |
| |
| :call filename#funcname() |
| |
| These functions are always global, in Vim9 script "g:" needs to be used: > |
| :call g:filename#funcname() |
| |
| When such a function is called, and it is not defined yet, Vim will search the |
| "autoload" directories in 'runtimepath' for a script file called |
| "filename.vim". For example "~/.vim/autoload/filename.vim". That file should |
| then define the function like this: > |
| |
| function filename#funcname() |
| echo "Done!" |
| endfunction |
| |
| The file name and the name used before the # in the function must match |
| exactly, and the defined function must have the name exactly as it will be |
| called. In Vim9 script the "g:" prefix must be used: > |
| function g:filename#funcname() |
| |
| or for a compiled function: > |
| def g:filename#funcname() |
| |
| It is possible to use subdirectories. Every # in the function name works like |
| a path separator. Thus when calling a function: > |
| |
| :call foo#bar#func() |
| |
| Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'. |
| |
| This also works when reading a variable that has not been set yet: > |
| |
| :let l = foo#bar#lvar |
| |
| However, when the autoload script was already loaded it won't be loaded again |
| for an unknown variable. |
| |
| When assigning a value to such a variable nothing special happens. This can |
| be used to pass settings to the autoload script before it's loaded: > |
| |
| :let foo#bar#toggle = 1 |
| :call foo#bar#func() |
| |
| Note that when you make a mistake and call a function that is supposed to be |
| defined in an autoload script, but the script doesn't actually define the |
| function, you will get an error message for the missing function. If you fix |
| the autoload script it won't be automatically loaded again. Either restart |
| Vim or manually source the script. |
| |
| Also note that if you have two script files, and one calls a function in the |
| other and vice versa, before the used function is defined, it won't work. |
| Avoid using the autoload functionality at the toplevel. |
| |
| In |Vim9| script you will get error *E1263* if you define a function with |
| a "#" character in the name. You should use a name without "#" and use |
| `:export`. |
| |
| Hint: If you distribute a bunch of scripts you can pack them together with the |
| |vimball| utility. Also read the user manual |distribute-script|. |
| |
| |
| vim:tw=78:ts=8:noet:ft=help:norl: |