-
Notifications
You must be signed in to change notification settings - Fork 41
Creating Vim Plugins with Maktaba
- The Basics
- Points of Style
- Plugin Metadata
- Plugin Files
- Configuration with Glaive
- Commands, Autocmds, and Mappings
- Tests
- Documentation
A maktaba plugin is a directory of vim files with basically the same file structure as any vim plugin:
myplugin/ addon-info.json ← Declares plugin metadata and dependencies (See Plugin Metadata) instant/ flags.vim ← Defines all flags (See Configuration with Glaive) plugin/ settings.vim ← Configures vim setting values commands.vim ← Defines all commands autocmds.vim ← Defines all autocmds mappings.vim ← Defines all mappings stuff.vim morestuff.vim autoload/ myplugin.vim myplugin/ morestuff.vim doc/ myplugin.txt ← Usually generated using Vimdoc tags ← Generated by vim’s `:helptags` command vroom/ main.vroom ← Vroom test / executable documentation morestuff.vroom ftplugin/ syntax/ …
Each file under myplugin/plugin/
and myplugin/instant/
should contain this boilerplate verbatim at the top:
let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>:p'))
if !s:enter
finish
endif
(This prevents double-sourcing and helps make your plugin more configurable. See Plugin Files for more details.)
Any flags, commands, autocmds, or mappings your plugin defines should be defined in their respective plugin/
files as indicated in the file structure above.
The plugin can now be loaded with:
call maktaba#plugin#GetOrInstall('myplugin')
That’s basically all that’s required of a maktaba plugin. Existing plugins can be converted to maktaba plugins simply by ensuring the files are laid out in the right structure and that the plugin/
files contains the boilerplate above.
The rest is about making use of the full power of maktaba (especially Glaive) and adhering to some style guidelines to avoid common vimscript pitfalls.
Vimscript is just full of gotchas. Will your plugin still work properly if users set ignorecase
or nomagic
? Will it confuse users by overriding their commands and mappings, or crash if vim sources your file twice? Can users disable features that annoy them without uninstalling your whole plugin?
Making full use of the maktaba framework helps avoid several mistakes. You should also familiarize yourself with the Vimscript Style Guide and the Full Vimscript Guide to avoid many other common pitfalls. Another great resource is Steve Losh’s book Learn Vimscript the Hard Way, which is available for free online.
## Plugin MetadataEvery plugin should include an addon-info.json
file with at least the following:
{
"name": "myplugin",
"dependencies": {
"maktaba": {"type": "git", "url": "git://github.com/google/maktaba"}
}
}
This allows plugin managers to satisfy plugin dependencies, and helps maktaba to detect the plugin directory as a plugin, as opposed to just a miscellaneous directory of runtime files on the runtimepath.
See the VAM-addon-info section in the VAM documentation for more information on the addon-info.json
spec.
Maktaba has some special conventions for files under plugin/
, but there’s nothing fundamentally different about them and any old file under plugin/
should continue to work as expected.
In general, files under plugin/
should expect to be sourced once and only once. Some shouldn’t even be sourced at all if the user opts to explicitly disable them. To give maktaba control to exit early and forbid reentry, each plugin/
file should start with the following boilerplate:
let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>:p'))
if !s:enter
finish
endif
A few filenames are special and maktaba will explicitly source them in some cases if vim hasn’t automatically sourced them yet.
Maktaba integrates with a system for powerful user configuration called Glaive. Generally, maktaba plugins should avoid relying on global variables for configuration, and instead manage their configuration as Glaive flags.
Glaive flags have several advantages for users and for plugin developers:
- A concise, readable format for users to specify configuration
- Short names that don’t collide with flags in other plugins (every flag is namespaced under the plugin name)
- Powerful operations like
+=
that can be deferred until the flag is initialized - Less boilerplate for accessing and modifying flag values
- Automatically documented by Vimdoc
To use Glaive flags, define them in your instant/flags.vim
file:
call s:plugin.Flag('sayhello', 1)
call s:plugin.Flag('name', 'Whoever you are')
and access them from autoload files or other code via maktaba#plugin#Get
:
let s:plugin = maktaba#plugin#Get('myplugin')
if s:plugin.Flag('sayhello')
" Say hello unless user has explicitly disabled it.
endif
Users can configure Glaive flags in their .vimrc
after they load maktaba with:
Glaive myplugin !sayhello name='George'
A flag value can be a number, string, list, or dict. See the Glaive documentation for more information.
NOTE: instant/flags.vim
will be automatically sourced when you first try to read a flag value for your plugin, so in general you can use flags from autoload, autocmd, and other special contexts without worrying about whether they’re defined yet.
Maktaba plugins should define any commands, autocmds, and mappings in their respective plugin/
file.
plugin/commands.vim
" ...
command DoSomething call myplugin#DoSomething()
plugin/autocmds.vim
" ...
augroup myplugin
autocmd!
autocmd BufWritePre * DoSomething
augroup END
plugin/mappings.vim
" ...
let s:prefix = s:plugin.MapPrefix('m')
execute 'nnoremap <unique> <silent>' s:prefix . 's' :DoSomething<CR>
Maktaba provides a special dict flag for each plugin called plugin
, which the user can configure to selectively disable features. For example, a user who doesn’t like the default autocmds could configure your plugin with
Glaive myplugin !plugin[autocmds]
and then the maktaba#plugin#Enter
boilerplate would prevent the autocmds from being loaded at all.
Plugins can be tested using the Vroom testing system. Vroom tests are part executable test, part walkthrough-style documentation. Vroom is not part of maktaba, but all maktaba plugins should define at least a basic test that loads the plugin, so that you have an automated way to detect initialization errors:
:call maktaba#plugin#GetOrInstall('myplugin')
All maktaba plugins should include some help files under the doc/
directory, typically at doc/myplugin.txt
. These files can be generated using Vimdoc, which scans your plugins for doc comments starting with the vimdoc leader:
"" This is a vimdoc comment
and creates high-quality vim help files.
All flags, public functions, commands, and autocmds should have vimdoc comments so they’re included in the generated help files.
See the Vimdoc documentation for more information.