mirror of
https://github.com/joaotavora/yasnippet.git
synced 2025-10-13 21:13:04 +00:00
406 lines
13 KiB
ReStructuredText
406 lines
13 KiB
ReStructuredText
==================
|
|
Expanding snippets
|
|
==================
|
|
|
|
.. _Organizing Snippets: snippet-organization.html
|
|
.. _Expanding Snippets: snippet-expansion.html
|
|
.. _Writing Snippets: snippet-development.html
|
|
.. _The YASnippet Menu: snippet-menu.html
|
|
|
|
.. contents::
|
|
|
|
|
|
Triggering expansion
|
|
====================
|
|
|
|
You can use YASnippet to expand snippets in different ways:
|
|
|
|
* By typing a snippet abbrev and then pressing the key defined in
|
|
``yas/trigger-key`` (which defaults to "TAB"). This works in a
|
|
buffer where the minor mode ``yas/minor-mode`` is active;
|
|
|
|
* By invoking the command ``yas/insert-snippet`` (either by typing
|
|
``M-x yas/insert-snippet`` or its keybinding). This does *not*
|
|
require ``yas/minor-mode`` to be active.
|
|
|
|
* By using the keybinding associated with an active snippet. This also
|
|
requires ``yas/minor-mode`` to be active;
|
|
|
|
* By expanding directly from the "YASnippet" menu in the menu-bar
|
|
|
|
* By using hippie-expand
|
|
|
|
* Expanding from emacs-lisp code
|
|
|
|
Trigger key
|
|
-----------
|
|
|
|
When ``yas/minor-mode`` is enabled, the keybinding taken from
|
|
``yas/trigger-key`` will take effect.
|
|
|
|
``yas/trigger-key`` invokes ``yas/expand``, which tries to expand a
|
|
*snippet abbrev* (also known as *snippet key*) before point.
|
|
|
|
The default key is ``"TAB"``, however, you can freely set it to some
|
|
other key.
|
|
|
|
.. image:: images/minor-mode-indicator.png
|
|
:align: left
|
|
|
|
To enable the YASnippet minor mode in all buffers globally use the
|
|
command ``yas/global-mode``.
|
|
|
|
When you use ``yas/global-mode`` you can also selectively disable
|
|
YASnippet in some buffers by setting the buffer-local variable
|
|
``yas/dont-active`` in the buffer's mode hook.
|
|
|
|
Trouble when using or understanding the ``yas/trigger-key`` is easily
|
|
the most controversial issue in YASsnippet. See the `FAQ <faq.html>`_.
|
|
|
|
Fallback bahaviour
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
``yas/fallback-behaviour`` is a customization variable bound to
|
|
``'call-other-command`` by default. If ``yas/expand`` failed to find
|
|
any suitable snippet to expand, it will disable the minor mode
|
|
temporarily and find if there's any other command bound the
|
|
``yas/trigger-key``.
|
|
|
|
If found, the command will be called. Usually this works very well --
|
|
when there's a snippet, expand it, otherwise, call whatever command
|
|
originally bind to the trigger key.
|
|
|
|
However, you can change this behavior by customizing the
|
|
``yas/fallback-behavior`` variable. If you set this variable to
|
|
``'return-nil``, it will return ``nil`` instead of trying to call the
|
|
*original* command when no snippet is found.
|
|
|
|
Insert at point
|
|
---------------
|
|
|
|
The command ``M-x yas/insert-snippet`` lets you insert snippets at
|
|
point *for you current major mode*. It prompts you for the snippet
|
|
key first, and then for a snippet template if more than one template
|
|
exists for the same key.
|
|
|
|
The list presented contains the snippets that can be inserted at
|
|
point, according to the condition system. If you want to see all
|
|
applicable snippets for the major mode, prefix this command with
|
|
``C-u``.
|
|
|
|
The prompting methods used are again controlled by
|
|
``yas/prompt-functions``.
|
|
|
|
Snippet keybinding
|
|
------------------
|
|
|
|
See the section of the ``# binding:`` directive in `Writing
|
|
Snippets`_.
|
|
|
|
|
|
Expanding from the menu
|
|
-----------------------
|
|
|
|
See `the YASnippet Menu`_.
|
|
|
|
Expanding with ``hippie-expand``
|
|
----------------------------------
|
|
|
|
To integrate with ``hippie-expand``, just put
|
|
``yas/hippie-try-expand`` in
|
|
``hippie-expand-try-functions-list``. This probably makes more sense
|
|
when placed at the top of the list, but it can be put anywhere you
|
|
prefer.
|
|
|
|
Expanding from emacs-lisp code
|
|
------------------------------
|
|
|
|
Sometimes you might want to expand a snippet directly by calling a
|
|
functin from elisp code. You should call ``yas/expand-snippet``
|
|
instead of ``yas/expand`` in this case.
|
|
|
|
As with expanding from the menubar, condition system and multiple
|
|
candidates won't exists here. In fact, expanding from menubar has the
|
|
same effect of evaluating the follow code:
|
|
|
|
.. sourcecode:: common-lisp
|
|
|
|
(yas/expand-snippet template)
|
|
|
|
See the internal documentation on ``yas/expand-snippet`` for more
|
|
information.
|
|
|
|
Controlling expansion
|
|
=====================
|
|
|
|
Eligible snippets
|
|
-----------------
|
|
|
|
YASnippet does quite a bit of filtering to find out which snippets are
|
|
eligible for expanding at point.
|
|
|
|
In particular, the following things matter:
|
|
|
|
* Currently loaded snippets tables
|
|
|
|
These are loaded from a directory hierarchy in your file system. See
|
|
`Organizing Snippets`_. They are named after major modes like
|
|
``html-mode``, ``ruby-mode``, etc...
|
|
|
|
* Major mode of the current buffer
|
|
|
|
If it matches one of the loaded snippet tables, then all that
|
|
table's snippets are considered for expansion. Use ``M-x
|
|
describe-variable RET major-mode RET`` to find out which mode you
|
|
are in currently.
|
|
|
|
* Parent tables
|
|
|
|
Snippet tables defined as parent of some other table considered in
|
|
the previous step are also considered.
|
|
|
|
* Buffer-local ``yas/mode-symbol`` variable
|
|
|
|
This can be used to consider snippet tables whose name does not
|
|
correspond to a major mode. If you set this variable to a name ,
|
|
like ``rinari-minor-mode``, you can have some snippets expand only
|
|
in that minor mode. Naturally, you want to set this conditionally,
|
|
i.e. only when entering that minor mode, using a hook is a good
|
|
idea.
|
|
|
|
.. sourcecode:: common-lisp
|
|
|
|
;; When entering rinari-minor-mode, consider also the snippets in the
|
|
;; snippet table "rails-mode"
|
|
(add-hook 'rinari-minor-mode-hook
|
|
#'(lambda ()
|
|
(setq yas/mode-symbol 'rails-mode)))
|
|
|
|
* Buffer-local ``yas/buffer-local-condition`` variable
|
|
|
|
This variable provides more fine grained control over what snippets
|
|
can be expanded in the current buffer. The default value, won't let
|
|
you expand snippets inside comments or string literals for
|
|
example. See `The condition system`_ for more info.
|
|
|
|
The condition system
|
|
--------------------
|
|
|
|
Consider this scenario: you are an old Emacs hacker. You like the
|
|
abbrev-way and set ``yas/trigger-key`` to ``"SPC"``. However,
|
|
you don't want ``if`` to be expanded as a snippet when you are typing
|
|
in a comment block or a string (e.g. in ``python-mode``).
|
|
|
|
If you use the ``# condition :`` directive (see `Writing Snippets`_)
|
|
you could just specify the condition for ``if`` to be ``(not
|
|
(python-in-string/comment))``. But how about ``while``, ``for``,
|
|
etc. ? Writing the same condition for all the snippets is just
|
|
boring. So has a buffer local variable
|
|
``yas/buffer-local-condition``. You can set this variable to ``(not
|
|
(python-in-string/comment))`` in ``python-mode-hook``.
|
|
|
|
Then, what if you really want some particular snippet to expand even
|
|
inside a comment? This is also possible! But let's stop telling the
|
|
story and look at the rules:
|
|
|
|
* If ``yas/buffer-local-condition`` evaluate to nil, no snippets will
|
|
be considered for expansion.
|
|
|
|
* If it evaluates to the a *cons cell* where the ``car`` is the symbol
|
|
``require-snippet-condition`` and the ``cdr`` is a symbol (let's
|
|
call it ``requirement``), then:
|
|
|
|
* Snippets having no ``# condition:`` directive won't be considered;
|
|
|
|
* Snippets with conditions that evaluate to nil (or produce an
|
|
error) won't be considered;
|
|
|
|
* If the snippet has a condition that evaluates to non-nil (let's
|
|
call it ``result``):
|
|
|
|
* If ``requirement`` is ``t``, the snippet is ready to be
|
|
expanded;
|
|
|
|
* If ``requirement`` is ``eq`` to ``result``, the snippet is ready
|
|
to be expanded;
|
|
|
|
* Otherwise the snippet won't be considered.
|
|
|
|
* If it evaluates to the symbol ``always``, all snippets are
|
|
considered for expansion, regardless of any conditions.
|
|
|
|
* If it evaluate to ``t`` or some other non-nil value:
|
|
|
|
* If the snippet has no condition, or has a condition that evaluate
|
|
to non-nil, it is ready to be expanded.
|
|
|
|
* Otherwise, it won't be considered.
|
|
|
|
In the mentioned scenario, set ``yas/buffer-local-condition`` like
|
|
this
|
|
|
|
.. sourcecode:: common-lisp
|
|
|
|
(add-hook 'python-mode-hook
|
|
'(lambda ()
|
|
(setq yas/buffer-local-condition
|
|
'(if (python-in-string/comment)
|
|
'(require-snippet-condition . force-in-comment)
|
|
t))))
|
|
|
|
... and specify the condition for a snippet that you're going to
|
|
expand in comment to be evaluated to the symbol
|
|
``force-in-comment``. Then it can be expanded as you expected, while
|
|
other snippets like ``if`` still can't expanded in comment.
|
|
|
|
Multiples snippet with the same key
|
|
-----------------------------------
|
|
|
|
The rules outlined `above <Eligible snippets>`_ can return more than
|
|
one snippet to be expanded at point.
|
|
|
|
When there are multiple candidates, YASnippet will let you select
|
|
one. The UI for selecting multiple candidate can be customized. A
|
|
customization variable, called ``yas/prompt-functions`` defines your
|
|
preferred method of being prompted for snippets.
|
|
|
|
You can customize it with ``M-x customize-variable RET
|
|
yas/prompt-functions RET``. Alternatively you can put in your
|
|
emacs-file:
|
|
|
|
.. sourcecode:: common-lisp
|
|
|
|
(setq yas/prompt-functions '(yas/x-prompt yas/dropdown-prompt))
|
|
|
|
Currently there are some alternatives solution with YASnippet.
|
|
|
|
.. image:: images/x-menu.png
|
|
:align: right
|
|
|
|
Use the X window system
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The function ``yas/x-prompt`` can be used to show a popup menu for you
|
|
to select. This menu will be part of you native window system widget,
|
|
which means:
|
|
|
|
* It usually looks beautiful. E.g. when you compile Emacs with gtk
|
|
support, this menu will be rendered with your gtk theme.
|
|
* Emacs have little control over it. E.g. you can't use ``C-n``,
|
|
``C-p`` to navigate.
|
|
* This function can't be used when in a terminal.
|
|
|
|
.. image:: images/ido-menu.png
|
|
:align: right
|
|
|
|
Use built-in Emacs selection methods
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
You can use functions ``yas/completing-prompt`` for the classic emacs
|
|
completion method or ``yas/ido-prompt`` for a much nicer looking
|
|
method. The best way is to try it. This works in a terminal.
|
|
|
|
.. image:: images/dropdown-menu.png
|
|
:align: right
|
|
|
|
Use ``dropdown-menu.el``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The function ``yas/dropdown-prompt`` can also be placed in the
|
|
``yas/prompt-functions`` list.
|
|
|
|
This works in both window system and terminal and is customizable, you
|
|
can use ``C-n``, ``C-p`` to navigate, ``q`` to quit and even press
|
|
``6`` as a shortcut to select the 6th candidate.
|
|
|
|
Roll your own
|
|
~~~~~~~~~~~~~
|
|
|
|
See below for the documentation on variable ``yas/prompt-functions``
|
|
|
|
Customizable Variables
|
|
======================
|
|
|
|
``yas/prompt-functions``
|
|
------------------------
|
|
|
|
|
|
You can write a function and add it to the ``yas/prompt-functions``
|
|
list. 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. When applied to each of the
|
|
objects in CHOICES it 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!")``
|
|
|
|
``yas/fallback-behavior``
|
|
-------------------------
|
|
|
|
How to act when ``yas/expand`` does *not* expand a snippet.
|
|
|
|
``call-other-command`` means try to temporarily disable YASnippet and
|
|
call the next command bound to ``yas/trigger-key``.
|
|
|
|
``return-nil`` means return nil. (i.e. do nothing)
|
|
|
|
An entry (apply COMMAND . ARGS) means interactively call COMMAND, if
|
|
ARGS is non-nil, call COMMAND non-interactively with ARGS as
|
|
arguments.
|
|
|
|
``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``.
|
|
|
|
``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``
|
|
|
|
``yas/key-syntaxes``
|
|
--------------------
|
|
|
|
The default searching strategy is quite powerful. For example, in
|
|
``c-mode``, ``"bar"``, ``"foo_bar"``, ``"#foo_bar"`` can all be
|
|
recognized as a snippet key. Furthermore, the searching is in that
|
|
order. In other words, if ``"bar"`` is found to be a key to some
|
|
*valid* snippet, then ``"foo_bar"`` and ``"#foobar"`` won't be
|
|
searched.
|
|
|
|
However, this strategy can also be customized easily from the
|
|
``yas/key-syntaxes`` variable. It is a list of syntax rules, the
|
|
default value is ``("w" "w_" "w_." "^ ")``. Which means search the
|
|
following thing until found one:
|
|
|
|
* a word.
|
|
* a symbol. In lisp, ``-`` and ``?`` can all be part of a symbol.
|
|
* a sequence of characters of either word, symbol or punctuation.
|
|
* a sequence of characters of non-whitespace characters.
|
|
|
|
But you'd better keep the default value unless you understand what
|
|
Emacs's syntax rule mean.
|
|
|
|
|