Created: 05 Oct 2013
These are some bits of vim configuration that have helped speed up both reading and writing puppet code.
I’ve described the way I install things using Ubuntu, but everything should be possible on other distributions and operating systems, if you understand their packaging systems.
I find colour highlighting to be useful. When reading a codebase it seems to help me read manifests quicker e.g. by highlighting the boundaries between variables and literal strings inside double quoted strings, or between resource names and parameters. When editing, it alerts me to the cases when I’ve missed out a quote to terminate a string.
I install and use the puppet plugin provided by the vim-puppet
ubuntu package
from the puppetlabs apt repo to match the version
of puppet I’m using. I then enable the addon for all users:
sudo vim-addons install -w puppet
If there aren’t any packages for your platform, the plugin resides within the puppet source with installation instructions.
Note: there is an alternative puppet plugin for vim with more features, such as automatic formatting and syntax checking.
These entries in ~/.vimrc
ensure that I have all the syntax highlighting on
and defines the preferred indentation of two spaces:
syntax on
au FileType puppet setlocal tabstop=8 expandtab shiftwidth=2 softtabstop=2
I use the ubuntu exuberant-ctags
package to generate tag files for vim to
read. Mac users, go
here.
To make ctags understand puppet’s syntax, I have the ~/.ctags
definition
from Paul Nasrat:
--langdef=puppet
--langmap=puppet:.pp
--regex-puppet=/^class[ \t]*([:a-zA-Z0-9_\-]+)[ \t]*/\1/d,definition/
--regex-puppet=/^site[ \t]*([a-zA-Z0-9_\-]+)[ \t]*/\1/d,definition/
--regex-puppet=/^node[ \t]*([a-zA-Z0-9_\-]+)[ \t]*/\1/d,definition/
--regex-puppet=/^define[ \t]*([:a-zA-Z0-9_\-]+)[ \t]*/\1/d,definition/
I then run ctags -R
in the base of the manifests directory to generate a tags
file.
There are two vim directives that make vim’s ctags support more useful. Firstly, this tells vim to look upwards in the directory hierarchy for a tags file until it finds one:
set tags=./tags;
This means that if, my current working directory is modules/web_server
, vim
will still find the tags
file I generated in the root of the puppet
manifests. The default behaviour is to look for a tags
file in the current
working directory.
The next directive helps vim properly parse class, define and variable names of the form ‘web_server::config’. By default ‘:’ will end a word, causing that qualified name to be treated as two words.
Adding this to .vimrc
causes vim to treat ‘:’ as part of the keyword for tag
navigation purposes.
au FileType puppet setlocal isk+=:
Now open a manifest with vim and hit Ctrl+]
to follow to the definition of a
class or define. Use Ctrl+T to jump back one level in the tag stack.
This is extremely useful in the case of a large set of manifests, especially one unfamiliar to you.
Finally, you’ll probably also want to exclude tags
from being noticed by your
revision control system.
When writing puppet manifests there can be a lot of semi-repetitive text entry; when defining a file for example, I set a minimum of four parameters in addition to the namevar.
file { '/etc/default/useradd':
content => template ('users/default/useradd.erb'),
owner => root,
group => root,
mode => 0644,
}
In order to speed this up a bit, I have SnipMate configured with snippets for puppet, based on those supplied by R.I.Pienaar, but with edits to suit my preferred style and additions to include local defines/classes that I use frequently.
And that’s pretty much it; it doesn’t require a lot of work to set up, but a worthwhile gain in efficiency when maintaining puppet code.
In a future blog post I’ll explain how I use puppet to install this config on all the machines I use regularly.