Yet another snippet extension
Table of Contents
1 Quick start
YASnippet is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates. Bundled language templates includes: C, C++, C#, Perl, Python, Ruby, SQL, LaTeX, HTML, CSS and more. The snippet syntax is inspired from TextMate's syntax, you can even import most TextMate snippets
YASnippet is an original creation of http://pluskid.lifegoo.org who also wrote its predecessor http://code.google.com/p/smart-snippet.
1.1 Watch a demo
On youtube.
1.2 Installation
Clone this repository somewhere
$ cd ~/.emacs.d/plugins $ git clone https://github.com/capitaomorte/yasnippet
Add the following in your .emacs
file:
(add-to-list 'load-path "~/.emacs.d/plugins/yasnippet") (require 'yasnippet) (yas-global-mode 1)
Add your own snippets to ~/.emacs.d/snippets
by placing files there or
invoking yas-new-snippet
.
1.3 Import textmate snippets (rails example)
YASnippet lets you use TextMate bundles directly:
$ cd ~/.emacs.d/plugins $ git clone https://github.com/capitaomorte/yasnippet $ cd yasnippet $ git submodule init $ git submodule update $ gem install plist trollop $ rake convert_bundles # will convert ruby, rails and html bundles from drnic
Then, in your .emacs
file
(add-to-list 'load-path "~/.emacs.d/plugins/yasnippet") (require 'yasnippet) (setq yas-snippet-dirs '("~/.emacs.d/snippets" "~/.emacs.d/extras/imported")) (yas-global-mode 1)
Open some rails file (model, app, etc) and start using the textmate snippets. Consider that this is a work-in-progress and many snippets/commands might not work. Patches welcome!
1.4 Contributing snippets
Please do not ask me to add snippets to the default collection under
/snippets
. This collection is considered frozen. By customizing
yas-snippet-dirs
you can point yasnippet to good
snippet collections out there.
The extras/textmate-import.rb
tool can import many actual Textmate
snippets. I'm focusing on developing it and the accompanying yas-setup.el
files that guide it with more difficult importations. The idea is to deprecate
/snippets
and replace it with extras/imported
.
1.5 Documentation, issues, etc
Please refer to the comprehensive documentation for full customization and support. If you think you've found a bug, please report it on the GitHub issue tracker. (please **do not** submit new issues to the old googlecode tracker)
If you run into problems using YASnippet, or have snippets to contribute, post to the yasnippet forum. Thank you very much for using YASnippet!
2 Organizing snippets
2.1 Basic structure
Snippet collections can be stored in plain text files. They are arranged by sub-directories naming snippet tables. These mostly name Emacs major names.
. |-- c-mode | `-- printf |-- java-mode | `-- println `-- text-mode |-- email `-- time
The collections are loaded into snippet tables which the triggering mechanism (see Expanding snippets) looks up and (hopefully) cause the right snippet to be expanded for you.
2.2 Setting up yas-snippet-dirs
The emacs variable yas-snippet-dirs
tells YASnippet
which collections to consider. It's used when you activate
yas-global-mode
or call
yas-reload-all
interactively.
The default considers:
- a personal collection that lives in
~/.emacs.d/snippets
- the bundled collection, taken as a relative path to
yasnippet.el
localtion
When you come across other snippet collections, do the following to try them out:
;; Develop in ~/emacs.d/mysnippets, but also ;; try out snippets in ~/Downloads/interesting-snippets (setq yas-snippet-dirs '("~/emacs.d/mysnippets" "~/Downloads/interesting-snippets")) ;; OR, keeping yasnippet's defaults try out ~/Downloads/interesting-snippets (setq yas-snippet-dirs (append yas-snippet-dirs '("~/Downloads/interesting-snippets")))
Collections appearing earlier in the list shadow snippets with same names
appearing in collections later in the list. yas-new-snippet
always stores
snippets in the first collection.
2.3 The .yas-parents
file
It's very useful to have certain modes share snippets between themselves. To do
this, choose a mode subdirectory and place a .yas-parents
containing a
whitespace-separated list of other mode names. When you reload those modes
become parents of the original mode.
. |-- c-mode | |-- .yas-parents # contains "cc-mode text-mode" | `-- printf |-- cc-mode | |-- for | `-- while |-- java-mode | |-- .yas-parents # contains "cc-mode text-mode" | `-- println `-- text-mode |-- email `-- time
2.4 TODO The .yas-make-groups
file
If you place an empty plain text file .yas-make-groups
inside one of the
mode directories, the names of these sub-directories are considered groups of
snippets and the menu is organized much more cleanly:
(TODO image)
Another alternative way to achieve this is to place a # group:
directive
inside the snippet definition. See Writing Snippets
$ tree ruby-mode/ ruby-mode/ |-- .yas-make-groups |-- collections | |-- each | `-- ... |-- control structure | |-- forin | `-- ... |-- definitions | `-- ... `-- general `-- ...
Yet another way to create a nice snippet menu is to write into
.yas-make-groups
a menu definition. TODO
2.5 TODO The .yas-setup.el
file
2.5.1 TODO
2.6 TODO The .yas-compiled-snippet.el
file
2.6.1 TODO
2.7 The .yas-skip
file
3 Expanding Snippets
This section describes how YASnippet chooses snippets for expansion at point.
Maybe, you'll want some snippets to be expanded in a particular mode, or only under certain conditions, or be prompted using
3.1 Triggering expansion
To make a snippet expand after the cursor:
- Type the snippet's trigger key then calling
yas-expand
. It's bound toTAB
and<tab>
by default, to change it use
(define-key yas-minor-mode-map (kbd "<tab>") nil) (define-key yas-minor-mode-map (kbd "TAB") nil) (define-key yas-minor-mode-map (kbd "<the new key>") 'yas-expand)
- Use the snippet's keybinding.
- Call
yas-insert-snippet
(useM-x yas-insert-snippet=
or its keybindingC-c & C-s
). - By expanding directly from the "YASnippet" menu in the menu-bar
- Using hippie-expand
- Use m2m's excellent auto-complete
4 Reference
4.1 Interactive functions
4.1.1 yas-skip-and-clear-or-delete-char
(&optional field)
/WARNING/: no doc for symbol yas-skip-and-clear-or-delete-char
4.1.10 yas-load-snippet-buffer
(table &optional interactive)
/WARNING/: no doc for symbol yas-load-snippet-buffer
4.1.14 yas-expand-from-keymap
()
Expand/run snippets from keymaps, possibly falling back to original binding.
4.1.15 yas-expand-from-trigger-key
(&optional field)
/WARNING/: no doc for symbol yas-expand-from-trigger-key
4.1.20 yas-load-directory
(top-level-dir &optional use-jit interactive)
/WARNING/: no doc for symbol yas-load-directory
4.1.23 yas-global-mode
(&optional arg)
Non-nil if Yas-Global mode is enabled.
See the command yas-global-mode
for a description of this minor mode.
Setting this variable directly does not take effect;
either customize it (see the info node `Easy Customization')
or call the function yas-global-mode
.
4.1.24 yas-minor-mode
(&optional arg)
Non-nil if yas minor mode is enabled.
Use the command yas-minor-mode
to change this variable.
4.1.25 yas-expand
(&optional field)
Expand a snippet before point. If no snippet
expansion is possible, call command org-self-insert-command
.
Optional argument FIELD is for non-interactive use and is an
object satisfying yas–field-p
to restrict the expansion to.
4.2 Customization variables
4.2.1 yas-expand-only-for-last-commands
List of last-command
values to restrict tab-triggering to, or nil.
Leave this set at nil (the default) to be able to trigger an expansion simply by placing the cursor after a valid tab trigger, using whichever commands.
Optionally, set this to something like '(self-insert-command) if you to wish restrict expansion to only happen when the last letter of the snippet tab trigger was typed immediately before the trigger key itself.
4.2.3 yas-good-grace
If non-nil, don't raise errors in inline elisp evaluation.
An error string "[yas] error" is returned instead.
4.2.4 yas-wrap-around-region
If non-nil, snippet expansion wraps around selected region.
The wrapping occurs just before the snippet's exit marker. This can be overridden on a per-snippet basis.
4.2.7 yas-choose-tables-first
If non-nil, and multiple eligible snippet tables, prompts user for tables first.
Otherwise, user chooses between the merging together of all eligible tables.
This affects yas-insert-snippet
, yas-visit-snippet-file
4.2.8 yas-choose-keys-first
If non-nil, prompt for snippet key first, then for template.
Otherwise prompts for all possible snippet names.
This affects yas-insert-snippet
and yas-visit-snippet-file
.
4.2.9 yas-fallback-behavior
How to act when yas-expand
does not expand a snippet.
call-other-command
means try to temporarily disable /YAS/nippet and call the next command bound to whatever key was used to invokeyas-expand
.- nil or the symbol
return-nil
mean do nothing. (andyas-expand
returns nil) - A Lisp form (apply COMMAND . ARGS) means interactively call COMMAND, if ARGS is non-nil, call COMMAND non-interactively with ARGS as arguments.
4.2.10 yas-triggers-in-field
If non-nil, allow stacked expansions (snippets inside snippets).
Otherwise yas-next-field-or-maybe-expand
just moves on to the
next field
4.2.12 yas-also-auto-indent-first-line
Non-nil means also auto indent first line according to mode.
Naturally this is only valid when yas-indent-line
is auto
4.2.13 yas-indent-line
Controls indenting applied to a recent snippet expansion.
The following values are possible:
fixed
Indent the snippet to the current column;auto
Indent each line of the snippet withindent-according-to-mode
Every other value means don't apply any snippet-side indentation after expansion (the manual per-line "$>" indentation still applies).
4.2.14 yas-prompt-functions
Functions to prompt for keys, templates, etc interactively.
These functions are called with the following arguments:
- PROMPT: A string to prompt the user
- CHOICES: a list of strings or objects.
- optional DISPLAY-FN : A function that, when applied to each of
the objects in CHOICES will return a string.
The return value of any function you put here should be one of the objects in CHOICES, properly formatted with DISPLAY-FN (if that is passed).
- To signal that your particular style of prompting is
unavailable at the moment, you can also have the function return nil.
- To signal that the user quit the prompting process, you can
signal quit
with
(signal 'quit "user quit!").
4.2.15 yas-snippet-dirs
()
Directory or list of snippet dirs for each major mode.
The directory where user-created snippets are to be stored. Can
also be a list of directories. In that case, when used for
bulk (re)loading of snippets (at startup or via
yas-reload-all
), directories appearing earlier in the list
shadow other dir's snippets. Also, the first directory is taken
as the default for storing the user's new snippets.
4.3 Useful functions
4.3.3 yas-define-condition-cache
(func doc &rest body)
/WARNING/: no doc for symbol yas-define-condition-cache
4.3.18 yas-expand-snippet
(content &optional start end expand-env)
/WARNING/: no doc for symbol yas-expand-snippet
4.3.19 yas-dropdown-prompt
(prompt choices &optional display-fn)
/WARNING/: no doc for symbol yas-dropdown-prompt
4.3.20 yas-completing-prompt
(prompt choices &optional display-fn completion-fn)
/WARNING/: no doc for symbol yas-completing-prompt
4.3.21 yas-no-prompt
(prompt choices &optional display-fn)
/WARNING/: no doc for symbol yas-no-prompt
4.4 Useful variables
4.4.5 yas-dont-activate
If non-nil don't let yas-global-mode
affect some buffers.
If a function of zero arguments, then its result is used.
If a list of functions, then all functions must return nil to activate yas for this buffer.
In Emacsen <= 23, this variable is buffer-local. Because
yas-minor-mode-on
is called by yas-global-mode
after
executing the buffer's major mode hook, setting this variable
there is an effective way to define exceptions to the "global"
activation behaviour.
In Emacsen > 23, only the global value is used. To define
per-mode exceptions to the "global" activation behaviour, call
yas-minor-mode
with a negative argument directily in the major
mode's hook.
4.4.6 yas-buffer-local-condition
Snippet expanding condition.
This variable is a Lisp form which is evaluated every time a snippet expansion is attempted:
- If it evaluates to nil, no snippets can be expanded.
- If it evaluates to the a cons (require-snippet-condition
. REQUIREMENT)
- Snippets bearing no "# condition:" directive are not considered
- Snippets bearing conditions that evaluate to nil (or produce an error) won't be considered.
- If the snippet has a condition that evaluates to non-nil
RESULT:
- If REQUIREMENT is t, the snippet is considered
- If REQUIREMENT is
eq
RESULT, the snippet is considered - Otherwise, the snippet is not considered.
- If it evaluates to the symbol 'always, all snippets are considered for expansion, regardless of any conditions.
- If it evaluates to t or some other non-nil value
- Snippet bearing no conditions, or conditions that evaluate to non-nil, are considered for expansion.
- Otherwise, the snippet is not considered.
Here's an example preventing snippets from being expanded from
inside comments, in python-mode
only, with the exception of
snippets returning the symbol 'force-in-comment in their
conditions.
(add-hook 'python-mode-hook '(lambda () (setq yas-buffer-local-condition '(if (python-in-string/comment) '(require-snippet-condition . force-in-comment) t))))
The default value is similar, it filters out potential snippet
expansions inside comments and string literals, unless the
snippet itself contains a condition that returns the symbol
force-in-comment
.
4.4.8 yas-after-exit-snippet-hook
Hooks to run after a snippet exited.
The hooks will be run in an environment where some variables bound to proper values:
yas-snippet-beg
: The beginning of the region of the snippet.
yas-snippet-end
: Similar to beg.
Attention: These hooks are not run when exiting nested/stacked snippet expansion!
4.4.9 yas-key-syntaxes
List of character syntaxes used to find a trigger key before point. The list is tried in the order while scanning characters backwards from point. For example, if the list is '("w" "w_") first look for trigger keys which are composed exclusively of "word"-syntax characters, and then, if that fails, look for keys which are either of "word" or "symbol" syntax. Triggering after
foo-bar
will, according to the "w" element first try "bar". If that isn't a trigger key, "foo-bar" is tried, respecting a second "w_" element.
4.4.10 yas-extra-modes
A list of modes for which to also lookup snippets.
This variable probably makes more sense as buffer-local, so
ensure your use make-local-variable
when you set it.
4.4.11 yas-verbosity
Log level for yas–message
4 means trace most anything, 0 means nothing.