created October 24, 2003 · complexity intermediate · author Jean-Christophe Clavier · version 6.0
Are you tired of hundreds of mappings and functions that pollute your vimrc? Do you want to nicely organize your customization to quickly find what you search ? Perhaps is it time for you to consider the use of plugins (if it is not already done).
Plugins are really easy to do and provide a simple way to organize functions and mappings. They are automatically loaded.
Here is an example of simple and very short plugin that provides a command :MyCommand that saves the selected text in the file passed in parameter. I don't know if the function is useful but the example show the parameter passing, the autocompletion and the use of ranges in a function.
Autocompletion is very practical to help to remember the commands you defined. It is often a problem to remember all the mappings you've done so it may be faster to type your command than to remember the mapping you've chosen.
Using user-commands allows you to use mappings only when it is absolutely pertinent.
" file MyPlugin.vim " save 'cpo' let s:cpo_save = &cpo set cpo&vim " To Edit the Plugin nnoremap <F12> :e $VIMRUNTIME/plugins/MyPlugin.vim " To reload the plugin if you modify it nnoremap <S-F12> :so $VIMRUNTIME/plugins/MyPlugin.vim " It is very interesting to define commands to call your functions because you can then use " autocompletion and other features you cannot use for usual functions if !exists(':MyCommand') command -range=% -nargs=1 -complete=file MyCommand <line1>,<line2>call s:MyCommandFunction(<f-args>) endif " the ! allows you to modify the function and reload the plugin. It will be your new version that " will be considered function! s:MyCommandFunction(...) range split execute "norm! " . a:firstline . "GV" execute "norm! " . a:lastline . 'G"ay' enew norm! "ap exe "sav! " . a:1 q endfunction " restore 'cpo' let &cpo = s:cpo_save unlet s:cpo_save
Commented version of the function:
function! s:MyCommandFunction(...) range " create a temporary window split " select and copy the lines in the range passed (a:firstline and a:lastline are the vim " variables for the first and the last lien of the range) execute "norm! " . a:firstline . "GV" execute "norm! " . a:lastline . 'G"ay' " create a new file and paste enew norm! "ap " saves the file with the name passed in parameter " exe executes the string passed as a command " a:1 is the first parameter (if you have more, a:2, a:3. a:0 gives you the number of parameter " passed exe "sav! " . a:1 " quit the temporary window q endfunction
Of course you can separate your functions in different plugins (one for the mapping, one for the functions... You can use prefix to classify your functions and use the autocompletion more efficiently.
- General considerations on plugin: :help plugins
- How to create a user-command and how to use the parameters (-range, -nargs, -complete...): :help user-commands
- How to program vim: :help eval.txt
- All the buildin functions: :help functions
- How to define a function: :help user-functions
I definitively agree that plugins are a must -- AFAIK, ftplugins are the major improvment of Vim over Vi.
However, I have a few remarks:
- You forget the anti-reinclusion guards,
- You can propose a way to override the default mappings you propose in your plugin -- check VimTip147 that is a must-read
- You'd better always use ":normal!" and "*noremap" instead of ":normal" and ":*map". We are never sure of mappings defined into other plugins.
- If you want the exact path of the current plugin:
let s:file = expand('<sfile>:p') nnoremap <silent> <s-12> :silent exe 'source '.s:file
But a better solution is to rely on ":runtime". BTW, $VIMRUNTIME is not really meant to be polluted with our own scripts.