mirror of
https://github.com/joaotavora/yasnippet.git
synced 2026-02-05 15:02:26 +00:00
doc almost complete. Drawing closer to 0.6.1b
This commit is contained in:
@@ -2,23 +2,34 @@
|
||||
Writing snippets
|
||||
================
|
||||
|
||||
:Author: pluskid, joaotavora
|
||||
:Contact: pluskid@gmail.com
|
||||
:Date: 2009-08-18
|
||||
.. _Organizing Snippets: snippet-organization.html
|
||||
.. _Expanding Snippets: snippet-expansion.html
|
||||
.. _Writing Snippets: snippet-development.html
|
||||
.. _The YASnippet Menu: snippet-menu.html
|
||||
|
||||
.. contents::
|
||||
|
||||
Quickly finding/defining snippets
|
||||
---------------------------------
|
||||
Snippet development
|
||||
===================
|
||||
|
||||
From version 0.6 upwards there are two ways you can quickly find a
|
||||
snippet file. Once you find this file it will be set to
|
||||
``snippet-mode`` (see ahead)
|
||||
Quickly finding snippets
|
||||
------------------------
|
||||
|
||||
There are some ways you can quickly find a snippet file. Once you find
|
||||
this file it will be set to ``snippet-mode`` (see ahead) and you can
|
||||
start editing your snippet.
|
||||
|
||||
* ``M-x yas/new-snippet``
|
||||
|
||||
Prompts you for a snippet name, then tries to guess a suitable
|
||||
directory to store it, prompting you for creation if it does not
|
||||
exist. Finally, places you in a new buffer set to ``snippet-mode``
|
||||
so you can write your snippet.
|
||||
|
||||
* ``M-x yas/find-snippets``
|
||||
|
||||
Lets you find the snippet file in the directory the snippet was
|
||||
loaded from (if it exists) like ``find-file-other-window``.
|
||||
loaded from (if it exists) like ``find-file-other-window``.
|
||||
|
||||
* ``M-x yas/visit-snippet-file``
|
||||
|
||||
@@ -30,32 +41,199 @@ snippet file. Once you find this file it will be set to
|
||||
Using the ``snippet-mode`` major mode
|
||||
-------------------------------------
|
||||
|
||||
From version 0.6 upwards there is a major mode ``snippet-mode`` to
|
||||
edit snippets. You can set the buffer to this mode with ``M-x
|
||||
snippet-mode``. It provides reasonably useful syntax highlighting.
|
||||
There is a major mode ``snippet-mode`` to edit snippets. You can set
|
||||
the buffer to this mode with ``M-x snippet-mode``. It provides
|
||||
reasonably useful syntax highlighting.
|
||||
|
||||
Two commands are defined in this mode:
|
||||
|
||||
* ``M-x yas/load-snippet-buffer``
|
||||
|
||||
* ``M-x yas/load-snippet-buffer``
|
||||
|
||||
When editing a snippet, this loads the snippet into the correct
|
||||
mode and menu. Bound to ``C-c C-c`` by default while in
|
||||
``snippet-mode``.
|
||||
|
||||
* ``M-x yas/tryout-snippet``
|
||||
|
||||
|
||||
* ``M-x yas/tryout-snippet``
|
||||
|
||||
When editing a snippet, this opens a new empty buffer, sets it to
|
||||
the appropriate major mode and inserts the snippet there, so you
|
||||
can see what it looks like. This is bound to ``C-c C-t`` while in
|
||||
``snippet-mode``.
|
||||
|
||||
|
||||
There are also snippets for making snippets: ``vars``, ``field`` and
|
||||
``mirror``.
|
||||
|
||||
File content
|
||||
============
|
||||
|
||||
A file defining a snippet may just contain the template for the
|
||||
snippet. Optionally it can also contains some meta data for the
|
||||
snippet as well as comments.
|
||||
|
||||
Generally speaking, if the file contains a line of ``# --``, then all
|
||||
contents above that line are considered directives (meta data) and
|
||||
comments; below that line lies the snippet template.
|
||||
|
||||
If no ``# --`` is found, the whole file content is considered as the
|
||||
template.
|
||||
|
||||
Here's a typical example:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
#contributor : pluskid <pluskid@gmail.com>
|
||||
#name : __...__
|
||||
# --
|
||||
__${init}__
|
||||
|
||||
Meta data are specified in the syntax of
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
#data-name : data value
|
||||
|
||||
Any other text above ``# --`` is considered as comment and
|
||||
ignored. Here's a list of currently supported directives:
|
||||
|
||||
``# key:`` snippet abbrev
|
||||
--------------------------
|
||||
|
||||
This is the probably the most important directive, it's the
|
||||
abbreviation you type to expand a snippet just before hitting
|
||||
``yas/trigger-key``.
|
||||
|
||||
If you don't specify this it will default to the name of the file the
|
||||
snippet is being loaded from, unless YASnippet is ignoring file names
|
||||
as triggers (see ``yas/ignore-filenames-as-triggers`` in `Organizing
|
||||
snippets`_), in which case this snippet
|
||||
will not be expandable through the key mechanism.
|
||||
|
||||
Sometimes the key of a snippet is non-ASCII or not valid filename
|
||||
(e.g. contains ``/``). One can then define the ``key`` property which
|
||||
will overwrite the filename as the key to expand the snippet.
|
||||
|
||||
``# name:`` snippet name
|
||||
------------------------
|
||||
|
||||
This is a one-line description of the snippet. It will be displayed in
|
||||
the menu. It's a good idea to select a descriptive name for a
|
||||
snippet -- especially distinguishable among similar snippets.
|
||||
|
||||
If you omit this name it will default to the file name the snippet was
|
||||
loaded from.
|
||||
|
||||
|
||||
The Syntax of the Template
|
||||
==========================
|
||||
``# condition:`` snippet condition
|
||||
----------------------------------
|
||||
This is a piece of Emacs-lisp code. If a snippet has a condition, then it
|
||||
will only be expanded when the condition code evaluate to some non-nil
|
||||
value.
|
||||
|
||||
See also ``yas/buffer-local-condition`` in `Expanding snippets`_
|
||||
|
||||
|
||||
|
||||
``# group`` snippet menu grouping
|
||||
|
||||
When expanding/visiting snippets from the menu-bar menu, snippets for a
|
||||
given mode can be grouped into sub-menus . This is useful if one has
|
||||
too many snippets for a mode which will make the menu too
|
||||
long.
|
||||
|
||||
The ``# group:`` property only affect menu construction (See `the
|
||||
YASnippet menu`_) and the same effect can be achieved by grouping
|
||||
snippets into sub-directories and using the ``.yas-make-groups``
|
||||
special file (for this see `Organizing Snippets`_
|
||||
|
||||
|
||||
Refer to the bundled snippets for ``ruby-mode`` for examples on the
|
||||
``# group:`` directive. Group can also be nested, e.g. ``control
|
||||
structure.loops`` tells that the snippet is under the ``loops`` group
|
||||
which is under the ``control structure`` group.
|
||||
|
||||
``# expand-env:`` expand environment
|
||||
------------------------------------
|
||||
|
||||
This is another piece of Emacs-lisp code in the form of a ``let`` *varlist*
|
||||
form, i.e. a list of lists assigning values to variables. It can be
|
||||
used to override variable values while the snippet is being expanded.
|
||||
|
||||
Interesting variables to override are ``yas/wrap-around-region`` and
|
||||
``yas/indent-line`` (see `Expanding Snippets`_).
|
||||
|
||||
|
||||
As an example, you might normally have ``yas/indent-line`` set to
|
||||
``'auto`` and ``yas/wrap-around-region`` set to ``t``, but for this
|
||||
particularly brilliant piece of ASCII art these values would mess up
|
||||
your hard work. You can then use:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
# name : ASCII home
|
||||
# expand-env: ((yas/indent-line 'fixed) (yas/wrap-around-region 'nil))
|
||||
# --
|
||||
welcome to my
|
||||
X humble
|
||||
/ \ home,
|
||||
/ \ $0
|
||||
/ \
|
||||
/-------\
|
||||
| |
|
||||
| +-+ |
|
||||
| | | |
|
||||
+--+-+--+
|
||||
|
||||
``# binding:``: direct keybinding
|
||||
---------------------------------
|
||||
|
||||
You can use this directive to expand a snippet directly from a normal
|
||||
Emacs keybinding. The keybinding will be registered in the Emacs
|
||||
keymap named after the major mode the snippet is active
|
||||
for.
|
||||
|
||||
Additionally a variable ``yas/prefix`` is set to to the prefix
|
||||
argument you normally use for a command. This allows for small
|
||||
variations on the same snippet, for example in this "html-mode"
|
||||
snippet.
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
#name : <p>...</p>
|
||||
#binding: "C-c C-c C-m"
|
||||
# --
|
||||
<p>`(when yas/prefix "\n")`$0`(when yas/prefix "\n")`</p>
|
||||
|
||||
This binding will be recorded in the keymap ``html-mode-map``. To
|
||||
expand a paragraph tag newlines, just press "C-u C-c C-c
|
||||
C-m". Omitting the "C-u" will expand the paragraph tag without
|
||||
newlines.
|
||||
|
||||
To override the keymap choice based on the major mode name. Use a cons
|
||||
cell where the first element specifies the name of the keymap where
|
||||
you want to record the keybinding.
|
||||
|
||||
.. sourcecode:: text
|
||||
#name : <p>...</p>
|
||||
#binding: (rinari-minor-mode-map . "C-c C-c C-m")
|
||||
# --
|
||||
<p>`(when yas/prefix "\n")`$0`(when yas/prefix "\n")`</p>
|
||||
|
||||
Note that this feature is still experimental and should be used with
|
||||
caution: It is easy to override important keybindings for many basic
|
||||
modes and it is hard to undefine them. In particular, the variable
|
||||
``yas/active-keybinding`` can tell you what snippet keybindings are
|
||||
active and the function ``yas/kill-snippet-keybindings`` will try to
|
||||
undefine all the keybindings.
|
||||
|
||||
``# contributor:``: snippet author
|
||||
---------------------------------------------------
|
||||
|
||||
This is optional and has no effect whatsoever on snippet
|
||||
functionality, but it looks nice.
|
||||
|
||||
|
||||
Template syntax
|
||||
===============
|
||||
|
||||
The syntax of the snippet template is simple but powerful, very
|
||||
similar to TextMate's.
|
||||
@@ -68,10 +246,10 @@ usually interpreted as plain text, except ``$`` and `````. You need to
|
||||
use ``\`` to escape them: ``\$`` and ``\```. The ``\`` itself may also
|
||||
needed to be escaped as ``\\`` sometimes.
|
||||
|
||||
Embedded elisp code
|
||||
-------------------
|
||||
Embedded Emacs-lisp code
|
||||
------------------------
|
||||
|
||||
Elisp code can be embedded inside the template. They are written
|
||||
Emacs-Lisp code can be embedded inside the template. They are written
|
||||
inside back-quotes (`````):
|
||||
|
||||
They are evaluated when the snippet is being expanded. The evaluation
|
||||
@@ -82,13 +260,13 @@ example for ``c-mode`` to calculate the header file guard dynamically:
|
||||
|
||||
#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
|
||||
#define $1
|
||||
|
||||
|
||||
$0
|
||||
|
||||
|
||||
#endif /* $1 */
|
||||
|
||||
From version 0.6.0, snippets expansions are run with some special
|
||||
emacs-lisp variables bound. One of this is ``yas/selected-text``. You
|
||||
Emacs-lisp variables bound. One of this is ``yas/selected-text``. You
|
||||
can therefore define a snippet like:
|
||||
|
||||
.. sourcecode:: text
|
||||
@@ -105,7 +283,7 @@ Tab stop fields
|
||||
---------------
|
||||
|
||||
Tab stops are fields that you can navigate back and forth by ``TAB``
|
||||
and ``S-TAB`` [3]_. They are written by ``$`` followed with a
|
||||
and ``S-TAB``. They are written by ``$`` followed with a
|
||||
number. ``$0`` has the special meaning of the *exit point* of a
|
||||
snippet. That is the last place to go when you've traveled all the
|
||||
fields. Here's a typical example:
|
||||
@@ -163,7 +341,7 @@ Mirrors with transformations
|
||||
|
||||
If the default value of a field starts with ``$``, then it is interpreted
|
||||
as the transformation code instead of default value. A transformation
|
||||
is some arbitrary elisp code that will get evaluated in an environment
|
||||
is some arbitrary Emacs-lisp code that will get evaluated in an environment
|
||||
when the variable text is bind to the inputted text of the
|
||||
field. Here's an example for Objective-C:
|
||||
|
||||
@@ -173,7 +351,7 @@ field. Here's an example for Objective-C:
|
||||
{
|
||||
return $2;
|
||||
}
|
||||
|
||||
|
||||
- (void)set${2:$(capitalize text)}:($1)aValue
|
||||
{
|
||||
[$2 autorelease];
|
||||
@@ -185,8 +363,8 @@ Look at ``${2:$(capitalize text)}``, it is a transformation instead of
|
||||
a placeholder. The actual placeholder is at the first line:
|
||||
``${2:foo}``. When you type text in ``${2:foo}``, the transformation
|
||||
will be evaluated and the result will be placed there as the
|
||||
transformated text. So in this example, if you type baz in the field,
|
||||
the transformed text will be Baz. This example is also available in
|
||||
transformed text. So in this example, if you type "baz" in the field,
|
||||
the transformed text will be "Baz". This example is also available in
|
||||
the screencast.
|
||||
|
||||
Another example is for ``rst-mode``. In reStructuredText, the document
|
||||
@@ -207,19 +385,15 @@ is a valid title but
|
||||
Title
|
||||
===
|
||||
|
||||
is not. Here's an snippet for rst title:
|
||||
is not. Here's an snippet for rst title:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
${1:$(make-string (string-width text) ?\=)}
|
||||
${1:Title}
|
||||
${1:$(make-string (string-width text) ?\=)}
|
||||
|
||||
$0
|
||||
|
||||
.. [1] With some minor change, mainly for fixing some trivial bugs.
|
||||
.. [2] This is done when you call ``yas/initialize``.
|
||||
.. [3] Of course, this can be customized.
|
||||
$0
|
||||
|
||||
Fields with transformations
|
||||
---------------------------
|
||||
@@ -240,8 +414,8 @@ distinguish between fields and mirrors. In the following example
|
||||
the field. As you type text, it gets filtered through the
|
||||
transformation every time.
|
||||
|
||||
Note that this is differentiated from a mirror with a transformation
|
||||
by the existance of extra text between the ``:`` and the
|
||||
Note that to tell this kind of expression from a mirror with a
|
||||
transformation, YASnippet needs extra text between the ``:`` and the
|
||||
transformation's ``$``. If you don't want this extra-text, you can use
|
||||
two ``$``'s instead.
|
||||
|
||||
@@ -261,16 +435,16 @@ As mentioned, the field transformation is invoked just after you enter
|
||||
the field, and with some useful variables bound, notably
|
||||
``yas/field-modified-p`` and ``yas/moving-away-p``. Because of this
|
||||
feature you can place a transformation in the primary field that lets
|
||||
you select default values for it.
|
||||
you select default values for it.
|
||||
|
||||
The ``yas/choose-value`` does this work for you. For example:
|
||||
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
<div align="${2:$$(yas/choose-value '("right" "center" "left"))}">
|
||||
$0
|
||||
</div>
|
||||
|
||||
|
||||
See the definition of ``yas/choose-value`` to see how it was written
|
||||
using the two variables. Also check out ``yas/verify-value`` for
|
||||
another neat trick.
|
||||
@@ -288,8 +462,134 @@ This allows you to choose if you want to give this ``div`` an ``id``
|
||||
attribute. If you tab forward after expanding it will let you change
|
||||
"some_id" to whatever you like. Alternatively, you can just press
|
||||
``C-d`` (which executes ``yas/skip-and-clear-or-delete-char``) and go
|
||||
straight to the exit marker.
|
||||
straight to the exit marker.
|
||||
|
||||
By the way, ``C-d`` will only clear the field if you cursor is at the
|
||||
beginning of the field *and* it hasn't been changed yet. Otherwise, it
|
||||
performs the normal Emacs ``delete-char`` command.
|
||||
|
||||
Customizable variables
|
||||
======================
|
||||
|
||||
``yas/trigger-key``
|
||||
-------------------
|
||||
|
||||
The key bound to ``yas/expand`` when function ``yas/minor-mode`` is
|
||||
active.
|
||||
|
||||
Value is a string that is converted to the internal Emacs key
|
||||
representation using ``read-kbd-macro``.
|
||||
|
||||
Default value is ``"TAB"``.
|
||||
|
||||
``yas/next-field-key``
|
||||
----------------------
|
||||
|
||||
The key to navigate to next field when a snippet is active.
|
||||
|
||||
Value is a string that is converted to the internal Emacs key
|
||||
representation using ``read-kbd-macro``.
|
||||
|
||||
Can also be a list of keys.
|
||||
|
||||
Default value is ``"TAB"``.
|
||||
|
||||
``yas/prev-field-key``
|
||||
----------------------
|
||||
|
||||
The key to navigate to previous field when a snippet is active.
|
||||
|
||||
Value is a string that is converted to the internal Emacs key
|
||||
representation using ``read-kbd-macro``.
|
||||
|
||||
Can also be a list of keys.
|
||||
|
||||
Default value is ``("<backtab>" "<S-tab>)"``.
|
||||
|
||||
``yas/skip-and-clear-key``
|
||||
--------------------------
|
||||
|
||||
The key to clear the currently active field.
|
||||
|
||||
Value is a string that is converted to the internal Emacs key
|
||||
representation using ``read-kbd-macro``.
|
||||
|
||||
Can also be a list of keys.
|
||||
|
||||
Default value is ``"C-d"``.
|
||||
|
||||
``yas/good-grace``
|
||||
------------------
|
||||
|
||||
If non-nil, don't raise errors in inline Emacs-lisp evaluation inside
|
||||
snippet definitions. An error string "[yas] error" is returned instead.
|
||||
|
||||
``yas/indent-line``
|
||||
-------------------
|
||||
|
||||
The variable ``yas/indent-line`` controls the indenting. It is bound
|
||||
to ``'auto`` by default, which causes your snippet to be indented
|
||||
according to the mode of the buffer it was inserted in.
|
||||
|
||||
Another variable ``yas/also-auto-indent-first-line``, when non-nil
|
||||
does exactly that :-).
|
||||
|
||||
To use the hard-coded indentation in your snippet template, set this
|
||||
variable to ``fixed``.
|
||||
|
||||
To control indentation on a per-snippet basis, see also the directive
|
||||
``# expand-env:`` in `Writing Snippets`_.
|
||||
|
||||
For backward compatibility with earlier versions of YASnippet, you can
|
||||
also place a ``$>`` in your snippet, an ``(indent-according-to-mode)``
|
||||
will be executed there to indent the line. This only takes effect when
|
||||
``yas/indent-line`` is set to something other than ``'auto``.
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
for (${int i = 0}; ${i < 10}; ${++i})
|
||||
{$>
|
||||
$0$>
|
||||
}$>
|
||||
|
||||
``yas/wrap-around-region``
|
||||
--------------------------
|
||||
|
||||
If non-nil, YASnippet will try to expand the snippet's exit marker
|
||||
around the currently selected region. When this variable is set to t,
|
||||
this has the same effect has using the ```yas/selected-text``` inline
|
||||
evaluation.
|
||||
|
||||
Because on most systems starting to type deletes the currently region,
|
||||
this works mostly with the ``yas/insert-snippet`` command.
|
||||
|
||||
However, when the value is of this variable is ``cua`` YASnippet will
|
||||
additionally look-up any recently selected that you deleted by starting
|
||||
typing. This allows you select a region, type a snippet key (deleting
|
||||
the region), then press ``yas/trigger-key`` to see the deleted region
|
||||
spring back to life inside your new snippet.
|
||||
|
||||
``yas/triggers-in-field``
|
||||
--------------------------
|
||||
|
||||
If non-nil, ``yas/next-field-key`` can trigger stacked expansions,
|
||||
that is a snippet expansion inside another snippet
|
||||
expansion. Otherwise, ``yas/next-field-key`` just tries to move on to
|
||||
the next field.
|
||||
|
||||
``yas/snippet-revival``
|
||||
-----------------------
|
||||
|
||||
Non-nil means re-activate snippet fields after undo/redo.
|
||||
|
||||
``yas/after-exit-snippet-hook`` and ``yas/before-expand-snippet-hook``
|
||||
----------------------------------------------------------------------
|
||||
|
||||
These hooks are called, respectively, before the insertion of a
|
||||
snippet and after exiting the snippet. If you find any strange but
|
||||
functional use for them, that's probably a design flaw in YASnippet,
|
||||
so let us know.
|
||||
|
||||
.. LocalWords: html YASnippet yas sourcecode pluskid init filenames filename
|
||||
.. LocalWords: env varlist keybinding keymap rinari ifndef upcase endif
|
||||
.. LocalWords: nondirectory autorelease aValue inline
|
||||
|
||||
Reference in New Issue
Block a user