VIM plugin creation tutorial?

There are many ways to proceed.

A- You can write a simple script that contains the lines you want to execute, and invoke it manually. ex:

" $HOME/.vim/macros/foo.vim
:v/\S/d_
:update
" EOF

" and from vim
:runtime macros/foo.vim
" or
:so ~/.vim/macros/foo.vim

B- You can have a plugin that contains something that will trigger what you want to execute. If the action is a little bit complex, we usually prefer to define a function for maintenance purposes.

B.1. If the function is short enough and used every time you use vim, you can define it into your plugin.

B.1.1. If you prefer to invoke the function directly (usually never the case) with :call Foo(), you have to make it public by giving it a name that begins with a capital letter:

" ~/.vim/plugin/foo.vim
function! Foo()
    :v/\S/d_
    :update
endfunction

(That solution pollutes the global namespace, moreover other plugins may overrule it.)

B.1.2 Usually, we define either a mapping, or a command that will call the function. This way, the function can be made local to the current script -- its name starts with s:.

" ~/.vim/plugin/foo.vim
function! s:Foo()
    :v/\S/d_
    :update
endfunction

Now you can either define a command:

" ~/.vim/plugin/foo.vim
command! -nargs=0 Foo call s:Foo()

or a mapping:

" ~/.vim/plugin/foo.vim
" to call a script-local function from a mapping (defined in the same script!)
" we need to use <sid> instead of s:
nnoremap µ :call <sid>Foo()<cr>

" or the more "professional" way that permits other users to choose another 
" trigger for the mapping
nnoremap <Plug>Foo :call <sid>Foo()<cr>
if !hasmapto('<Plug>Foo', 'n')
    nmap µ <Plug>Foo
endif

" ~/.vimrc
" this way some users may bind the action to anything else in their .vimrc
" while the default mapping on µ is defined for the all the other users
:nmap <f11> <Plug>Foo

B.2. If the function is really long by itself, or because of the other functions it requires to accomplish its work, and/or if the function is seldom used, we prefer to define it in an autoload plugin:

" ~/.vim/autoload/yourinitials/foo.vim
" NB: I use my initials (lh) to avoid name clashes on common filenames
function! yourinitials#foo#bar()
   ....

and the call to the (public) function from the plugin is done using the ... function name:

" ~/.vim/plugin/foo.vim
command! -nargs=0 Foo call yourinitials#foo#bar()
nnoremap <Plug>Foo :call yourinitials#foo#bar()<cr>

Last notes:

We usually provide anti-inclusion guards on plugins (and ftplugins), but not on plain scripts nor on autoload plugins. This is because one may want to prevent, from their .vimrc, some plugins to be loaded. Remark: the plugin muTemplate I'm maintaining has skeletons for the different kinds of vim scripts.

However we may sometime want to reload one particular plugin we are maintaining in order to use/test/tune the (new) function(s) we are developing. In that case it is important that the functions and commands definitions are banged with a ! to permit their overriding.

Tags:

Vim

Script