From f6cace08f378fe4aff18342860c4ee47220ff056 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 23 Nov 2013 22:34:26 -0500 Subject: [PATCH] convert old rst manuals to org mode This is just the initial conversion with pandoc, they still need to be fixed up. Also define new org files as a project in yas-doc-helper.el. --- doc/faq.org | 93 ++++++++ doc/index.org | 40 +++- doc/snippet-development.org | 434 +++++++++++++++++++++++++++++++++++ doc/snippet-expansion.org | 333 +++++++++++++++++++++++++++ doc/snippet-menu.org | 67 ++++++ doc/snippet-organization.org | 107 +++++++++ doc/yas-doc-helper.el | 15 ++ 7 files changed, 1082 insertions(+), 7 deletions(-) create mode 100644 doc/faq.org create mode 100644 doc/snippet-development.org create mode 100644 doc/snippet-expansion.org create mode 100644 doc/snippet-menu.org create mode 100644 doc/snippet-organization.org diff --git a/doc/faq.org b/doc/faq.org new file mode 100644 index 000000000..d45b2c371 --- /dev/null +++ b/doc/faq.org @@ -0,0 +1,93 @@ +* Frequently Asked Questions + +** Why is there an extra newline? + +If you have a newline at the end of the snippet definition file, then +YASnippet will add a newline when you expanding a snippet. Please don't +add a newline at the end if you don't want it when you saving the +snippet file. + +Note some editors will automatically add a newline for you. In Emacs, if +you set =require-final-newline= to =t=, it will add the final newline +for you automatically. + +** Why doesn't TAB expand a snippet? + +First check the mode line to see if there's =yas=. If not, then try +=M-x yas-minor-mode= to manually turn on the minor mode and try to +expand the snippet again. If it works, then, you can add the following +code to your =.emacs= /before/ loading YASnippet: + +where =the-major-mode= is the major mode in which =yas-minor-mode= isn't +enabled by default. + +From YASnippet 0.6 you can also use the command =M-x yas-global-mode= to +turn on YASnippet automatically for /all/ major modes. + +If =yas-minor-mode= is on but the snippet still not expanded. Then try +to see what command is bound to the =TAB= key: press =C-h k= and then +press =TAB=. Emacs will show you the result. + +You'll see a buffer prompted by Emacs saying that +=TAB runs the command ...=. Alternatively, you might see += runs the command ...=, note the difference between =TAB= and +== where the latter has priority. If you see == bound to a +command other than =yas-expand=, (e.g. in =org-mode=) you can try the +following code to work around: + +replace =org-mode-hook= and =org-mode-map= with the major mode hook you +are dealing with (Use =C-h m= to see what major mode you are in). + +As an alternative, you can also try + +To /advise/ the modes indentation function bound to TAB, (in this case +=ruby-indent-line=) to first try to run =yas-expand=. + +If the output of =C-h k RET = tells you that == is indeed +bound to =yas-expand= but YASnippet still doesn't work, check your +configuration and you may also ask for help on the +[[http://groups.google.com/group/smart-snippet][discussion group]]. See +this particular +[[http://code.google.com/p/yasnippet/issues/detail?id=93&can=1][thread]] +for quite some solutions and alternatives. + +Don't forget to attach the information on what command is bound to TAB +as well as the mode information (Can be obtained by =C-h m=). + +** Why doesn't TAB navigation work with flyspell + +A workaround is to inhibit flyspell overlays while the snippet is +active: + +This is apparently related to overlay priorities. For some reason, the +=keymap= property of flyspell's overlays always takes priority over the +same property in yasnippet's overlays, even if one sets the latter's +=priority= property to something big. If you know emacs-lisp and can +solve this problem, drop a line in the +[[http://groups.google.com/group/smart-snippet][discussion group]]. + +** How do I turn off the minor mode where in some buffers + +The best way, since version 0.6.1c, is to set the default value of the +variable =yas-dont-activate= to a lambda function like so: + +This is also the default value starting for that version. It skips the +minor mode in buffers where it is not applicable (no snippet tables), +but only once you have setup your yas-root-directory. + +** How do I define an abbrev key containing characters not supported by +the filesystem? + +- *Note*: This question applies if you're still defining + snippets :: whose key /is/ the filename. This is behavior stil + provided by version 0.6 for backward compatibilty, but is somewhat + deprecated... + +For example, you want to define a snippet by the key =<= which is not a +valid character for filename on Windows. This means you can't use the +filename as a trigger key in this case. + +You should rather use the =# key:= directive to specify the key of the +defined snippet explicitly and name your snippet with an arbitrary valid +filename, =lt.yasnippet= for example, using =<= for the =# key:= +directive: diff --git a/doc/index.org b/doc/index.org index c6d153597..055013bf0 100644 --- a/doc/index.org +++ b/doc/index.org @@ -2,8 +2,6 @@ #+OPTIONS: toc:1 #+STARTUP: showall -#+STYLE: - * Quick start *YASnippet* is a template system for Emacs. It allows you to type an @@ -83,12 +81,40 @@ files that guide it with more difficult importations. The idea is to deprecate =/snippets= and replace it with =extras/imported=. -** Documentation, issues, etc +** Documentation + + The documentation has been split into separate parts: + + 1. [[file:snippet-organization.org][Organizing Snippets]] + #+BEGIN_QUOTE + Describes ways to organize your snippets in the hard disk. + #+END_QUOTE + + 2. [[file:snippet-expansion.org][Expanding Snippets]] + #+BEGIN_QUOTE + Describes how YASnippet chooses snippets for expansion at point. + + Maybe, you'll want some snippets to be expanded in a particular mode, + or only under certain conditions, or be prompted using =ido=, etc... + #+END_QUOTE + + 3. [[file:snippet-development.org][Writing Snippets]] + #+BEGIN_QUOTE + Describes the YASnippet definition syntax, which is very close (but + not equivalent) to Textmate's. Includes a section about converting + TextMate snippets. + #+END_QUOTE + + 4. [[file:snippet-menu.org][The YASnippet menu]] + #+BEGIN_QUOTE + Explains how to use the YASnippet menu to explore, learn and modify + snippets. + #+END_QUOTE + +** Bugs, discussion, contributions, etc - Please refer to the comprehensive [[http://capitaomorte.github.com/yasnippet][documentation]] for full customization and - support. If you think you've found a bug, please report it on [[https://github.com/capitaomorte/yasnippet/issues][the GitHub - issue tracker]]. (please **do not** submit new issues to the old [[http://code.google.com/p/yasnippet/issues/list][googlecode - tracker]]) + If you think you've found a bug, please report it on [[https://github.com/capitaomorte/yasnippet/issues][the GitHub issue tracker]] + (please **do not** submit new issues to the old [[http://code.google.com/p/yasnippet/issues/list][googlecode tracker]]). If you run into problems using YASnippet, or have snippets to contribute, post to the [[http://groups.google.com/group/smart-snippet][yasnippet forum]]. Thank you very much for using YASnippet! diff --git a/doc/snippet-development.org b/doc/snippet-development.org new file mode 100644 index 000000000..7298ff9f6 --- /dev/null +++ b/doc/snippet-development.org @@ -0,0 +1,434 @@ +* Writing snippets + +** Snippet development + +*** Quickly finding snippets + +There are some ways you can quickly find a snippet file: + +- =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=. The + directory searching logic is similar to =M-x yas-new-snippet=. + +- =M-x yas-visit-snippet-file= + + Prompts you for possible snippet expansions like + =yas-insert-snippet=, but instead of expanding it, takes you directly + to the snippet definition's file, if it exists. + +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 + +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= + + #+BEGIN_QUOTE + 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=. + #+END_QUOTE + +- =M-x yas-tryout-snippet= + + #+BEGIN_QUOTE + 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=. + #+END_QUOTE + +There are also /snippets for writing snippets/: =vars=, =$f= and =$m= +:-). + +** File content + +A file defining a snippet generally contains the template to be +expanded. + +Optionally, if the file contains a line of =# --=, the lines above it +count as comments, some of which can be /directives/ (or meta data). +Snippet directives look like =# property: value= and tweak certain +snippets properties described below. If no =# --= is found, the whole +file is considered the snippet template. + +Here's a typical example: + +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 the snippet will not be expandable through the +key mechanism. + +*** =# 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. + +*** =# 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 +[[snippet-expansion.html][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 +[[snippet-menu.html][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 +[[snippet-organization.html][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 [[snippet-expansion.html][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: + +*** =# 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. + +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. + +*** =# 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. + +*** 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 +escaped as =\\= sometimes. + +*** 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 +being expanded. The evaluation is done in the same buffer as the +snippet being expanded. + +Here's an example for c-mode` to calculate the header file guard +dynamically: + +From version 0.6, snippets expansions are run with some special +Emacs-lisp variables bound. One of this is =yas-selected-text=. You can +therefore define a snippet like: + +to "wrap" the selected region inside your recently inserted snippet. +Alternatively, you can also customize the variable +=yas-wrap-around-region= to =t= which will do this automatically. + +*** 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 +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: + +*** 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. + +*** Mirrors + +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 +field. Here's an example: + +When you type ="document"= at =${1:enumerate}=, the word ="document"= +will also be inserted at =\end{$1}=. The best explanation is to see the +screencast([[http://www.youtube.com/watch?v=vOj7btx3ATg][YouTube]] or +[[http://yasnippet.googlecode.com/files/yasnippet.avi][avi video]]). + +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. + +*** Mirrors with 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 =yas-text=) is bound to the text content (string) +contained in the field =n=.Here's an example for Objective-C: + +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. + +Another example is for =rst-mode=. In reStructuredText, the document +title can be some text surrounded by "===" below and above. The "===" +should be at least as long as the text. So + +is a valid title but + +is not. Here's an snippet for rst title: + +*** 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 +you first enter the field, after each change you make to the field and +also just before you exit the field. + +The syntax is also a tiny bit different, so that the parser can +distinguish between fields and mirrors. In the following example + +=mydefine= gets automatically upcased to =MYDEFINE= once you enter the +field. As you type text, it gets filtered through the transformation +every time. + +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. + +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 +=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 + +As mentioned, the field transformation is invoked just after you enter +the field, and with some useful variables bound, notably +=yas-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. + +The =yas-choose-value= does this work for you. For example: + +See the definition of =yas-choose-value= to see how it was written using +the two variables. + +Here's another use, for LaTeX-mode, which calls reftex-label just as you +enter snippet field 2. This one makes use of =yas-modified-p= directly. + +The function =yas-verify-value= has another neat trick, and makes use of +=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 + +From version 0.6 on, you can also have nested placeholders of the type: + +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. + +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 =("" ")"=. + +*** =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 [[snippet-development.html][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=. + +*** =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 selected +region, this works mostly for snippets with direct keybindings or 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. + +** Importing TextMate snippets + +There are a couple of tools that take TextMate's ".tmSnippet" xml files +and create YASnippet definitions: + +#+BEGIN_QUOTE + + - [[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. + +#+END_QUOTE + +In this section, i'll shortly cover the *second* option. + +Download the =textmate_import.rb= tool and the TextMate bundle you're +interested in. + +Then invoke =textmate_import.rb= like this: + +You should end up with a =html-mode= subdir containing snippets exported +from textmate. + +The =-g= is optional but helps the tool figure out the grouping. +According to [[snippet-organization.html][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. + +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. diff --git a/doc/snippet-expansion.org b/doc/snippet-expansion.org new file mode 100644 index 000000000..75efe86f7 --- /dev/null +++ b/doc/snippet-expansion.org @@ -0,0 +1,333 @@ +* Expanding snippets + +** Triggering expansion + +You can use YASnippet to expand snippets in different ways: + +- By typing an abbrev, the snippet /trigger key/, and then pressing the + key defined in =yas-trigger-key= (which defaults to "TAB"). This + works in buffers 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. + +[[images/minor-mode-indicator.png]] + +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.html][FAQ]]. + +**** 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 +[[snippet-development.html][Writing Snippets]]. + +*** Expanding from the menu + +See [[snippet-menu.html][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 from you own elisp +code. You should call =yas-expand-snippet= instead of =yas-expand= in +this case. + +As with expanding from the menubar, the condition system and multiple +candidates doesn't affect expansion. In fact, expanding from the +YASnippet menu has the same effect of evaluating the follow code: + +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 the current cursor position. + +In particular, the following things matter: + +- Currently loaded snippets tables + + These are loaded from a directory hierarchy in your file system. See + [[snippet-organization.html][Organizing Snippets]]. They are named + after major modes like =html-mode=, =ruby-mode=, etc... + +- Major mode of the current buffer + + If the currrent major mode 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 major + mode you are in currently. + +- Parent tables + + Snippet tables defined as the parent of some other eligible table are + also considered. This works recursively, i.e. parents of parents of + eligible tables 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, so using a hook is a good idea. + +- Buffer-local =yas-buffer-local-condition= variable + + This variable provides finer 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 +[[snippet-development.html][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 + +... 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 [[Eligible%20snippets][above]] 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 through +=yas-prompt-functions= , which defines your preferred methods 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: + +Currently there are some alternatives solution with YASnippet. + +[[images/x-menu.png]] + +**** 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. +- Your window system may or may not allow to you use =C-n=, =C-p= to + navigate this menu. +- This function can't be used when in a terminal. + +[[images/ido-menu.png]] + +**** Minibuffer prompting + +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. + +[[images/dropdown-menu.png]] + +**** 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 that +snippet is expanded and replaces the =bar=. Snippets pointed to by +=foo_bar= and ="#foobar= won't be considered. + +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 want to understand +how Emacs's syntax rules work... diff --git a/doc/snippet-menu.org b/doc/snippet-menu.org new file mode 100644 index 000000000..cf5dec587 --- /dev/null +++ b/doc/snippet-menu.org @@ -0,0 +1,67 @@ +* YASnippet menu + +When =yas-minor-mode= is active, YASnippet will setup a menu just after +the "Buffers" menu in the menubar. + +In this menu, you can find + +- The currently loaded snippet definitions, organized by major mode, + and optional grouping. + +- A rundown of the most common commands, (followed by their + keybindings) including commands to load directories and reload all + snippet definitions. + +- A series of submenus for customizing and exploring YASnippet + behavior. + +[[images/menu-1.png]] + +** Loading snippets from menu + +Invoking "Load snippets..." from the menu invokes =yas-load-directory= +and prompts you for a snippet directory hierarchy to load. + +Also useful is the "Reload all" options which uncondionally reloads all +the snippets directories defined in =yas-root-directory= and rebuilds +the menus. + +** Snippet menu behavior + +YASnippet will list in this section all the loaded snippet definitions +organized by snippet table name. + +You can use this section to explore currently loaded snippets. If you +click on one of them, the default behavior is to expand it, +unconditionally, inside the current buffer. + +You can however, customize variable =yas-visit-from-menu= to be =t= +which will take you to the snippet definition file when you select it +from the menu. + +If you want the menu show only snippet tables whose name corresponds to +a "real" major mode. You do this by setting =yas-use-menu= to +='real-modes=. + +Finally, to have the menu show only the tables for the currently active +mode, set =yas-use-menu= to =abbreviate=. + +These customizations can also be found in the menu itself, under the +"Snippet menu behavior" submenu. + +** Controlling indenting + +The "Indenting" submenu contains options to control the values of +=yas-indent-line= and =yas-also-auto-indent-first-line=. See +[[snippet-development.html][Writing snippets]] . + +** Prompting method + +The "Prompting method" submenu contains options to control the value of +=yas-prompt-functions=. See [[snippet-expansion.html][Expanding +snippets]] . + +** Misc + +The "Misc" submenu contains options to control the values of more +variables. diff --git a/doc/snippet-organization.org b/doc/snippet-organization.org new file mode 100644 index 000000000..9ca14c067 --- /dev/null +++ b/doc/snippet-organization.org @@ -0,0 +1,107 @@ +* Organizing snippets + +** Loading snippets + +Snippet definitions are stored in files in the filesystem. Unless you +use the simpler [[index.html@installation][bundle version]]), these are +arranged so that YASnippet can load them into /snippet tables/. The +triggering mechanisms (see [[snippet-expansion.html][Expanding +snippets]]) will look up these snippet tables and (hopefully) expand the +snippet you intended. + +The non-bundle version of YASnippet, once unpacked, comes with a full +directory of snippets, which you can copy somewhere and use. You can +also create or download more directories. + +Once these directories are in place reference them in the variable +=yas-root-directory= and load them with =yas-load-directory=: + +The point in using =yas-root-directory= (as opposed to calling +=yas-load-directory= directly) is considering "~/emacs.d/mysnippets" for +snippet development, so you can use commands like =yas-new-snippet= and +others described in section [[snippet-development.html][Writing +Snippets]]. + +You can make this variable a list and store more items into it: + +In this last example, the all the directories are loaded and their +snippets considered for expansion. However development still happens in +the first element, "~/emacs.d/mysnippets". + +** Organizing snippets + +Once you've setup =yas-root-directory= , you can store snippets inside +sub-directories of these directories. + +Snippet definitions are put in plain text files. They are arranged by +sub-directories, and the snippet tables are named after these +directories. + +The name corresponds to the Emacs mode where you want expansion to take +place. For example, snippets for =c-mode= are put in the =c-mode= +sub-directory. + +*** The =.yas.parents= file + +It's very useful to have certain modes share snippets between +themselves. To do this, choose a mode subdirectory and place a +=.yas-parents= containing a whitespace-separated list of other mode +names. When you reload those modes become parents of the original mode. + +*** The =.yas-make-groups= file + +[[images/menu-groups.png]] + +If you place an empty plain text file =.yas-make-groups= inside one of +the mode directories, the names of these sub-directories are considered +groups of snippets and [[snippet-menu.html][The YASnippet Menu]] is +organized much more cleanly, as you can see in the image. + +Another alternative way to achieve this is to place a =# group:= +directive inside the snippet definition. See +[[snippet-development.html][Writing Snippets]]. + +** YASnippet bundle + +The most convenient way to define snippets for YASnippet is to put them +in a directory arranged by the mode and use =yas-load-directory= to load +them. + +However, this might slow down the Emacs start-up speed if you have many +snippets. You can use =yas-define-snippets= to define a bunch of +snippets for a particular mode in an Emacs-lisp file. + +Since this is hard to maintain, there's a better way: define your +snippets in directory and then call =M-x yas-compile-bundle= to compile +it into a bundle file when you modified your snippets. + +The release bundle of YASnippet is produced by =yas-compile-bundle=. The +bundle uses =yas-define-snippets= to define snippets. This avoids the IO +and parsing overhead when loading snippets. + +Further more, the generated bundle is a stand-alone file not depending +on =yasnippet.el=. The released bundles of YASnippet are all generated +this way. + +See the internal documentation for these functions + +- =M-x describe-function RET yas-define-snippets RET= +- =M-x describe-function RET yas-compile-bundle RET=. + +** Customizable variables + +*** =yas-root-directory= + +Root directory that stores the snippets for each major mode. + +If you set this from your .emacs, can also be a list of strings, for +multiple root directories. If you make this a list, the first element is +always the user-created snippets directory. Other directories are used +for bulk reloading of all snippets using =yas-reload-all= + +*** =yas-ignore-filenames-as-triggers= + +If non-nil, don't derive tab triggers from filenames. + +This means a snippet without a =# key:= directive wont have a tab +trigger. diff --git a/doc/yas-doc-helper.el b/doc/yas-doc-helper.el index 39c971661..4300597c4 100755 --- a/doc/yas-doc-helper.el +++ b/doc/yas-doc-helper.el @@ -92,6 +92,21 @@ (define-key org-mode-map [M-f8] 'yas--internal-link-snippet) +;; This lets all the org files be exported to HTML with +;; `org-publish-current-project' (C-c C-e P). +(progn + (defvar yas--document-org-project-plist + `(:style + "" + :base-directory ,default-directory + :publishing-directory ,default-directory)) + + (let ((project (assoc "yasnippet" org-publish-project-alist))) + (if project + (setcdr project yas--document-org-project-plist) + (push `("yasnippet" . ,yas--document-org-project-plist) + org-publish-project-alist)))) + (provide 'yas-doc-helper) ;;; yas-doc-helper.el ends here ;; Local Variables: -- 2.39.2