yasnippet/doc/snippet-organization.html
2009-08-19 16:19:06 +00:00

326 lines
17 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.6: http://docutils.sourceforge.net/" />
<title>Organizing snippets</title>
<meta name="author" content="pluskid, joaotavora" />
<meta name="date" content="2009-08-18" />
<link rel="stylesheet" href="styles.css" type="text/css" />
</head>
<body>
<div class="document" id="organizing-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">Organizing snippets</h1>
</div>
<ul class="primary-links">
<li>
<a title="" href="index.html">Home</a>
</li>
<li>
<a title="" href="snippet-organization.html">Organize</a>
</li>
<li>
<a title="" href="snippet-expansion.html">Expand</a>
</li>
<li>
<a title="" href="snippet-development.html">Write</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">
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#new-style-storage-recommended" id="id1">New-style storage (recommended)</a></li>
<li><a class="reference internal" href="#old-style-storage-pre-0-6" id="id2">Old-style storage (pre 0.6)</a></li>
<li><a class="reference internal" href="#no-storage-bundle" id="id3">No storage (bundle)</a></li>
<li><a class="reference internal" href="#define-snippets-in-files" id="id4">Define snippets in files</a><ul>
<li><a class="reference internal" href="#directory-hierarchy" id="id5">Directory hierarchy</a></li>
<li><a class="reference internal" href="#define-snippets-using-elisp-code" id="id6">Define snippets using elisp code</a><ul>
<li><a class="reference internal" href="#yas-define-snippets" id="id7">yas/define-snippets</a></li>
<li><a class="reference internal" href="#yas-define" id="id8">yas/define</a></li>
<li><a class="reference internal" href="#yas-compile-bundle" id="id9">yas/compile-bundle</a></li>
<li><a class="reference internal" href="#the-menu" id="id10">The Menu</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<p>There are three ways to keep your snippets:</p>
<div class="section" id="new-style-storage-recommended">
<h1><a class="toc-backref" href="#id1">New-style storage (recommended)</a></h1>
<p>Hehe</p>
</div>
<div class="section" id="old-style-storage-pre-0-6">
<h1><a class="toc-backref" href="#id2">Old-style storage (pre 0.6)</a></h1>
<p>Blabla</p>
</div>
<div class="section" id="no-storage-bundle">
<h1><a class="toc-backref" href="#id3">No storage (bundle)</a></h1>
<p>The most convenient way to define snippets for YASnippet is to put
them in a directory arranged by the mode and use
<tt class="docutils literal"><span class="pre">yas/load-directory</span></tt> to load them.</p>
<p>However, this might slow down the Emacs startup speed if you have many
snippets. You can use <tt class="docutils literal"><span class="pre">yas/define-snippets</span></tt> to define a bunch of
snippets for a perticular mode. But this is hard to maintain! So,
there's a better way: define your snippets in directory and use
<tt class="docutils literal"><span class="pre">yas/compile-bundle</span></tt> to compile it into a bundle file when you
modified your snippets.</p>
<p>The release bundle of YASnippet is produced by
<tt class="docutils literal"><span class="pre">yas/compile-bundle</span></tt>. The bundle use <tt class="docutils literal"><span class="pre">yas/define-snippets</span></tt> to
define snippets. This avoid the IO and parsing overhead when loading
snippets.</p>
<p>Finally, you can use <tt class="docutils literal"><span class="pre">yas/define</span></tt> to define a single snippet at your
convenience. I ofthen use this to do some testing.</p>
</div>
<div class="section" id="define-snippets-in-files">
<h1><a class="toc-backref" href="#id4">Define snippets in files</a></h1>
<div class="section" id="directory-hierarchy">
<h2><a class="toc-backref" href="#id5">Directory hierarchy</a></h2>
<p>Here's the directory hierarchy of the <tt class="docutils literal"><span class="pre">snippets</span></tt> directory comes
with YASnippet:</p>
<div class="highlight"><pre>snippets
`-- text-mode/
|-- cc-mode/
| |-- c++-mode/
| | |-- beginend
| | |-- class
| | `-- using
| |-- c-mode/
| | `-- fopen
| |-- do
| |-- for
| |-- if
| |-- inc
| |-- inc.1
| |-- main
| |-- once
| `-- struct
|-- css-mode/
| |-- background
| |-- background.1
| `-- border
|-- email
|-- html-mode/
| |-- div
| |-- doctype
| |-- doctype.xhml1
| |-- doctype.xhtml1_1
| |-- doctype.xhtml1_strict
| `-- doctype.xhtml1_transitional
|-- objc-mode/
| `-- prop
|-- perl-mode/
| |-- cperl-mode/
| |-- eval
| |-- for
| |-- fore
| |-- if
| |-- ife
| |-- ifee
| |-- sub
| |-- unless
| |-- while
| |-- xfore
| |-- xif
| |-- xunless
| `-- xwhile
|-- python-mode/
| |-- __
| |-- class
| |-- def
| |-- for
| |-- ifmain
| `-- while
|-- rst-mode/
| |-- chapter
| |-- section
| `-- title
|-- ruby-mode/
| |-- #
| |-- =b
| |-- Comp
| |-- all
| |-- am
| |-- any
| |-- app
| |-- bm
| |-- case
| |-- cla
| |-- classify
| |-- cls
| |-- collect
| |-- dee
| |-- deli
| |-- det
| |-- ea
| |-- eac
| |-- eai
| |-- eav
| |-- eawi
| |-- forin
| |-- if
| |-- ife
| |-- inject
| |-- mm
| |-- r
| |-- rb
| |-- reject
| |-- req
| |-- rreq
| |-- rw
| |-- select
| |-- w
| |-- y
| `-- zip
`-- time
</pre></div>
<p>Snippet definitions are put in plain text files. They are arranged by
subdirectories. For example, snippets for <tt class="docutils literal"><span class="pre">c-mode</span></tt> are put in the
<tt class="docutils literal"><span class="pre">c-mode</span></tt> directory.</p>
<p>The parent directory acts as the <em>parent mode</em>. This is the way of
YASnippet to share snippet definitions among different modes. As you
can see above, <tt class="docutils literal"><span class="pre">c-mode</span></tt> and <tt class="docutils literal"><span class="pre">c++-mode</span></tt> share the same parents
<tt class="docutils literal"><span class="pre">cc-mode</span></tt>, while all modes are derived from <tt class="docutils literal"><span class="pre">text-mode</span></tt>. This can
be also used to as an <em>alias</em> -- <tt class="docutils literal"><span class="pre">cperl-mode</span></tt> is an empty directory
whose parent is <tt class="docutils literal"><span class="pre">perl-mode</span></tt>.</p>
<p>File names act as the snippet trigger key. Note files starting with a
dot (<tt class="docutils literal"><span class="pre">.</span></tt>) are ignored.</p>
</div>
<div class="section" id="define-snippets-using-elisp-code">
<h2><a class="toc-backref" href="#id6">Define snippets using elisp code</a></h2>
<p>As I mentioned above, you can define snippets directly by writing
elisp code.</p>
<div class="section" id="yas-define-snippets">
<h3><a class="toc-backref" href="#id7">yas/define-snippets</a></h3>
<p>The basic syntax of <tt class="docutils literal"><span class="pre">yas/define-snippets</span></tt> is</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/define-snippets</span> <span style="color: #19177C">MODE</span> <span style="color: #19177C">SNIPPETS</span> <span style="color: #008000; font-weight: bold">&amp;optional</span> <span style="color: #19177C">PARENT</span>)
</pre></div>
<p>The parameters are self-descriptive. If you specify a <tt class="docutils literal"><span class="pre">PARENT</span></tt>, then
the snippets of the parents may be shared by <tt class="docutils literal"><span class="pre">MODE</span></tt>. Note if you use
this function several times, the later specified <tt class="docutils literal"><span class="pre">PARENT</span></tt> will
overwrite the original one. However, not specifying a <tt class="docutils literal"><span class="pre">PARENT</span></tt> won't
erase the original parent.</p>
<p>The <tt class="docutils literal"><span class="pre">SNIPPETS</span></tt> parameter is a list of snippet definitions. Each
element should have the following form:</p>
<div class="highlight"><pre>(<span style="color: #19177C">KEY</span> <span style="color: #19177C">TEMPLATE</span> <span style="color: #19177C">NAME</span> <span style="color: #19177C">CONDITION</span> <span style="color: #19177C">GROUP</span>)
</pre></div>
<p>The <tt class="docutils literal"><span class="pre">NAME</span></tt>, <tt class="docutils literal"><span class="pre">CONDITION</span></tt> and <tt class="docutils literal"><span class="pre">GROUP</span></tt> can be omitted if you don't
want to provide one. Here's an example:</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/define-snippets</span> <span style="color: #19177C">&#39;c++-mode</span>
<span style="color: #666666">&#39;</span>(
(<span style="color: #BA2121">&quot;using&quot;</span> <span style="color: #BA2121">&quot;using namespace ${std};</span>
<span style="color: #BA2121">$0&quot;</span> <span style="color: #BA2121">&quot;using namespace ... &quot;</span> <span style="color: #880000">nil</span>)
(<span style="color: #BA2121">&quot;class&quot;</span> <span style="color: #BA2121">&quot;class ${1:Name}</span>
<span style="color: #BA2121">{</span>
<span style="color: #BA2121">public:</span>
<span style="color: #BA2121"> $1($2);</span>
<span style="color: #BA2121"> virtual ~$1();</span>
<span style="color: #BA2121">};&quot;</span> <span style="color: #BA2121">&quot;class ... { ... }&quot;</span> <span style="color: #880000">nil</span>)
(<span style="color: #BA2121">&quot;beginend&quot;</span> <span style="color: #BA2121">&quot;${1:v}.begin(), $1.end&quot;</span> <span style="color: #BA2121">&quot;v.begin(), v.end()&quot;</span> <span style="color: #880000">nil</span>)
)
<span style="color: #19177C">&#39;cc-mode</span>)
</pre></div>
<p>The example above is auto-generated code by <tt class="docutils literal"><span class="pre">yas/compile-bundle</span></tt>.</p>
</div>
<div class="section" id="yas-define">
<h3><a class="toc-backref" href="#id8">yas/define</a></h3>
<p>The basic syntax for <tt class="docutils literal"><span class="pre">yas/define</span></tt> is</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/define</span> <span style="color: #19177C">mode</span> <span style="color: #19177C">key</span> <span style="color: #19177C">template</span> <span style="color: #008000; font-weight: bold">&amp;optional</span> <span style="color: #19177C">name</span> <span style="color: #B00040">condition</span> <span style="color: #19177C">group</span>)
</pre></div>
<p>This is only a syntax sugar for</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/define-snippets</span> <span style="color: #19177C">mode</span>
(<span style="color: #008000">list</span> (<span style="color: #008000">list</span> <span style="color: #19177C">key</span> <span style="color: #19177C">template</span> <span style="color: #19177C">name</span> <span style="color: #B00040">condition</span> <span style="color: #19177C">group</span>)))
</pre></div>
</div>
<div class="section" id="yas-compile-bundle">
<h3><a class="toc-backref" href="#id9">yas/compile-bundle</a></h3>
<p><tt class="docutils literal"><span class="pre">yas/compile-bundle</span></tt> can be used to parse the snippets from a
directory hierarchy and translate them into the elisp form. The
translated code is faster to load. Further more, the generated bundle
is a stand-alone file not depending on <tt class="docutils literal"><span class="pre">yasnippet.el</span></tt>. The released
bundles of YASnippet are all generated this way.</p>
</div>
<div class="section" id="the-menu">
<h3><a class="toc-backref" href="#id10">The Menu</a></h3>
<p>YASnippet will setup a menu just after the <em>Buffers</em> Menu in the
menubar. The snippets for all <em>real</em> modes are listed there under the
menu. You can select a snippet from the menu to expand it. Since you
select manually from the menu, you can expand any snippet. For
example, you can expand a snippet defined for <tt class="docutils literal"><span class="pre">python-mode</span></tt> in a
<tt class="docutils literal"><span class="pre">c-mode</span></tt> buffer by selecting it from the menu:</p>
<img align="right" alt="images/menubar.png" class="align-right" src="images/menubar.png" />
<ul class="simple">
<li>Condition system is ignored since you select to expand it
explicitly.</li>
<li>There will be no muliple candidates since they are listed in the
menu as different items.</li>
</ul>
<p>This can be convenient sometimes. However, if you don't like the
menubar of Emacs and never use it. You can tell YASnippet don't boring
to build a menu by setting <tt class="docutils literal"><span class="pre">yas/use-menu</span></tt> to nil.</p>
<p>Another thing to note is that only <em>real</em> modes are listed under the
menu. As you know, common snippets can be shared by making up a
<em>virtual</em> parent mode. It's too bad if the menu is floored by those
<em>virtual</em> modes. So YASnippet only show menus for those <em>real</em>
modes. But the snippets fo the <em>virtual</em> modes can still be accessed
through the <tt class="docutils literal"><span class="pre">parent</span></tt> submenu of some <em>real</em> mode.</p>
<p>YASnippet use a simple way to check whether a mode is <em>real</em> or
<em>virtual</em>: <tt class="docutils literal"><span class="pre">(fboundp</span> <span class="pre">mode)</span></tt>. For example, the symbol <tt class="docutils literal"><span class="pre">c-mode</span></tt> is
bound to a function while <tt class="docutils literal"><span class="pre">cc-mode</span></tt> is not. But this is not enough,
some modes aren't part of Emacs, and maybe when initializing
YASnippet, those modes haven't been initialized. So YASnippet also
maintain a list of known modes (<tt class="docutils literal"><span class="pre">yas/known-modes</span></tt>). You can add item
to that list if you need.</p>
<p>The basic syntax of <tt class="docutils literal"><span class="pre">yas/compile-bundle</span></tt> is</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/compile-bundle</span> <span style="color: #008000; font-weight: bold">&amp;optional</span> <span style="color: #19177C">yasnippet</span> <span style="color: #19177C">yasnippet-bundle</span> <span style="color: #19177C">snippet-roots</span> <span style="color: #19177C">code</span> <span style="color: #19177C">dropdown</span>)
</pre></div>
<p>As you can see, all the parameters are optional. The default values
for those parameters are convenient for me to produce the default
release bundle:</p>
<div class="highlight"><pre>(<span style="color: #19177C">yas/compile-bundle</span> <span style="color: #BA2121">&quot;yasnippet.el&quot;</span>
<span style="color: #BA2121">&quot;./yasnippet-bundle.el&quot;</span>
<span style="color: #666666">&#39;</span>(<span style="color: #BA2121">&quot;snippets&quot;</span>)
<span style="color: #BA2121">&quot;(yas/initialize)&quot;</span>
<span style="color: #BA2121">&quot;dropdown-list.el&quot;</span>)
</pre></div>
<p>The <tt class="docutils literal"><span class="pre">snippet-roots</span></tt> can be a list of root directories. This is
useful when you have multiple snippet directories (maybe from other
users). The <tt class="docutils literal"><span class="pre">code</span></tt> parameter can be used to specify your own
customization code instead of the default <tt class="docutils literal"><span class="pre">(yas/initialize)</span></tt>. For
example, you can set <tt class="docutils literal"><span class="pre">yas/trigger-key</span></tt> to <tt class="docutils literal"><span class="pre">(kbd</span> <span class="pre">&quot;SPC&quot;)</span></tt> here if
you like.</p>
<p>From release 0.6 you have to specify the <tt class="docutils literal"><span class="pre">dropdown-list.el</span></tt> file if
you want it to be a part of the generated bundle.</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>