vim Functions


  • Don't forget the bang to allow Vim to overwrite that function next time you reload the script where the function is defined.
  • Custom functions must start either with an uppercase character (global functions), or with s: (script local functions), or they must be prefixed with the name associated to the autoload plugin where they are defined (e.g. in {&rtp}/autoload/foo/bar.vim we could define foo#bar#functionname()).
  • To be able to use the parameters in the function, use a:parameter_name. Variadic functions can be defined with the ellipsis ..., to access the parameters use a:000 (list of all parameters), or a:0 (number of parameters equal to len(a:000)), a:1 first unnamed parameters, and so on.
  • Functions can be called like so: :call MyFunction(param1, param2)
  • Every line in a function implicitly begins with a :, thus all the commands are colon commands
  • To prevent the function from continuing its execution in case of error, it's best to annotate the function signature with abort


function! MyFunction(foo, bar, ... ) abort
    return a:foo . a:bar . (a:0 > 0 ? a:1 : '')

Script functions

If you only plan on using your function in the file where it's defined (either because you've broken a bigger function in smaller parts, or because you'll use it in a command, a mapping, ...), you can prefix it with s:, avoiding littering your global namespace with useless internal functions:

function! s:my_private_function() " note we don't need to capitalize the first letter this time
    echo "Hi!"

Using s:functions from mappings

If your script local function is going to be used in a mapping, you need to reference it using the special <SID> prefix:

nnoremap <your-mapping-key> :call <SID>my_private_function()<CR>

See :help user-functions.

Note however, that since Vim 7, it's considered a best practice to define mappings abbreviations, commands and menus in (ft)plugins, and defining functions in autoload plugins -- except the functions the plugins need to use when they're loaded. This means that nowadays the need to call scripts local functions from mappings is not as pertinent as what it used to be.