SnipMate aims to provide support for textual snippets, similar to TextMate or
other Vim plugins like UltiSnips. For
example, in C, typing for<tab>
could be expanded to
for (i = 0; i < count; i++) {
/* code */
}
with successive presses of tab jumping around the snippet.
Originally authored by Michael Sanders, SnipMate was forked in 2011 after a stagnation in development. This fork is currently maintained by Rok Garbas, Marc Weber, and Adnan Zafar.
SnipMate can be installed using a package manager or using Vim's built-in package handling. It does depend on vim-addon-mw-utils and optionally tlib. For example, to use Vim's built-in support,
% mkdir -p ~/.vim/pack/SnipMate/start
% cd ~/.vim/pack/SnipMate/start
% git clone https://github.com/garbas/vim-snipmate.git
% git clone https://github.com/MarcWeber/vim-addon-mw-utils.git
# Optional:
% git clone https://github.com/tomtom/tlib_vim.git
% git clone https://github.com/honza/vim-snippets.git
NOTE: SnipMate does not ship with any snippets out of the box. We suggest looking at the vim-snippets repository.
If tlib is enabled, it is used for multisnip (:h SnipMate-multisnip
). It's
also required for the :SnipMateOpenSnippetFiles
command.
Remember to run :helptags ALL
once your Vim has loaded SnipMate!
Install and create some snippets (see :h SnipMate-snippets
). Then type in the
trigger for one in the correct filetype and hit the expansion key (by default
bound to <Tab>
).
SnipMate doesn't work / My snippets aren't triggering
Try all of the following:
-
Check that SnipMate is loaded. This can be done by looking for
<Plug>snipMateTrigger
and similar maps in the output of:imap
. Additionally make sure either<Plug>snipMateTrigger
or<Plug>snipMateNextOrTrigger
is mapped to the key you expect. -
Check that the snippets file you mean to use exists, and that it contains the snippet you're trying to expand.
-
Check that your snippets file is located inside a
foo/snippets
directory, wherefoo
is a path listed in yourruntimepath
. -
Check that your snippets file is in scope by either the filetype matching the path of the snippet file or the scope explicitly loaded.
-
Check if any snippets from your snippets file are available. This can be done with the "show available snips" map, by default bound to
<C-R><Tab>
in insert mode.
If all of the above check out, please open an issue stating your Vim version, a sample snippet, and a description of exactly what happens when you try to trigger a snippet.
How does SnipMate determine which snippets to load? How can I separate, for example, my Rails snippets from my Ruby snippets?
Primarily SnipMate looks at the 'filetype'
and 'syntax'
settings. Taking
"scopes" from these options, it looks in each snippets/
directory in
'runtimepath'
for files named scope.snippets
, scope/*.snippets
, or
scope_*.snippets
.
However we understand this may not allow for the flexibility desired by some
languages. For this we provide two options: scope aliases and the
:SnipMateLoadScope
command. Scope aliases simply say "whenever this scope is
loaded, also load this other scope:
let g:snipMate = get(g:, 'snipMate', {}) " Allow for vimrc re-sourcing
let g:snipMate.scope_aliases = {}
let g:snipMate.scope_aliases['ruby'] = 'ruby,rails'
will load the ruby-rails
scope whenever the ruby
scope is active. The
:SnipMateLoadScope foo
command will always load the foo scope in the current
buffer. The vim-rails plugin automatically
does :SnipMateLoadScope rails
when editing a Rails project for example.
What are the snippet parser versions and what's the difference between them?
Originally SnipMate used regex to parse a snippet. Determining where stops were, what the placeholders were, where mirrors were, etc. were all done with regex. Needless to say this was a little fragile. When the time came for a rewritten parser, some incompatibilities were a little necessary. Rather than break everyone's snippets everywhere, we provided both the new (version 1) and the old (version 0) and let the user choose between them.
Version 0 is considered legacy and not a lot of effort is going to go into
improving or even maintaining it. Version 1 is the future, and one can expect
new features to only exist for version 1 users. A full list of differences can
be found in the docs at :h SnipMate-parser-versions
.
Some changes listed here were contributed by non-maintainers. A full list can be found at Contributors.md.
- Make tlib an optional dependency.
- Add SnipLookupPre and SnipLookupPost autocommand events
- Make version 1 of the snippet parser the default with no message
- Remove empty lines at the end of a
${VISUAL}
expansion - Fix code for opening folds when expanding a snippet
- Deprecate legacy snippet parser
- Fix jumps when
&sel == 'exclusive'
- Various regex updates to legacy parser
- Addition of double bang syntax to completely remove a snippet from lookup
- Group various SnipMate autocommands
- Support setting 'shiftwidth' to 0
- Parser now operates linewise, adding some flexibility
- Mirror substitutions are more literal
- Mirror length is calculated correctly when substitutions occur
-
Implement simple caching
-
Remove expansion guards
-
Add
:SnipMateLoadScope
command and buffer-local scope aliases -
Load
<scope>_*.snippets
files -
Use CursorMoved autocmd events entirely
-
The nested branch has been merged
- A new snippet parser has been added. The g:snipmate.version as well as version lines in snippet files determines which is used
- The new parser supports tab stops placed within placeholders, substitutions, non-consecutive stop numbers, and fewer ambiguities
- The stop jumping code has been updated
- Tests have been added for the jumping code and the new parser
-
The override branch has been merged
- The g:snipMate.override option is added. When enabled, if two snippets share the same name, the later-loaded one is kept and the other discarded
- Override behavior can be enabled on a per-snippet basis with a bang (!) in the snippet file
- Otherwise, SnipMate tries to preserve all snippets loaded
-
Fix bug with mirrors in the first column
-
Fix bug with tabs in indents (#143)
-
Fix bug with mirrors in placeholders
-
Fix reading single snippet files
-
Fix the use of the visual map at the end of a line
-
Fix expansion of stops containing only the zero tab stop
-
Remove select mode mappings
-
Indent visual placeholder expansions and remove extraneous lines (#177 and #178)
- Stop indenting empty lines when expanding snippets
- Support extends keyword in .snippets files
- Fix visual placeholder support
- Add zero tabstop support
- Support negative 'softtabstop'
- Add g:snipMate_no_default_aliases option
- Add snipMateTrigger for triggering an expansion inside a snippet
- Add snipMate#CanBeTriggered() function