Light at the end of the carpal tunnel: snippets in vim with snipMate
I’ve tried a number of snippet plugins for vim, many claiming more and less feature parity with the beloved TextMate. I started using snipMate today, and it is by far my favorite. If you haven’t seen TextMate-like snippets in action, check out this short video. If you weren’t a fan of snippets before, you should be now. They allow you to type a small piece of text that serves to remind you of the purpose and, once triggered, have it be replaced with blocks of text and code of all sorts.
So why choose snipMate for snippets? The main features:
- Easy to use
- Well documented
- Lots of snippets out of the box
- Simple to define your own snippets
- Easy to convert current TextMate snippets for snipMate use
- Marks aren’t added into the buffer, so if you change your mind and escape in the middle of finishing the snippet, you don’t have ugly “{<foo>}” placeholders in your code
- Variables are updated dynamically, so different parts of a snippet related to what you’re typing change as you type
- <Shift-Tab> goes backwards in the tabbed fields
Many of the other snippet plugins lack one or many of these characteristics, which are all quite valuable.
Setup
- Download the latest zip file into your ~/.vim directory and unzip it. This will place the plugin files, snippet files, and help files into the right places.
- Open a new instance of vim and run “:helptags ~/.vim/doc”. This will load snipMate’s help files for vim to access.
- The next time you open/restart vim you’ll be ready to go.
Conflicts
There’s one fly in this tabular ointment. <Tab> is a popular fellow, so snipMate’s use of it will likely conflict with other completion plugins. Perhaps your language-based code completion (see this post if you haven’t set this up before). In my case, all was good until I opened a Python file, wherein <Tab> after “class”, for example, brought up the word completion pop-up, not the desired snippet.
To get around this, I changed the trigger for code completion to <CTRL+n>, so both sets of functionality can be used. I find snippets more valuable than language completion, so I’d rather it be closer at hand.
Use and examples
To use a snippet, you simply type the appropriate term representing it and press <Tab>. The snippet is then placed at your current location. In many cases, you need to fill out part of the snippet to make it valid code. In these cases, you can simply tab through the locations you need or might want to edit, typing as you go. Once you tab past the last one, you are done.
.html file example, after typing “doct”, <Tab>, “html”, <Tab>, “head”, <Tab>:

Then you just type in the title, the rest is complete and indented already. A .py file example, after typing “cl”, <Tab>:

Roll your own
What really sold me on snipMate was how easy it was to define custom snippets. In some other snippet plugins I tried, the snippets were in a wretched format:
1 2 | exec "Snippet get def get_".st."name".et."(self):<CR>return self._".st."name".et."<CR>".st.et exec "Snippet set def set_".st."name".et."(self, ".st."value".et."): |
Not exactly easy on the eye. snipMate, however, is much more flexible. One place to start adding your own is in ~/.vim/snippets/_.snippets. This file is for snippets to be loaded for all filetypes. Here are a few useful ones I added to illustrate:
1 2 3 4 5 6 7 8 | snippet date `strftime("%Y-%m-%d")` snippet datetime `strftime("%Y-%m-%d %T %Z")` # My name and email snippet myinfo Author: `g:BASH_AuthorName` Email: `g:BASH_Email` |
Tabs and newlines can be used without escaping, and you have full access to vimscript. It gets even better once you need to be able to type in certain parts of the snippet:
1 2 3 4 | snippet def def ${1:fname}(${2:`indent('.') ? 'self' : ''`}): """${3:docstring for $1}""" ${4:pass} |
Each “${NUM}” represents a tab stop. In this example, typing “def” then <Tab> would bring up the snippet, with the cursor placed right after def, ready to be filled in. And the string after “${NUM:” acts as a reminding placeholder. In addition, “$NUM” can be used to refer to the content of previous entries, which allows dependent parts of a snippet to be updated as you type! After “def” and <Tab>, I only typed the function name once:

Multiple filetypes
One issue I ran into early on was wanting more than one filetype’s snippets available for a single file. In my case, I was editing a file with a .php extension, but it had a lot of HTML in it as well. Since the filetype is determined from the extension, I only had the snippets for PHP. To fix this, I added a file ~/.vim/ftdetect/php.vim, containing:
1 | au BufRead,BufNewFile *.php set filetype=php.html |
When a file with an extension matching a filename in ftdetect is opened, its filetype can be changed to whatever is desired via a directive like the one above. The dot separating the filetypes allows for multiple formats to be made available at once.
Useful customizations
I’ve been adding more snippets as I’ve needed them. Additions to ~/.vim/snippets/python.snippets:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | snippet sb #!/usr/bin/env python snippet sba #!/usr/bin/env python """${1} """ snippet docs """ File: `Filename('$1.py', 'foo.py')` Author: `g:BASH_AuthorName` Date: `strftime("%Y-%m-%d %T %Z")` Description: ${1} """ # Debugging snippet pdb import pdb; pdb.set_trace() snippet pudb import pudb; pudb.set_trace() |
And to ~/.vim/snippets/html.snippets:
1 2 3 4 | snippet img <img src="${1}" alt="${2:Helpful description}" />${3} snippet p <p>${1}</p> |
Aside from this, I also changed the names of several of the trigger words. If a needed snippet’s name isn’t intuitive to you, change it! The longer it takes you to recall the shortcut, the closer you are to typing the full form. To customize the terms, open the file appropriate to the language you are working inside of ~/.vim/snippets. Just search for the old term, replace it, save, and the next time you open vim your new trigger will be in place.
July 19, 2009 - 8:39 PM Comments (5)













