#+SETUPFILE: org-setup.inc
-* Writing snippets
+#+TITLE: Writing snippets
-** Snippet development
+* Snippet development
-*** Quickly finding snippets
+** Quickly finding snippets
-There are some ways you can quickly find a snippet file:
+There are some ways you can quickly find a snippet file or create a new one:
- =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.
+ Creates a new buffer with a template for making a new snippet.
+ The buffer is in =snippet-mode= (see below). When you are done
+ editing the new snippet, use =C-c C-c= to save it. This will
+ prompt for a directory two steps: first, the snippet table
+ (with a default based on the major mode you started in), and then
+ then snippet collection directory (defaults to the first directory
+ in =yas-snippet-dirs=. (See [[file:snippet-organization.org][Organizing Snippets]]
+ for more detail on how snippets are organized.)
- =M-x yas-find-snippets=
Once you find this file it will be set to =snippet-mode= (see ahead) and
you can start editing your snippet.
-*** Using the =snippet-mode= major mode
+** Using the =snippet-mode= major mode
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
There are also /snippets for writing snippets/: =vars=, =$f= and =$m=
:-).
-** File content
+* File content
A file defining a snippet generally contains the template to be
expanded.
Here's a list of currently supported directives:
-*** =# key:= snippet abbrev
+** =# key:= snippet abbrev
-This is the probably the most important directive, it's the abbreviation
-you type to expand a snippet just before hitting [[sym:yas-trigger-key][=yas-trigger-key=]]. If
-you don't specify this the snippet will not be expandable through the
-key mechanism.
+This is the probably the most important directive, it's the
+abbreviation you type to expand a snippet just before hitting the key
+that runs [[sym:yas-expand][=yas-expand=]]. If you don't specify this
+the snippet will not be expandable through the trigger mechanism.
-*** =# name:= snippet name
+** =# 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 --
If you omit this name it will default to the file name the snippet was
loaded from.
-*** =# condition:= snippet condition
+** =# 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
See also [[sym:yas-buffer-local-condition][=yas-buffer-local-condition=]] in
[[./snippet-expansion.org][Expanding snippets]]
-*** =# group:= snippet menu grouping
+** =# 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
=control structure.loops= tells that the snippet is under the =loops=
group which is under the =control structure= group.
-*** =# expand-env:= expand environment
+** =# 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
+--+-+--+
#+END_SRC
-*** =# binding:= direct keybinding
+** =# 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
paragraph tag newlines, just press =C-u C-c C-c C-m=. Omitting the =C-u=
will expand the paragraph tag without newlines.
-*** =# contributor:= snippet author
+** =# type:= =snippet= or =command=
+
+If the =type= directive is set to =command=, the body of the snippet
+is interpreted as lisp code to be evaluated when the snippet is
+triggered.
+
+If it's =snippet= (the default when there is no =type= directive), the
+snippet body will be parsed according to the [[Template Syntax]],
+described below.
+
+** =# uuid:= unique identifier
+
+This provides to a way to identify a snippet, independent of its name.
+Loading a second snippet file with the same uuid would replace the
+previous snippet.
+
+** =# contributor:= snippet author
This is optional and has no effect whatsoever on snippet functionality,
but it looks nice.
-** Template syntax
+* Template Syntax
The syntax of the snippet template is simple but powerful, very similar
to TextMate's.
-*** Plain Text
+** Plain Text
Arbitrary text can be included as the content of a template. They are
-usually interpreted as plain text, except =$= and ==. You need to
-use \` to escape them: =\$= and =\=. The \` itself may also needed to be
+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 Emacs-lisp code
+** Embedded Emacs-lisp code
Emacs-Lisp code can be embedded inside the template, written inside
-back-quotes (==). The lisp forms are evaluated when the snippet is
+back-quotes (=`=). The lisp forms are evaluated when the snippet is
being expanded. The evaluation is done in the same buffer as the
-snippet being expanded.
+snippet being expanded.
Here's an example for c-mode` to calculate the header file guard
dynamically:
#+BEGIN_SRC snippet
#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
#define $1
-
+
$0
-
+
#endif /* $1 */
#+END_SRC
Alternatively, you can also customize the variable
[[sym:yas-wrap-around-region][=yas-wrap-around-region=]] to =t= which will do this automatically.
-*** Tab stop fields
+** Tab stop fields
Tab stops are fields that you can navigate back and forth by =TAB= and
=S-TAB=. They are written by =$= followed with a number. =$0= has the
$0
</div>
#+END_SRC
-*** Placeholder fields
+** Placeholder fields
Tab stops can have default values -- a.k.a placeholders. The syntax is
like this:
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 [[mirrors]] or
-[[transformations]] for this field.
+The number can be omitted if you don't want to create [[mirrors-fields][mirrors]] or
+[[mirror-transformations][transformations]] for this field.
-*** <<Mirrors>>
+** Mirrors <<mirrors-fields>>
We refer the tab stops with placeholders as a /field/. A field can have
mirrors. Its mirrors will get updated when you change the text of a
none of the tab stops has an initial value, the first one is selected as
the field and others mirrors.
-*** Mirrors with <<transformations>>
+** Mirrors with transformations <<mirror-transformations>>
-If the value of an =${n:=-construct starts with and contains =$(=, then
-it is interpreted as a mirror for field =n= 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 =text= (or [[sym:yas-text][=yas-text=]]) is bound to the text content (string)
-contained in the field =n=.Here's an example for Objective-C:
+If the value of an =${n:=-construct starts with and contains =$(=,
+then it is interpreted as a mirror for field =n= 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 [[sym:yas-text][=yas-text=]] is bound to the text
+content (string) contained in the field =n=. Here's an example for
+Objective-C:
#+BEGIN_SRC snippet
- (${1:id})${2:foo}
{
return $2;
}
-
- - (void)set${2:$(capitalize text)}:($1)aValue
+
+ - (void)set${2:$(capitalize yas-text)}:($1)aValue
{
[$2 autorelease];
$2 = [aValue retain];
$0
#+END_SRC
-Look at =${2:$(capitalize text)}=, it is a mirror with transformation
-instead of a field. The actual field 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 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.
+Look at =${2:$(capitalize yas-text)}=, it is a mirror with
+transformation instead of a field. The actual field 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
+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
title can be some text surrounded by "===" below and above. The "==="
is not. Here's an snippet for rst title:
#+BEGIN_SRC snippet
- ${1:$(make-string (string-width text) ?\=)}
+ ${1:$(make-string (string-width yas-text) ?\=)}
${1:Title}
- ${1:$(make-string (string-width text) ?\=)}
-
+ ${1:$(make-string (string-width yas-text) ?\=)}
+
$0
#+END_SRC
-*** Fields with transformations
+** Fields with transformations
From version 0.6 on, you can also have lisp transformation inside
fields. These work mostly mirror transformations but are evaluated when
=true=. As a consequence, the auto-deletion behaviour of normal fields
does not take place. This is by design.
-*** Choosing fields value from a list and other tricks
+** Choosing fields value from a list and other tricks
As mentioned, the field transformation is invoked just after you enter
the field, and with some useful variables bound, notably
\section{${1:"Titel der Tour"}}%
\index{$1}%
\label{{2:"waiting for reftex-label call..."$(unless yas-modified-p (reftex-label nil 'dont-
- insert))}}%
+ insert))}}%
#+END_SRC
-The function [[sym:yas-verify-value][=yas-verify-value=]] has another neat trick, and makes use of
-[[sym:yas-moving-away-p][=yas-moving-away-p=]]. Try it and see! Also, check out this
-[[http://groups.google.com/group/smart-snippet/browse_thread/thread/282a90a118e1b662][thread]]
+The function [[sym:yas-verify-value][=yas-verify-value=]] has another neat trick, and makes use
+of [[sym:yas-moving-away-p][=yas-moving-away-p=]]. Try it and see! Also, check out this [[http://groups.google.com/group/smart-snippet/browse_thread/thread/282a90a118e1b662][thread]]
-*** Nested placeholder fields
+** Nested placeholder fields
From version 0.6 on, you can also have nested placeholders of the type:
beginning of the field /and/ it hasn't been changed yet. Otherwise, it
performs the normal Emacs =delete-char= command.
-** Importing TextMate snippets
-
-There are a couple of tools that take TextMate's ".tmSnippet" xml files
-and create YASnippet definitions:
-
-
- - [[http://code.nokrev.com/?p=snippet-copier.git;a=blob_plain;f=snippet_copier.py][a python script by Jeff Wheeler]]
-
- - a [[http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb][ruby tool]] , =textmate_import.rb= adapted from [[http://www.neutronflux.net/2009/07/28/shoulda-snippets-for-emacs/][Rob Christie's]],
- which I have uploaded to the repository.
-
-
-In this section, i'll shortly cover the *second* option.
-
-Download the =textmate_import.rb= tool and the TextMate bundle you're
-interested in.
-
-#+BEGIN_EXAMPLE
- $ curl -O http://yasnippet.googlecode.com/svn/trunk/extras/textmate_import.rb
- $ svn export http://svn.textmate.org/trunk/Bundles/HTML.tmbundle/
-#+END_EXAMPLE
-
-Then invoke =textmate_import.rb= like this:
-
-#+BEGIN_EXAMPLE
- $ ./textmate_import.rb -d HTML.tmbundle/Snippets/ -o html-mode -g HTML.tmbundle/info.plist
-#+END_EXAMPLE
-
-You should end up with a =html-mode= subdir containing snippets exported
-from textmate.
-
-#+BEGIN_EXAMPLE
- $ tree html-mode # to view dir contents, if you have 'tree' installed
-#+END_EXAMPLE
-
-The =-g= is optional but helps the tool figure out the grouping.
-According to [[./snippet-organization.org][Organizing Snippets]], don't forget to touch
-=.yas-make-groups= and =.yas-ignore-filename-triggers= inside the
-=html-mode= dir.
-
-Also try =textmate_import.rb --help= for a list of options.
+** Indentation markers
-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
-=textmate_import.rb= to automatically perform them and submit that.
+If [[sym:yas-indent-line][=yas-indent-line=]] is *not* set to '=auto=, it's still possible to
+indent specific lines by adding an indentation marker, =$>=, somewhere
+on the line.