yasnippet/snippet-development.html
2011-11-04 12:01:45 +00:00

602 lines
38 KiB
HTML

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
<title>Writing snippets</title>
<link rel="stylesheet" href="styles.css" type="text/css" />
</head>
<body>
<div class="document" id="writing-snippets">
<div id="header-region" class="clear-block"></div>
<div id="wrapper">
<div id="container" class="clear-block">
<div id="header">
<div id="logo-floater">
<h1 class="title">Writing snippets</h1>
</div>
<ul class="primary-links">
<li>
<a title="" href="index.html">Intro and tutorial</a>
</li>
<li>
<a title="" href="snippet-organization.html">Howto: organize</a>
</li>
<li>
<a title="" href="snippet-expansion.html">Howto: expand</a>
</li>
<li>
<a title="" href="snippet-development.html">Howto: write </a>
</li>
<li>
<a title="" href="snippet-menu.html">Howto: menu </a>
</li>
<li>
<a title="" href="faq.html">FAQ</a>
</li>
<li>
<a title="" href="changelog.html">ChangeLog</a>
</li>
<li>
<a title="" href="http://code.google.com/p/yasnippet/downloads/list">Download</a>
</li>
</ul>
</div>
<div id="center">
<div id="squeeze">
<div class="right-corner">
<div class="left-corner">
<p>
<b>Important:</b> This documentation applies to
the <b>SVN trunk</b> of YASnippet, which you
get <a href="http://code.google.com/p/yasnippet/source/checkout">here</a>. Documentation
for other versions can be found <a title=""
href="http://code.google.com/p/yasnippet/downloads/list">here</a>.
</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#snippet-development" id="id3">Snippet development</a><ul>
<li><a class="reference internal" href="#quickly-finding-snippets" id="id4">Quickly finding snippets</a></li>
<li><a class="reference internal" href="#using-the-snippet-mode-major-mode" id="id5">Using the <tt class="docutils literal"><span class="pre">snippet-mode</span></tt> major mode</a></li>
</ul>
</li>
<li><a class="reference internal" href="#file-content" id="id6">File content</a><ul>
<li><a class="reference internal" href="#key-snippet-abbrev" id="id7"><tt class="docutils literal"># key:</tt> snippet abbrev</a></li>
<li><a class="reference internal" href="#name-snippet-name" id="id8"><tt class="docutils literal"># name:</tt> snippet name</a></li>
<li><a class="reference internal" href="#condition-snippet-condition" id="id9"><tt class="docutils literal"># condition:</tt> snippet condition</a></li>
<li><a class="reference internal" href="#group-snippet-menu-grouping" id="id10"><tt class="docutils literal"># group:</tt> snippet menu grouping</a></li>
<li><a class="reference internal" href="#expand-env-expand-environment" id="id11"><tt class="docutils literal"># <span class="pre">expand-env:</span></tt> expand environment</a></li>
<li><a class="reference internal" href="#binding-direct-keybinding" id="id12"><tt class="docutils literal"># binding:</tt> direct keybinding</a></li>
<li><a class="reference internal" href="#contributor-snippet-author" id="id13"><tt class="docutils literal"># contributor:</tt> snippet author</a></li>
</ul>
</li>
<li><a class="reference internal" href="#template-syntax" id="id14">Template syntax</a><ul>
<li><a class="reference internal" href="#plain-text" id="id15">Plain Text</a></li>
<li><a class="reference internal" href="#embedded-emacs-lisp-code" id="id16">Embedded Emacs-lisp code</a></li>
<li><a class="reference internal" href="#tab-stop-fields" id="id17">Tab stop fields</a></li>
<li><a class="reference internal" href="#placeholder-fields" id="id18">Placeholder fields</a></li>
<li><a class="reference internal" href="#id2" id="id19">Mirrors</a></li>
<li><a class="reference internal" href="#mirrors-with-transformations" id="id20">Mirrors with transformations</a></li>
<li><a class="reference internal" href="#fields-with-transformations" id="id21">Fields with transformations</a></li>
<li><a class="reference internal" href="#choosing-fields-value-from-a-list-and-other-tricks" id="id22">Choosing fields value from a list and other tricks</a></li>
<li><a class="reference internal" href="#nested-placeholder-fields" id="id23">Nested placeholder fields</a></li>
</ul>
</li>
<li><a class="reference internal" href="#customizable-variables" id="id24">Customizable variables</a><ul>
<li><a class="reference internal" href="#yas-trigger-key" id="id25"><tt class="docutils literal"><span class="pre">yas/trigger-key</span></tt></a></li>
<li><a class="reference internal" href="#yas-next-field-key" id="id26"><tt class="docutils literal"><span class="pre">yas/next-field-key</span></tt></a></li>
<li><a class="reference internal" href="#yas-prev-field-key" id="id27"><tt class="docutils literal"><span class="pre">yas/prev-field-key</span></tt></a></li>
<li><a class="reference internal" href="#yas-skip-and-clear-key" id="id28"><tt class="docutils literal"><span class="pre">yas/skip-and-clear-key</span></tt></a></li>
<li><a class="reference internal" href="#yas-good-grace" id="id29"><tt class="docutils literal"><span class="pre">yas/good-grace</span></tt></a></li>
<li><a class="reference internal" href="#yas-indent-line" id="id30"><tt class="docutils literal"><span class="pre">yas/indent-line</span></tt></a></li>
<li><a class="reference internal" href="#yas-wrap-around-region" id="id31"><tt class="docutils literal"><span class="pre">yas/wrap-around-region</span></tt></a></li>
<li><a class="reference internal" href="#yas-triggers-in-field" id="id32"><tt class="docutils literal"><span class="pre">yas/triggers-in-field</span></tt></a></li>
<li><a class="reference internal" href="#yas-snippet-revival" id="id33"><tt class="docutils literal"><span class="pre">yas/snippet-revival</span></tt></a></li>
<li><a class="reference internal" href="#yas-after-exit-snippet-hook-and-yas-before-expand-snippet-hook" id="id34"><tt class="docutils literal"><span class="pre">yas/after-exit-snippet-hook</span></tt> and <tt class="docutils literal"><span class="pre">yas/before-expand-snippet-hook</span></tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#importing-textmate-snippets" id="id35">Importing TextMate snippets</a></li>
</ul>
</div>
<div class="section" id="snippet-development">
<h1><a class="toc-backref" href="#id3">Snippet development</a></h1>
<div class="section" id="quickly-finding-snippets">
<h2><a class="toc-backref" href="#id4">Quickly finding snippets</a></h2>
<p>There are some ways you can quickly find a snippet file:</p>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/new-snippet</span></tt></p>
<p>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 <tt class="docutils literal"><span class="pre">snippet-mode</span></tt>
so you can write your snippet.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/find-snippets</span></tt></p>
<p>Lets you find the snippet file in the directory the snippet was
loaded from (if it exists) like <tt class="docutils literal"><span class="pre">find-file-other-window</span></tt>. The
directory searching logic is similar to <tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/new-snippet</span></tt>.</p>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/visit-snippet-file</span></tt></p>
<p>Prompts you for possible snippet expansions like
<tt class="docutils literal"><span class="pre">yas/insert-snippet</span></tt>, but instead of expanding it, takes you
directly to the snippet definition's file, if it exists.</p>
</li>
</ul>
<p>Once you find this file it will be set to <tt class="docutils literal"><span class="pre">snippet-mode</span></tt> (see ahead)
and you can start editing your snippet.</p>
</div>
<div class="section" id="using-the-snippet-mode-major-mode">
<h2><a class="toc-backref" href="#id5">Using the <tt class="docutils literal"><span class="pre">snippet-mode</span></tt> major mode</a></h2>
<p>There is a major mode <tt class="docutils literal"><span class="pre">snippet-mode</span></tt> to edit snippets. You can set
the buffer to this mode with <tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">snippet-mode</span></tt>. It provides
reasonably useful syntax highlighting.</p>
<p>Two commands are defined in this mode:</p>
<ul>
<li><p class="first"><tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/load-snippet-buffer</span></tt></p>
<blockquote>
<p>When editing a snippet, this loads the snippet into the correct
mode and menu. Bound to <tt class="docutils literal"><span class="pre">C-c</span> <span class="pre">C-c</span></tt> by default while in
<tt class="docutils literal"><span class="pre">snippet-mode</span></tt>.</p>
</blockquote>
</li>
<li><p class="first"><tt class="docutils literal"><span class="pre">M-x</span> <span class="pre">yas/tryout-snippet</span></tt></p>
<blockquote>
<p>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 <tt class="docutils literal"><span class="pre">C-c</span> <span class="pre">C-t</span></tt> while in
<tt class="docutils literal"><span class="pre">snippet-mode</span></tt>.</p>
</blockquote>
</li>
</ul>
<p>There are also <em>snippets for writing snippets</em>: <tt class="docutils literal">vars</tt>, <tt class="docutils literal">$f</tt> and
<tt class="docutils literal">$m</tt> :-).</p>
</div>
</div>
<div class="section" id="file-content">
<h1><a class="toc-backref" href="#id6">File content</a></h1>
<p>A file defining a snippet generally contains the template to be
expanded.</p>
<p>Optionally, if the file contains a line of <tt class="docutils literal"># <span class="pre">--</span></tt>, the lines above
it count as comments, some of which can be <em>directives</em> (or meta
data). Snippet directives look like <tt class="docutils literal"># property: value</tt> and tweak
certain snippets properties described below. If no <tt class="docutils literal"># <span class="pre">--</span></tt> is found,
the whole file is considered the snippet template.</p>
<p>Here's a typical example:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">#contributor : pluskid &lt;pluskid@gmail.com&gt;
#name : __...__
# --
__${init}__
</pre></div>
<p>Here's a list of currently supported directives:</p>
<div class="section" id="key-snippet-abbrev">
<h2><a class="toc-backref" href="#id7"><tt class="docutils literal"># key:</tt> snippet abbrev</a></h2>
<p>This is the probably the most important directive, it's the abbreviation you
type to expand a snippet just before hitting <tt class="docutils literal"><span class="pre">yas/trigger-key</span></tt>. If you don't
specify this the snippet will not be expandable through the key mechanism.</p>
</div>
<div class="section" id="name-snippet-name">
<h2><a class="toc-backref" href="#id8"><tt class="docutils literal"># name:</tt> snippet name</a></h2>
<p>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.</p>
<p>If you omit this name it will default to the file name the snippet was
loaded from.</p>
</div>
<div class="section" id="condition-snippet-condition">
<h2><a class="toc-backref" href="#id9"><tt class="docutils literal"># condition:</tt> snippet condition</a></h2>
<p>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.</p>
<p>See also <tt class="docutils literal"><span class="pre">yas/buffer-local-condition</span></tt> in <a class="reference external" href="snippet-expansion.html">Expanding snippets</a></p>
</div>
<div class="section" id="group-snippet-menu-grouping">
<h2><a class="toc-backref" href="#id10"><tt class="docutils literal"># group:</tt> snippet menu grouping</a></h2>
<p>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.</p>
<p>The <tt class="docutils literal"># group:</tt> property only affect menu construction (See <a class="reference external" href="snippet-menu.html">the
YASnippet menu</a>) and the same effect can be achieved by grouping
snippets into sub-directories and using the <tt class="docutils literal"><span class="pre">.yas-make-groups</span></tt>
special file (for this see <a class="reference external" href="snippet-organization.html">Organizing Snippets</a></p>
<p>Refer to the bundled snippets for <tt class="docutils literal"><span class="pre">ruby-mode</span></tt> for examples on the
<tt class="docutils literal"># group:</tt> directive. Group can also be nested, e.g. <tt class="docutils literal">control
structure.loops</tt> tells that the snippet is under the <tt class="docutils literal">loops</tt> group
which is under the <tt class="docutils literal">control structure</tt> group.</p>
</div>
<div class="section" id="expand-env-expand-environment">
<h2><a class="toc-backref" href="#id11"><tt class="docutils literal"># <span class="pre">expand-env:</span></tt> expand environment</a></h2>
<p>This is another piece of Emacs-lisp code in the form of a <tt class="docutils literal">let</tt>
<em>varlist form</em>, i.e. a list of lists assigning values to variables. It
can be used to override variable values while the snippet is being
expanded.</p>
<p>Interesting variables to override are <tt class="docutils literal"><span class="pre">yas/wrap-around-region</span></tt> and
<tt class="docutils literal"><span class="pre">yas/indent-line</span></tt> (see <a class="reference external" href="snippet-expansion.html">Expanding Snippets</a>).</p>
<p>As an example, you might normally have <tt class="docutils literal"><span class="pre">yas/indent-line</span></tt> set to
<tt class="docutils literal">'auto</tt> and <tt class="docutils literal"><span class="pre">yas/wrap-around-region</span></tt> set to <tt class="docutils literal">t</tt>, but for this
particularly brilliant piece of ASCII art these values would mess up
your hard work. You can then use:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"># name : ASCII home
# expand-env: ((yas/indent-line &#39;fixed) (yas/wrap-around-region &#39;nil))
# --
welcome to my
X humble
/ \ home,
/ \ $0
/ \
/-------\
| |
| +-+ |
| | | |
+--+-+--+
</pre></div>
</div>
<div class="section" id="binding-direct-keybinding">
<h2><a class="toc-backref" href="#id12"><tt class="docutils literal"># binding:</tt> direct keybinding</a></h2>
<p>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.</p>
<p>Additionally a variable <tt class="docutils literal">yas/prefix</tt> 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 &quot;html-mode&quot;
snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">#name : &lt;p&gt;...&lt;/p&gt;
#binding: C-c C-c C-m
# --
&lt;p&gt;`(when yas/prefix &quot;\n&quot;)`$0`(when yas/prefix &quot;\n&quot;)`&lt;/p&gt;
</pre></div>
<p>This binding will be recorded in the keymap
<tt class="docutils literal"><span class="pre">html-mode-map</span></tt>. To expand a paragraph tag newlines, just
press <tt class="docutils literal"><span class="pre">C-u</span> <span class="pre">C-c</span> <span class="pre">C-c</span> <span class="pre">C-m</span></tt>. Omitting the <tt class="docutils literal"><span class="pre">C-u</span></tt> will expand the
paragraph tag without newlines.</p>
</div>
<div class="section" id="contributor-snippet-author">
<h2><a class="toc-backref" href="#id13"><tt class="docutils literal"># contributor:</tt> snippet author</a></h2>
<p>This is optional and has no effect whatsoever on snippet
functionality, but it looks nice.</p>
</div>
</div>
<div class="section" id="template-syntax">
<h1><a class="toc-backref" href="#id14">Template syntax</a></h1>
<p>The syntax of the snippet template is simple but powerful, very
similar to TextMate's.</p>
<div class="section" id="plain-text">
<h2><a class="toc-backref" href="#id15">Plain Text</a></h2>
<p>Arbitrary text can be included as the content of a template. They are
usually interpreted as plain text, except <tt class="docutils literal">$</tt> and <tt class="docutils literal">`</tt>. You need to
use <tt class="docutils literal">\</tt> to escape them: <tt class="docutils literal">\$</tt> and <tt class="docutils literal">\`</tt>. The <tt class="docutils literal">\</tt> itself may also
needed to be escaped as <tt class="docutils literal">\\</tt> sometimes.</p>
</div>
<div class="section" id="embedded-emacs-lisp-code">
<h2><a class="toc-backref" href="#id16">Embedded Emacs-lisp code</a></h2>
<p>Emacs-Lisp code can be embedded inside the template, written inside
back-quotes (<tt class="docutils literal">`</tt>). The lisp forms are evaluated when the snippet is
being expanded. The evaluation is done in the same buffer as the
snippet being expanded.</p>
<p>Here's an example for <tt class="docutils literal"><span class="pre">c-mode</span></tt> to calculate the header file guard
dynamically:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
#define $1
$0
#endif /* $1 */
</pre></div>
<p>From version 0.6, snippets expansions are run with some special
Emacs-lisp variables bound. One of this is <tt class="docutils literal"><span class="pre">yas/selected-text</span></tt>. You
can therefore define a snippet like:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">for ($1;$2;$3) {
`yas/selected-text`$0
}
</pre></div>
<p>to &quot;wrap&quot; the selected region inside your recently inserted
snippet. Alternatively, you can also customize the variable
<tt class="docutils literal"><span class="pre">yas/wrap-around-region</span></tt> to <tt class="docutils literal">t</tt> which will do this automatically.</p>
</div>
<div class="section" id="tab-stop-fields">
<h2><a class="toc-backref" href="#id17">Tab stop fields</a></h2>
<p>Tab stops are fields that you can navigate back and forth by <tt class="docutils literal">TAB</tt>
and <tt class="docutils literal"><span class="pre">S-TAB</span></tt>. They are written by <tt class="docutils literal">$</tt> followed with a
number. <tt class="docutils literal">$0</tt> has the special meaning of the <em>exit point</em> of a
snippet. That is the last place to go when you've traveled all the
fields. Here's a typical example:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">&lt;div$1&gt;
$0
&lt;/div&gt;
</pre></div>
</div>
<div class="section" id="placeholder-fields">
<h2><a class="toc-backref" href="#id18">Placeholder fields</a></h2>
<p>Tab stops can have default values -- a.k.a placeholders. The syntax is
like this:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">${N:default value}
</pre></div>
<p>They acts as the default value for a tab stop. But when you firstly
type at a tab stop, the default value will be replaced by your
typing. The number can be omitted if you don't want to create
<a class="reference internal" href="#mirrors">mirrors</a> or <a class="reference internal" href="#transformations">transformations</a> for this field.</p>
</div>
<div class="section" id="id2">
<span id="mirrors"></span><h2><a class="toc-backref" href="#id19">Mirrors</a></h2>
<p>We refer the tab stops with placeholders as a <em>field</em>. A field can have
mirrors. Its mirrors will get updated when you change the text of a
field. Here's an example:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">\begin{${1:enumerate}}
$0
\end{$1}
</pre></div>
<p>When you type <tt class="docutils literal">&quot;document&quot;</tt> at <tt class="docutils literal">${1:enumerate}</tt>, the word
<tt class="docutils literal">&quot;document&quot;</tt> will also be inserted at <tt class="docutils literal"><span class="pre">\end{$1}</span></tt>. The best
explanation is to see the screencast(<a class="reference external" href="http://www.youtube.com/watch?v=vOj7btx3ATg">YouTube</a> or <a class="reference external" href="http://yasnippet.googlecode.com/files/yasnippet.avi">avi video</a>).</p>
<p>The tab stops with the same number to the field act as its mirrors. If
none of the tab stops has an initial value, the first one is selected
as the field and others mirrors.</p>
</div>
<div class="section" id="mirrors-with-transformations">
<span id="transformations"></span><h2><a class="toc-backref" href="#id20">Mirrors with transformations</a></h2>
<p>If the value of an <tt class="docutils literal">${n:</tt>-construct starts with and contains <tt class="docutils literal">$(</tt>,
then it is interpreted as a mirror for field <tt class="docutils literal">n</tt> with a
transformation. The mirror's text content is calculated according to
this transformation, which is Emacs-lisp code that gets evaluated in
an environment where the variable <tt class="docutils literal">text</tt> (or <tt class="docutils literal">yas/text</tt>) is bound
to the text content (string) contained in the field <tt class="docutils literal">n</tt>.Here's an
example for Objective-C:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">- (${1:id})${2:foo}
{
return $2;
}
- (void)set${2:$(capitalize text)}:($1)aValue
{
[$2 autorelease];
$2 = [aValue retain];
}
$0
</pre></div>
<p>Look at <tt class="docutils literal"><span class="pre">${2:$(capitalize</span> text)}</tt>, it is a mirror with
transformation instead of a field. The actual field is at the first
line: <tt class="docutils literal">${2:foo}</tt>. When you type text in <tt class="docutils literal">${2:foo}</tt>, the
transformation will be evaluated and the result will be placed there
as the transformed text. So in this example, if you type &quot;baz&quot; in the
field, the transformed text will be &quot;Baz&quot;. This example is also
available in the screencast.</p>
<p>Another example is for <tt class="docutils literal"><span class="pre">rst-mode</span></tt>. In reStructuredText, the document
title can be some text surrounded by &quot;===&quot; below and above. The &quot;===&quot;
should be at least as long as the text. So</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">=====
Title
=====
</pre></div>
<p>is a valid title but</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">===
Title
===
</pre></div>
<p>is not. Here's an snippet for rst title:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">${1:$(make-string (string-width text) ?\=)}
${1:Title}
${1:$(make-string (string-width text) ?\=)}
$0
</pre></div>
</div>
<div class="section" id="fields-with-transformations">
<h2><a class="toc-backref" href="#id21">Fields with transformations</a></h2>
<p>From version 0.6 on, you can also have lisp transformation inside
fields. These work mostly mirror transformations but are evaluated
when you first enter the field, after each change you make to the
field and also just before you exit the field.</p>
<p>The syntax is also a tiny bit different, so that the parser can
distinguish between fields and mirrors. In the following example</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">#define &quot;${1:mydefine$(upcase yas/text)}&quot;
</pre></div>
<p><tt class="docutils literal">mydefine</tt> gets automatically upcased to <tt class="docutils literal">MYDEFINE</tt> once you enter
the field. As you type text, it gets filtered through the
transformation every time.</p>
<p>Note that to tell this kind of expression from a mirror with a
transformation, YASnippet needs extra text between the <tt class="docutils literal">:</tt> and the
transformation's <tt class="docutils literal">$</tt>. If you don't want this extra-text, you can use
two <tt class="docutils literal">$</tt>'s instead.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">#define &quot;${1:$$(upcase yas/text)}&quot;
</pre></div>
<p>Please note that as soon as a transformation takes place, it changes
the value of the field and sets it its internal modification state to
<tt class="docutils literal">true</tt>. As a consequence, the auto-deletion behaviour of normal
fields does not take place. This is by design.</p>
</div>
<div class="section" id="choosing-fields-value-from-a-list-and-other-tricks">
<h2><a class="toc-backref" href="#id22">Choosing fields value from a list and other tricks</a></h2>
<p>As mentioned, the field transformation is invoked just after you enter
the field, and with some useful variables bound, notably
<tt class="docutils literal"><span class="pre">yas/field-modified-p</span></tt> and <tt class="docutils literal"><span class="pre">yas/moving-away-p</span></tt>. Because of this
feature you can place a transformation in the primary field that lets
you select default values for it.</p>
<p>The <tt class="docutils literal"><span class="pre">yas/choose-value</span></tt> does this work for you. For example:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">&lt;div align=&quot;${2:$$(yas/choose-value &#39;(&quot;right&quot; &quot;center&quot; &quot;left&quot;))}&quot;&gt;
$0
&lt;/div&gt;
</pre></div>
<p>See the definition of <tt class="docutils literal"><span class="pre">yas/choose-value</span></tt> to see how it was written
using the two variables.</p>
<p>Here's another use, for LaTeX-mode, which calls reftex-label just as
you enter snippet field 2. This one makes use of <tt class="docutils literal"><span class="pre">yas/modified-p</span></tt>
directly.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">\section{${1:&quot;Titel der Tour&quot;}}%
\index{$1}%
\label{{2:&quot;waiting for reftex-label call...&quot;$(unless yas/modified-p (reftex-label nil &#39;dont-
insert))}}%
</pre></div>
<p>The function <tt class="docutils literal"><span class="pre">yas/verify-value</span></tt> has another neat trick, and makes
use of <tt class="docutils literal"><span class="pre">yas/moving-away-p</span></tt>. Try it and see! Also, check out this
<a class="reference external" href="http://groups.google.com/group/smart-snippet/browse_thread/thread/282a90a118e1b662">thread</a></p>
</div>
<div class="section" id="nested-placeholder-fields">
<h2><a class="toc-backref" href="#id23">Nested placeholder fields</a></h2>
<p>From version 0.6 on, you can also have nested placeholders of the type:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">&lt;div${1: id=&quot;${2:some_id}&quot;}&gt;$0&lt;/div&gt;
</pre></div>
<p>This allows you to choose if you want to give this <tt class="docutils literal">div</tt> an <tt class="docutils literal">id</tt>
attribute. If you tab forward after expanding it will let you change
&quot;some_id&quot; to whatever you like. Alternatively, you can just press
<tt class="docutils literal"><span class="pre">C-d</span></tt> (which executes <tt class="docutils literal"><span class="pre">yas/skip-and-clear-or-delete-char</span></tt>) and go
straight to the exit marker.</p>
<p>By the way, <tt class="docutils literal"><span class="pre">C-d</span></tt> will only clear the field if you cursor is at the
beginning of the field <em>and</em> it hasn't been changed yet. Otherwise, it
performs the normal Emacs <tt class="docutils literal"><span class="pre">delete-char</span></tt> command.</p>
</div>
</div>
<div class="section" id="customizable-variables">
<h1><a class="toc-backref" href="#id24">Customizable variables</a></h1>
<div class="section" id="yas-trigger-key">
<h2><a class="toc-backref" href="#id25"><tt class="docutils literal"><span class="pre">yas/trigger-key</span></tt></a></h2>
<p>The key bound to <tt class="docutils literal">yas/expand</tt> when function <tt class="docutils literal"><span class="pre">yas/minor-mode</span></tt> is
active.</p>
<p>Value is a string that is converted to the internal Emacs key
representation using <tt class="docutils literal"><span class="pre">read-kbd-macro</span></tt>.</p>
<p>Default value is <tt class="docutils literal">&quot;TAB&quot;</tt>.</p>
</div>
<div class="section" id="yas-next-field-key">
<h2><a class="toc-backref" href="#id26"><tt class="docutils literal"><span class="pre">yas/next-field-key</span></tt></a></h2>
<p>The key to navigate to next field when a snippet is active.</p>
<p>Value is a string that is converted to the internal Emacs key
representation using <tt class="docutils literal"><span class="pre">read-kbd-macro</span></tt>.</p>
<p>Can also be a list of keys.</p>
<p>Default value is <tt class="docutils literal">&quot;TAB&quot;</tt>.</p>
</div>
<div class="section" id="yas-prev-field-key">
<h2><a class="toc-backref" href="#id27"><tt class="docutils literal"><span class="pre">yas/prev-field-key</span></tt></a></h2>
<p>The key to navigate to previous field when a snippet is active.</p>
<p>Value is a string that is converted to the internal Emacs key
representation using <tt class="docutils literal"><span class="pre">read-kbd-macro</span></tt>.</p>
<p>Can also be a list of keys.</p>
<p>Default value is <tt class="docutils literal"><span class="pre">(&quot;&lt;backtab&gt;&quot;</span> <span class="pre">&quot;&lt;S-tab&gt;)&quot;</span></tt>.</p>
</div>
<div class="section" id="yas-skip-and-clear-key">
<h2><a class="toc-backref" href="#id28"><tt class="docutils literal"><span class="pre">yas/skip-and-clear-key</span></tt></a></h2>
<p>The key to clear the currently active field.</p>
<p>Value is a string that is converted to the internal Emacs key
representation using <tt class="docutils literal"><span class="pre">read-kbd-macro</span></tt>.</p>
<p>Can also be a list of keys.</p>
<p>Default value is <tt class="docutils literal"><span class="pre">&quot;C-d&quot;</span></tt>.</p>
</div>
<div class="section" id="yas-good-grace">
<h2><a class="toc-backref" href="#id29"><tt class="docutils literal"><span class="pre">yas/good-grace</span></tt></a></h2>
<p>If non-nil, don't raise errors in inline Emacs-lisp evaluation inside
snippet definitions. An error string &quot;[yas] error&quot; is returned instead.</p>
</div>
<div class="section" id="yas-indent-line">
<h2><a class="toc-backref" href="#id30"><tt class="docutils literal"><span class="pre">yas/indent-line</span></tt></a></h2>
<p>The variable <tt class="docutils literal"><span class="pre">yas/indent-line</span></tt> controls the indenting. It is bound
to <tt class="docutils literal">'auto</tt> by default, which causes your snippet to be indented
according to the mode of the buffer it was inserted in.</p>
<p>Another variable <tt class="docutils literal"><span class="pre">yas/also-auto-indent-first-line</span></tt>, when non-nil
does exactly that :-).</p>
<p>To use the hard-coded indentation in your snippet template, set this
variable to <tt class="docutils literal">fixed</tt>.</p>
<p>To control indentation on a per-snippet basis, see also the directive
<tt class="docutils literal"># <span class="pre">expand-env:</span></tt> in <a class="reference external" href="snippet-development.html">Writing Snippets</a>.</p>
<p>For backward compatibility with earlier versions of YASnippet, you can
also place a <tt class="docutils literal">$&gt;</tt> in your snippet, an <tt class="docutils literal"><span class="pre">(indent-according-to-mode)</span></tt>
will be executed there to indent the line. This only takes effect when
<tt class="docutils literal"><span class="pre">yas/indent-line</span></tt> is set to something other than <tt class="docutils literal">'auto</tt>.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">for (${int i = 0}; ${i &lt; 10}; ${++i})
{$&gt;
$0$&gt;
}$&gt;
</pre></div>
</div>
<div class="section" id="yas-wrap-around-region">
<h2><a class="toc-backref" href="#id31"><tt class="docutils literal"><span class="pre">yas/wrap-around-region</span></tt></a></h2>
<p>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 <tt class="docutils literal"><span class="pre">`yas/selected-text`</span></tt> inline
evaluation.</p>
<p>Because on most systems starting to type deletes the currently
selected region, this works mostly for snippets with direct
keybindings or with the <tt class="docutils literal"><span class="pre">yas/insert-snippet</span></tt> command.</p>
<p>However, when the value is of this variable is <tt class="docutils literal">cua</tt> 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 <tt class="docutils literal"><span class="pre">yas/trigger-key</span></tt> to see the deleted region
spring back to life inside your new snippet.</p>
</div>
<div class="section" id="yas-triggers-in-field">
<h2><a class="toc-backref" href="#id32"><tt class="docutils literal"><span class="pre">yas/triggers-in-field</span></tt></a></h2>
<p>If non-nil, <tt class="docutils literal"><span class="pre">yas/next-field-key</span></tt> can trigger stacked expansions,
that is a snippet expansion inside another snippet
expansion. Otherwise, <tt class="docutils literal"><span class="pre">yas/next-field-key</span></tt> just tries to move on to
the next field.</p>
</div>
<div class="section" id="yas-snippet-revival">
<h2><a class="toc-backref" href="#id33"><tt class="docutils literal"><span class="pre">yas/snippet-revival</span></tt></a></h2>
<p>Non-nil means re-activate snippet fields after undo/redo.</p>
</div>
<div class="section" id="yas-after-exit-snippet-hook-and-yas-before-expand-snippet-hook">
<h2><a class="toc-backref" href="#id34"><tt class="docutils literal"><span class="pre">yas/after-exit-snippet-hook</span></tt> and <tt class="docutils literal"><span class="pre">yas/before-expand-snippet-hook</span></tt></a></h2>
<p>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.</p>
</div>
</div>
<div class="section" id="importing-textmate-snippets">
<h1><a class="toc-backref" href="#id35">Importing TextMate snippets</a></h1>
<p>There are a couple of tools that take TextMate's &quot;.tmSnippet&quot; xml
files and create YASnippet definitions:</p>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://code.nokrev.com/?p=snippet-copier.git;a=blob_plain;f=snippet_copier.py">a python script by Jeff Wheeler</a></li>
<li>a <a class="reference external" href="http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb">ruby tool</a>
, <tt class="docutils literal">textmate_import.rb</tt> adapted from <a class="reference external" href="http://www.neutronflux.net/2009/07/28/shoulda-snippets-for-emacs/">Rob Christie's</a>,
which I have uploaded to the repository.</li>
</ul>
</blockquote>
<p>In this section, i'll shortly cover the <strong>second</strong> option.</p>
<p>Download the <tt class="docutils literal">textmate_import.rb</tt> tool and the TextMate
bundle you're interested in.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">$ curl -O http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb
$ svn export http://svn.textmate.org/trunk/Bundles/HTML.tmbundle/
</pre></div>
<p>Then invoke <tt class="docutils literal">textmate_import.rb</tt> like this:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">$ ./textmate_import.rb -d HTML.tmbundle/Snippets/ -o html-mode -g HTML.tmbundle/info.plist
</pre></div>
<p>You should end up with a <tt class="docutils literal"><span class="pre">html-mode</span></tt> subdir containing snippets
exported from textmate.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%">$ tree html-mode # to view dir contents, if you have &#39;tree&#39; installed
</pre></div>
<p>The <tt class="docutils literal"><span class="pre">-g</span></tt> is optional but helps the tool figure out the grouping.
According to <a class="reference external" href="snippet-organization.html">Organizing Snippets</a>, don't forget to touch
<tt class="docutils literal"><span class="pre">.yas-make-groups</span></tt> and <tt class="docutils literal"><span class="pre">.yas-ignore-filename-triggers</span></tt> inside the
<tt class="docutils literal"><span class="pre">html-mode</span></tt> dir.</p>
<p>Also try <tt class="docutils literal">textmate_import.rb <span class="pre">--help</span></tt> for a list of options.</p>
<p>Please note that snippet importation is not yet perfect. You'll
probably have some adjustments to some/many snippets. Please
contribute these adjustments to the google group or, better yet, patch
the <tt class="docutils literal">textmate_import.rb</tt> to automatically perform them and submit
that.</p>
<!-- LocalWords: html YASnippet yas sourcecode pluskid init filenames filename -->
<!-- LocalWords: env varlist keybinding keymap rinari ifndef upcase endif -->
<!-- LocalWords: nondirectory autorelease aValue inline -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-10536822-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
</div>
</body>
</html>