Vim Tips Wiki
Tip 1601 Printable Monobook Previous Next

created 2008 · complexity basic · author Mahlonsmith · version 7.0

If you're a plugin developer, your plugin has multiple files (which should be the case since you're distributing documentation too, right?), and want to distribute everything as a nice little bundled package, then you should become familar with Charles Campbell's VimBall plugin.

You can use a Makefile and a series of Vim commands to automatically update your project's vimball on changes, for a sort of poor-man Vim automated build.

The Makefile should look something like this:

PLUGIN = specky

SOURCE = syntax/rdoc.vim
SOURCE += syntax/specrun.vim
SOURCE += doc/specky.txt
SOURCE += plugin/specky.vim

${PLUGIN}.vba: ${SOURCE}
	vim --cmd 'let g:plugin_name="${PLUGIN}"' -s build.vim

	rsync -Rv ${SOURCE} ${HOME}/.vim/

	rm ${PLUGIN}.vba

Include each file that is part of your plugin as a SOURCE line. (This example is from the specky plugin.)

The 'vim -s build.vim' command loads Vim directives from a file. Here's the file I use to create the Vimball.

:let g:vimball_home = "."
:e Makefile
:execute '%MkVimball!' . g:plugin_name

This says to parse the SOURCE lines out of the Makefile, and feed them to a vimball. The resulting file (in this example) will be called "specky.vba". As you add (or remove) files, you can just update the Makefile -- no need to change anything else.

In this fashion, as you update your code, you can just type "make", and have a packaged up Vimball that is ready for distribution.


Since all the commands in build.vim are ex-commands, you could source it with -S rather than -s, and dispense with the colons at the start of all lines. I would move the last command (to close Vim) out of the script and to a -cq! argument at the end of the command line though, to make the script easier to run from within a running Vim.

--Tonymec 01:57, September 11, 2009 (UTC)

If the ${SOURCE} variable uses any substitution (anything more complicated than one file per line, in fact), the version of build.vim given above won't work. The Makefile can take care of the substitutions itself with this alternate build.vim:

let g:vimball_home = "."
:%s/ /^V^M/g
:execute '%MkVimball!' . g:plugin_name

(Note that ^V and ^M are the escape sequences created by pressing <ctrl>-V <ctrl>-V and <ctrl>-V <ctrl>-M.)

The Makefile should then use

${PLUGIN}.vba: ${SOURCE}
	@echo "${SOURCE}" | vim --cmd 'let g:plugin_name="${PLUGIN}"' - -s ../build.vim

--Pconley 00:47, March 1, 2012 (UTC)

Since Vim is a command here, in a Makefile, and not used as a text editor, you may want to avoid the Vim window alltogether, so your Makefile runs smoothly (see also Vim as a system interpreter for vimscript).

For this you should use:

  • -e for ex mode (that is, command mode)
  • -s for silent (batch) mode

Ex mode will also make Vim return a non-zero status if anything goes wrong, which is expected in a Makefile.

Silent mode, other than preventing the window from showing up, also has two other effects:

  • skips vimrc initialization, and as a side effect Vim stays in 'compatible' mode, which you are not going to like. So include the nocompatible -N option explicitly. This will among other things make Vim load the system addons, too, which we happen to need in here, to get the %MkVimball command.
  • prevents messages from being output, including errors, which is likely to get you confused. For that, set 'verbose' to non-zero, either with:
    • :set verbose=1 in the build.vim script
    • -V1 on the vim command line

I also believe the quit command should be moved out of the script, and that a few other options would help for this sort of usage:

  • -n, do not write a swap file
  • -u NORC, do not read the .vimrc and .gvimrc files (though redundant with the -s switch)
  • -i NONE, do not use a viminfo file

So the resulting command would look like:

vim -u NORC -i NONE -V1 -nNesS build.vim -c 'echo "" | qall!'

On Linux or cygwin, most of these options can also be set in a shebang line at the start of the script, like this:

#!/usr/bin/vim -nNesS

set verbose=1
set viminfo=
: script..

And you can run the build script as:


Now the script includes everything, and there are no special options to be included on the command line. Experience the power of Vim ! :)

The build script must be made executable. Anyway I at this point I still prefer the explicit command line, however, that keeps the script content away from user settings and from that quit command.

The shebang line is still good in this regard, since it is ignored as a vim script command, but it can not include all the needed options, more importantly, -V1. Well, it can actually, but only if you are willing to write something clever like:

#!/usr/bin/vim -nNesc :set verbose=1|set viminfo=|source %|echo "" |qall!

: ...vim ex cmds...

As funny as it looks, it will work and will turn vim into a command-line script interpreter (with no window) and run the script with all the needed options.

On Windows there is no shebang line, and the potential equivalent is not as nice. You may want to use:

Assoc .exim=VimCmdScript
FType VimCmdScript="C:\Program Files\Vim\Vim73\vim.exe" -V1 -i NONE -u NORC -U NONE -nNesS % -c "echo \"\" | qall!"

in a cmd window to achieve a similar effect, and you only need to invoke that once. Note this will make 'run' to be the default action when double-clicking an .exim script. This setting will also require admin privileges, because it takes effect system wide. See Vim_as_a_system_interpreter_for_vimscript and Windows_file_associations for details, and also how to do this on a per-user basis without admin rights.

--terminatorul 05:28, Sep 13, 2012 (UTC)

Alternative tools to create vimballs[]

  • mkvimball: Written in C (by the creator of vimball.vim Charles E Campbell)
  • vimball.rb: Written in ruby