diff --git a/Rakefile b/Rakefile index 54015a8..7d22c43 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,7 @@ require 'fileutils' def find_version - File.read("yasnippet.el") =~ /;; Version: *([0-9.]+) *$/ + File.read("yasnippet.el") =~ /;; Version: *([0-9.]+[a-z]?) *$/ $version = $1 end find_version @@ -19,7 +19,7 @@ desc "create a release package" task :package do release_dir = "pkg/yasnippet-#{$version}" FileUtils.mkdir_p(release_dir) - files = ['snippets', 'yasnippet.el'] + files = ['snippets', 'yasnippet.el', 'dropdown-list.el'] FileUtils.cp_r files, release_dir FileUtils.rm_r Dir[release_dir + "/**/.svn"] FileUtils.cd 'pkg' diff --git a/doc/changelog.html b/doc/changelog.html deleted file mode 100644 index ab1b98b..0000000 --- a/doc/changelog.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - -ChangeLog - - - - - -
-
-
-
- -
-
-
-
-
-

0.5.10 / 2009-02-11

-
    -
  • Added grouping support so that the snippets in the menu can be -groupped together.
  • -
  • Make the bundle ELPA -compatible.
  • -
-
-
-

0.5.9 / 2009-01-21

-
    -
  • Fixed the bug of disabling the auto-indenting of cc-mode.
  • -
-
-
-

0.5.8 / 2009-01-15

-
    -
  • Added a key property in snippet definition for snippet names -that are not valid path name.
  • -
  • Fixed some bugs of indenting (Issue 44, Issue -46).
  • -
  • Fixed Issue 45 by -providing a proper default value for yas/buffer-local-condition.
  • -
  • Added helper function yas/substr for convenient mirror -transformation.
  • -
  • Make variable yas/registered-snippet properly initialized.
  • -
  • Fixed the overlay error when overlay becomes empty (Issue 49 and -Issue 48). This -bug has occurred and been fixed earlier, and should not have -happened if we have proper regression test.
  • -
  • Added a workaround for c-electric- serial commands (Issue 27).
  • -
-
-
-

0.5.7 / 2008-12-03

-
    -
  • Fixed Issue 28 of -properly clean up snippet (by joaotavora).
  • -
  • Added a new section "Field-level undo functionality" to correct -Issue 33 -(by joaotavora).
  • -
  • Added some snippets from users for sql, erlang, scala, html, xml, latex, etc.
  • -
  • Fixed Issue 16 by adding -$> support. Here's the doc for $> indenting.
  • -
-
-
-

0.5.6 / 2008-08-07

-
    -
  • Added a buffer local variable yas/dont-activate to turn off -yas/minor-mode in some major modes. See Issue 29.
  • -
  • Make the environment of elisp evaluation more friendly to -(current-column).
  • -
  • Fixed the regular expression bug in python-mode snippets.
  • -
  • Use filename or full key extension for snippet name if no name -property is defined.
  • -
-
-
-

0.5.5 / 2008-05-29

-
    -
  • Tweak yas/extra-mode-hooks so that it can be more easily -customized.
  • -
  • Add an entry in FAQ about why TAB key doesn't work in some -modes.
  • -
-
-
-

0.5.4 / 2008-05-15

-
    -
  • Added ox-mode-hook and python-mode-hook to -yas/extra-mode-hooks to fix the problem YASnippet is not enabled -in those modes.
  • -
-
-
-

0.5.3 / 2008-05-07

-
    -
  • Fix indent of python-mode snippets.
  • -
  • Fix a bug of dropdown-list: conflicts with color-theme (Issue 23). Thanks -Mike.
  • -
  • Fix a bug of condition system.
  • -
-
-
-

0.5.2 / 2008-04-20

-
    -
  • Fix a bug for comparing string to symbol using string= (which -will fire an error).
  • -
-
-
-

0.5.1 / 2008-04-14

-
    -
  • Use a beautiful css style in the document.
  • -
-
-
-

0.5.0 / 2008-04-10

-
    -
  • Integrate with hippie-expand. Just add yas/hippie-try-expand to -hippie-expand-try-functions-list.
  • -
  • If you set yas/fall-back-behavior to 'return-nil, YASnippet -will return nil when it can't find a snippet to expand.
  • -
  • Defect fix: the condition of a snippet was evaluated twice in -earlier version.
  • -
  • Deleting snippet (using C-w or C-k) won't cause serious -problem now.
  • -
  • Several complex snippet for python-mode from Yasser included in the -distribution.
  • -
-
-
-

0.4.5 / 2008-04-07

-
    -
  • Merge the latest dropdown-list.el.
  • -
  • Add snippets for f90-mode from Li Zhu.
  • -
  • Bug fix: l-safe-expr-p: Lisp nesting exceeds max-lisp-eval-depth -error when several (more than two) snippets overlaps. Thanks -sunwaybupt@newsmth for reporting this bug.
  • -
-
-
-

0.4.4 / 2008-03-24

-
    -
  • Bug fix: dropdown-list.el doesn't recognize [return] properly.
  • -
-
-
-

0.4.3 / 2008-03-23

-
    -
  • Bug fix: failed to recognize user customized yas/trigger-key.
  • -
-
-
-

0.4.2 / 2008-03-22

-
    -
  • Make a separate document package for release. Also make document -available online.
  • -
-
-
-

0.4.1 / 2008-03-21

-
    -
  • Make sure yas/minor-mode's key bindings always take priority to -other minor modes.
  • -
-
-
-

0.4.0 / 2008-03-20

-
    -
  • Document refinement and released with YASnippet. Most of the Online -wiki document will be deprecated soon.
  • -
  • Powerful condition system added to yasnippet!
  • -
  • Incorporate dropdown-list.el and make it default way for -selecting multiple candidates. Thanks to Jaeyoun Chung.
  • -
  • yas/before-expand-snippet-hook
  • -
-
-
-

0.3.2 / 2008-03-19

-
    -
  • Enhancement: A better way to define minor-mode. Thanks to Kentaro -Kuribayashi. See this thread -for more details.
  • -
-
-
-

0.3.1 / 2008-03-17

-
    -
  • Bug fix: Emacs get confused when a field is deleted. See issue 10.
  • -
-
-
-

0.3.0 / 2008-03-16

-
    -
  • Add a yas/after-exit-snippet-hook so that you can do something like -indent-region or fill-region after finish the snippet.
  • -
  • Use minor-mode instead of global-set-key to bind the trigger -key. Now the trigger key and fall-back behavior can be more -flexible. Not constrained to <tab>. Thanks to Trey Jackson. See -this thread -for more details.
  • -
  • Now user can customize the popup function for selecting multiple -candidate for the same snippet key.
  • -
  • Support dropdown-list.el to be a better way to select multiple -candidate when in text mode.
  • -
-
-
-

0.2.3 / 2008-03-15

-
    -
  • Bug in non-window (-nw) mode when there's multiple candidate to -expand. See issue 7.
  • -
  • Allow expanding another snippet as long as not currently inside a -field.
  • -
-
-
-

0.2.2 / 2008-03-13

-
    -
  • Added customized face for fields and mirrors. Better in dark -background. And users can customize it.
  • -
-
-
-

0.2.1 / 2008-03-10

-
    -
  • Fix the insert-behind problem under both Emacs 22 and Emacs 23.
  • -
-
-
-

0.2.0 / 2008-03-10

-
    -
  • Use big keymap overlay to detect insert-behind event manually to -avoid sometimes missed hook calls. See issue 3 for more -details.
  • -
  • Support parent snippet table. Now you can set (for example) -cc-mode as common mode for c++-mode, c-mode and -java-mode. They'll share snippets defined for cc-mode.
  • -
-
-
-

0.1.1 / 2008-03-08

-
    -
  • Add a rake task to upload to google code.
  • -
  • Use elisp compile-bundle function instead of python scrip
  • -
-
-
-

0.1.0 / 2008-03-07

-
    -
  • Embedded elisp support.
  • -
  • Fields navigation support.
  • -
  • Mirror of fields support.
  • -
  • Menu-bar support.
  • -
  • Multiple snippets with same name support.
  • -
  • Popup menu for multiple snippet with same name support.
  • -
  • Transformation of fields support.
  • -
  • Load directory support.
  • -
  • Compile bundle support.
  • -
-
-
-
-
-
-
-
-
- - diff --git a/doc/define_snippet.html b/doc/define_snippet.html deleted file mode 100644 index 64db46b..0000000 --- a/doc/define_snippet.html +++ /dev/null @@ -1,760 +0,0 @@ - - - - - - -How to define a snippet ? - - - - - -
-
-
-
- -
-
-
-
- -

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 startup speed if you have many -snippets. You can use yas/define-snippets 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 -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 use yas/define-snippets to -define snippets. This avoid the IO and parsing overhead when loading -snippets.

-

Finally, you can use yas/define to define a single snippet at your -convenience. I ofthen use this to do some testing.

-
-

Define snippets in files

-
-

Directory hierarchy

-

Here's the directory hierarchy of the snippets directory comes -with YASnippet:

-
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
-
-

Snippet definitions are put in plain text files. They are arranged by -subdirectories. For example, snippets for c-mode are put in the -c-mode directory.

-

The parent directory acts as the parent mode. This is the way of -YASnippet to share snippet definitions among different modes. As you -can see above, c-mode and c++-mode share the same parents -cc-mode, while all modes are derived from text-mode. This can -be also used to as an alias -- cperl-mode is an empty directory -whose parent is perl-mode.

-

File names act as the snippet trigger key. Note files starting with a -dot (.) are ignored.

-
-
-

File content

-

A file defining a snippet may just contain the template for the -snippet. Optionally it can also contains some meta data for the -snippet as well as comments.

-

Generally speaking, if the file contains a line of # --, then all -contents above that line are considered as meta data and comments; -below are template. Or else the whole file content is considered as -the template.

-

Here's a typical example:

-
#contributor : pluskid <pluskid@gmail.com>
-#name : __...__
-# --
-__${init}__
-
-

Meta data are specified in the syntax of

-
#data-name : data value
-
-

Any other text above # -- is considered as comment and -ignored. Here's a list of currently supported meta data:

-images/group.png -
    -
  • name: The name of the snippet. This is a one-line description of -the snippet. It will be displayed in the menu. So it's a good idea -to select a descriptive name fo a snippet -- especially -distinguishable among similar snippets.
  • -
  • contributor: The contributor of the snippet.
  • -
  • condition: The condition of the snippet. This is a piece of -elisp code. If a snippet has a condition, then it will only be -expanded when the condition code evaluate to some non-nil value.
  • -
  • key: The key to expand the snippet. Sometimes the key of a -snippet is non-ASCII or not valid filename (e.g. contains -/). One can then define the key property which will -overwrite the filename as the key to expand the snippet.
  • -
  • group: The snippets for a mode can be grouped. Grouped snippets -will be grouped in sub-menu. This is useful if one has too many -snippets for a mode which will make the menu too long. group -property only affect menu construction (See The Menu). Refer to -the snippets for ruby-mode for examples. 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.
  • -
-
-
-

Define snippets using elisp code

-

As I mentioned above, you can define snippets directly by writing -elisp code.

-
-

yas/define-snippets

-

The basic syntax of yas/define-snippets is

-
(yas/define-snippets MODE SNIPPETS &optional PARENT)
-
-

The parameters are self-descriptive. If you specify a PARENT, then -the snippets of the parents may be shared by MODE. Note if you use -this function several times, the later specified PARENT will -overwrite the original one. However, not specifying a PARENT won't -erase the original parent.

-

The SNIPPETS parameter is a list of snippet definitions. Each -element should have the following form:

-
(KEY TEMPLATE NAME CONDITION GROUP)
-
-

The NAME, CONDITION and GROUP can be omitted if you don't -want to provide one. Here's an example:

-
(yas/define-snippets 'c++-mode
-'(
-  ("using" "using namespace ${std};
-$0" "using namespace ... " nil)
-  ("class" "class ${1:Name}
-{
-public:
-    $1($2);
-    virtual ~$1();
-};" "class ... { ... }" nil)
-  ("beginend" "${1:v}.begin(), $1.end" "v.begin(), v.end()" nil)
-  )
-'cc-mode)
-
-

The example above is auto-generated code by yas/compile-bundle.

-
-
-

yas/compile-bundle

-

yas/compile-bundle 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 yasnippet.el. The released -bundles of YASnippet are all generated this way.

-

The basic syntax of yas/compile-bundle is

-
(yas/compile-bundle &optional yasnippet yasnippet-bundle snippet-roots code)
-
-

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:

-
(yas/compile-bundle "yasnippet.el"
-                    "./yasnippet-bundle.el"
-                    '("snippets")
-                    "(yas/initialize)")
-
-

The snippet-roots can be a list of root directories. This is -useful when you have multiple snippet directories (maybe from other -users). The code parameter can be used to specify your own -customization code instead of the default (yas/initialize). For -example, you can set yas/trigger-key to (kbd "SPC") here if -you like.

-
-
-

yas/define

-

The basic syntax for yas/define is

-
(yas/define mode key template &optional name condition group)
-
-

This is only a syntax sugar for

-
(yas/define-snippets mode
-                     (list (list key template name condition group)))
-
-
-
-
-
-

The strategy to select a snippet

-

When user press the yas/trigger-key, YASnippet try to find a -proper snippet to expand. The strategy to find such a snippet is -explained here.

-
-

Finding the key

-

YASnippet search from current point backward trying to find the -snippet to be expanded. The default searching strategy is quite -powerful. For example, in c-mode, "bar", "foo_bar", -"#foo_bar" can all be recognized as a template key. Further more, -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.

-
-
-

The condition system

-

I write forked snippet.el to make the smart-snippet.el. I call it -smart-snippet because a condition can be attached to a snippet. This -is really a good idea. However, writing condition for a snippet -usually needs good elisp and Emacs knowledge, so it is strange to many -user.

-

Later I write YASnippet and persuade people to use it instead of -smart-snippet.el. However, some user still love smart-snippet because -it is smart. So I make YASnippet smart. Even smarter than -smart-snippet.el. :p

-

Consider this scenario: you are an old Emacs hacker. You like the -abbrev-way and set yas/trigger-key to (kbd "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).

-

It's OK, 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 YASnippet introduce a buffer local variable -yas/buffer-local-condition. You can set this variable to (not -(python-in-string/comment)) in python-mode-hook. There's no way -to do this in smart-snippet.el!

-

Then, what if you really want some snippet even in 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, snippet won't be -expanded.
  • -
  • If it evaluate 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):
      -
    • If the snippet has no condition, then it won't be expanded.
    • -
    • If the snippet has a condition but evaluate to nil or error -occured during evaluation, it won't be expanded.
    • -
    • If the snippet has a condition that evaluate 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 expanded.
      • -
      -
    • -
    -
  • -
  • If it evaluate to 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 expanded.
    • -
    -
  • -
-

So set yas/buffer-local-condition like this

-
(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.

-
-
-

Multiple snippet with the same key

-

There can be multiple snippet bind to the same key. If you define a -snippet with a key that is already used, you'll overwrite the original -snippet definition. However, you can add a different postfix to the -key.

-

In general, the extension (consider a file name) is ignored when -defining a snippet. So def, def.1 and def.mine will all be -valid candidates when the key is def.

-

When there are multiple candidates, YASnippet will let you select -one. The UI for selecting multiple candidate can be -customized. There're two variable related:

-
    -
  • yas/window-system-popup-function: the function used when you -have a window system.
  • -
  • yas/text-popup-function: the function used when you don't have a -window system, i.e. when you are working in a terminal.
  • -
-
-Currently there're three solution come with YASnippet.
-images/popup-menu.png - -
-

Just select the first one

-

This one is originally used in terminal mode. It doesn't let you to -choose anything, it just select the first one on behalf of you. So I -bet you never want to use this. :p

-
-
-

Use a dropdown-menu.el

-images/dropdown-menu.png -

Originally, only the above two function is available in -YASnippet. They are difficult to use -- especially in a -terminal. Until later Jaeyoun Chung show me his dropdown-menu.el, -I say wow! It's wonderful!

-
    -
  • It works in both window system and terminal.
  • -
  • It is customizable, you can use C-n, C-p to navigate, q -to quite and even press 6 as a shortcut to select the 6th -candidate.
  • -
-

So I added yas/dropdown-list-popup-for-template to support -dropdown-list.el. And upload dropdown-list.el to YASnippet -hompage for an optional download (since Jaeyoun didn't provide a URL).

-

Then finally, in 0.4.0, I included a copy of the content of -dropdown-list.el [1] in yasnippet.el and made it the default -way for selecting multiple candidates.

-

However, the original functions are still there, you can still use this

-
(setq yas/window-system-popup-function
-      'yas/x-popup-menu-for-template)
-
-

if you prefer a modern UI. :)

-
-
-
-

The Trigger Key

-

YASnippet is implemented as a minor-mode (yas/minor-mode). The -trigger key yas/trigger-key is defined in yas/minor-mode-map -to call yas/expand to try to expand a snippet.

-
-

The Minor Mode

-images/minor-mode-indicator.png -

When yas/minor-mode is enabled, the trigger key will take -effect. The default key is (kbd "TAB"), however, you can freely -set it to some other key. By default, YASnippet add a hook to -after-change-major-mode-hook to enable yas/minor-mode [2] in -every buffer. This works fine for most modes, however, some mode -doesn't follow the Emacs convention and doens't call this hook. You -can either explicitly hook for those mode or just add it to -yas/extra-mode-hooks to let YASnippet do it for you:

-
(require 'yasnippet)
-(add-to-list 'yas/extra-mode-hooks
-             'ruby-mode-hook)
-(yas/initialize)
-
-

Note that should be put after (require 'yasnippet) and before -(yas/initialize). Further more, you may report it to me, I'll add -that to the default value.

-
-
-

The Fallback

-

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 bind 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. This is useful when you -would like YASnippet to work with other extensions, -e.g. hippie-expand. I'm also glad to tell you that integration -with hippie-expand is already included in YASnippet.

-
-
-

Integration with hippie-expand

-

To integrate with hippie-expand, just put -yas/hippie-try-expand in -hippie-expand-try-functions-list. Personally I would like to put -in front of the list, but it can be put anywhere you prefer.

-
-
-
-

Other way to select a snippet

-

When you use the trigger key (so yas/expand) to expand a snippet, -the key for the snippet is deleted before the template for the snippet -is inserted.

-

However, there're other ways to insert a snippet.

-
-

The Menu

-

YASnippet will setup a menu just after the Buffers Menu in the -menubar. The snippets for all real 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 python-mode in a -c-mode buffer by selecting it from the menu:

-images/menubar.png -
    -
  • Condition system is ignored since you select to expand it -explicitly.
  • -
  • There will be no muliple candidates since they are listed in the -menu as different items.
  • -
-

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 yas/use-menu to nil.

-

Another thing to note is that only real modes are listed under the -menu. As you know, common snippets can be shared by making up a -virtual parent mode. It's too bad if the menu is floored by those -virtual modes. So YASnippet only show menus for those real -modes. But the snippets fo the virtual modes can still be accessed -through the parent submenu of some real mode.

-

YASnippet use a simple way to check whether a mode is real or -virtual: (fboundp mode). For example, the symbol c-mode is -bound to a function while cc-mode 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 (yas/known-modes). You can add item -to that list if you need.

-
-
-

Expanding From Elisp 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:

-
(yas/expand-snippet (point) (point) template)
-
-

Where template is the template of a snippet. It is never required -to belong to any snippet -- you can even make up it on the fly. The -1st and 2nd parameter defines the region to be deleted after YASnippet -inserted the template. It is used by yas/expand to indicate the -region of the key. There's usually no need to delete any region when -we are expanding a snippet from elisp code, so passing two (point) -is fine. Note only (point) will be fine because the 1st parameter -also indicate where to insert and expand the template.

-
-
-
-
-

The Syntax of the Template

-

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 elisp code

-

Elisp code can be embedded inside the template. They are written -inside back-quotes (`):

-

They 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:

-
#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
-#define $1
-
-$0
-
-#endif /* $1 */
-
-
-
-

Tab Stops

-

Tab stops are fields that you can navigate back and forth by TAB -and S-TAB [3]. 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:

-
<div$1>
-    $0
-</div>
-
-
-
-

Placeholders

-

Tab stops can have default values -- a.k.a placeholders. The syntax is -like this:

-
${N:default value}
-
-

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:

-
\begin{${1:enumerate}}
-    $0
-\end{$1}
-
-

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(YouTube or 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.

-
-
-

Transformations

-

If the default value of a field starts with $, then it is interpreted -as the transformation code instead of default value. A transformation -is some arbitrary elisp code that will get evaluated in an environment -when the variable text is bind to the inputted text of the -field. Here's an example for Objective-C:

-
- (${1:id})${2:foo}
-{
-    return $2;
-}
-
-- (void)set${2:$(capitalize text)}:($1)aValue
-{
-    [$2 autorelease];
-    $2 = [aValue retain];
-}
-$0
-
-

Look at ${2:$(capitalize text)}, it is a transformation instead of -a placeholder. The actual placeholder 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 -transformated 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

-
=====
-Title
-=====
-
-

is a valid title but

-
===
-Title
-===
-
-

is not. Here's an snippet for rst title:

-
${1:$(make-string (string-width text) ?\=)}
-${1:Title}
-${1:$(make-string (string-width text) ?\=)}
-
-$0
-
- - - - - -
[1]With some minor change, mainly for fixing some trivial bugs.
- - - - - -
[2]This is done when you call yas/initialize.
- - - - - -
[3]Of course, this can be customized.
-
-
-

Indenting

-

Many people miss the indenting feature of smart-snippet: when you -place a $> in your snippet, an (indent-according-to-mode) will -be executed there to indent the line. So you'll not need to hard-code -the indenting in the snippet template, and it will be very convenient -when you need to work with several different project where coding -styles are different.

-

The reason why this feature wasn't added to YASnippet until after -0.5.6 is that it doesn't work well for all modes. In some cases -(e.g. python-mode), calling indent-according-to-mode will break -the overlays created by YASnippet.

-

However, since many people asked for this feature, I finally added -this to YASnippet. Here's an example of the usage:

-
for (${int i = 0}; ${i < 10}; ${++i})
-{$>
-$0$>
-}$>
-
-
-
-
-
-
-
-
-
-
- - diff --git a/doc/faq.html b/doc/faq.html deleted file mode 100644 index f9a40e0..0000000 --- a/doc/faq.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - -How to define a snippet ? - - - - - -
-
-
-
- -
-
-
-
-
-

Why there's 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 TAB key doesn't expand a snippet?

-

First check the mode line to see if there's yas. If no, then try -M-x yas/minor-mode-on to manually turn on yas/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:

-
(setq yas/extra-mode-hooks '(the-major-mode))
-
-

where the-major-mode is the major mode in which yas/minor-mode -isn't enabled by default.

-

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 <tab> runs the command -..., note the difference between TAB and <tab> where the -latter has priority. If you see <tab> bound to a command other -than yas/expand, (e.g. in org-mode) you can try the following -code to work around:

-
(add-hook 'org-mode-hook
-          '(lambda ()
-             (make-variable-buffer-local 'yas/trigger-key)
-             (setq yas/trigger-key [tab])))
-
-

replace org-mode-hook with the major mode hook you are dealing -with (C-h m to see what major mode you are in).

-

If it says TAB but YASnippet still doesn't work, check your -configuration and you may also ask for help on the discussion group. 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).

-
-
-

How to define snippets with named by characters not supported by the filesystem?

-

For example, you want to define a snippet by the key < which is not a -valid character for filename on Windows. In this case, you may use -yas/define to define the snippet. If you want to enjoy defining -snippets in a file, you can use the key property to specify the key of -the defined snippet explicitly.

-

Just name your snippet with an arbitrary valid filename, lt for -example. and specify < for the key property:

-
#key: <
-#name: <...></...>
-# --
-<${1:div}>$0</$1>
-
-
-
-
-
-
-
-
-
- - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 192028e..0000000 --- a/doc/index.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - -Yet Another Snippet extension - - - - - -
-
-
-
- -
-
-
-
- -

Yasnippet is a template system for emacs. It allows you to type a -abbrevation and automatically expand the abbreviation into function -templates.

-

Bundled language templates includes: C, C++, C#, Perl, Python, Ruby, -SQL, LaTeX, HTML, CSS and more.

-

Yasnippet system is inspired from TextMate's template system. You can -use a tool -to import any TextMate template you have to Yasnippet. It is a -re-design and re-write of my original extension smart-snippet. It -is much cleaner and more powerful than smart-snippet.

-
-

Video Demo

-

Watch the demo at YouTube (download a higher -resolution version: yasnippet.avi).

-
-
-

Brief Install Instruction

-

There are two archives of YASnippet. One is a single file compiled -“bundle”, and the other is normal. If all you need is to use the -builtin templates, download the bundle one. If you want to add your -own templates, download the normal one.

-
-

Bundle Install

-
    -
  1. Download the latest yasnippet-bundle-x.y.z.el.tgz and unpack it.
  2. -
  3. You'll get a file named yasnippet-bundle.el, put it under -~/.emacs.d/plugins/ (create the directory if not exists).
  4. -
  5. Open the file in Emacs, and type Alt+x eval-buffer.
  6. -
-

That's it. Now open any one of your language file, you'll see a menu -YASnippet. you can pull the menu to insert a template. Or, you can -type the pre-defined abbrev and press TAB to expand it.

-

To have emacs load YASnippet automatically when it starts, put the -following in your ~/.emacs file:

-
-
(add-to-list 'load-path
-              "~/.emacs.d/plugins")
-(require 'yasnippet-bundle)
-
-
-
-
-

Normal Install

-

For full install of the normal archive, just download and unpack the -latest yasnippet-x.y.z.tar.bz2. You'll get a directory named -yasnippet, put it in your ~/.emacs.d/plugins and add the -following in your .emacs file:

-
-
(add-to-list 'load-path
-              "~/.emacs.d/plugins")
-(require 'yasnippet) ;; not yasnippet-bundle
-(yas/initialize)
-(yas/load-directory "~/.emacs.d/plugins/yasnippet/snippets")
-
-
-

Please refer to the documentation for full customization.

-
-
-
-

Bugs, Contribution and Support

- -

Thank you very much for using YASnippet!

-
-
-
-
-
-
-
-
- - diff --git a/dropdown-list.el b/dropdown-list.el new file mode 100644 index 0000000..7b451d5 --- /dev/null +++ b/dropdown-list.el @@ -0,0 +1,251 @@ +;;; dropdown-list.el --- Drop-down menu interface +;; +;; Filename: dropdown-list.el +;; Description: Drop-down menu interface +;; Author: Jaeyoun Chung [jay.chung@gmail.com] +;; Maintainer: +;; Copyright (C) 2008 Jaeyoun Chung +;; Created: Sun Mar 16 11:20:45 2008 (Pacific Daylight Time) +;; Version: +;; Last-Updated: Sun Mar 16 12:19:49 2008 (Pacific Daylight Time) +;; By: dradams +;; Update #: 43 +;; URL: http://www.emacswiki.org/cgi-bin/wiki/dropdown-list.el +;; Keywords: convenience menu +;; Compatibility: GNU Emacs 21.x, GNU Emacs 22.x +;; +;; Features that might be required by this library: +;; +;; `cl'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; According to Jaeyoun Chung, "overlay code stolen from company-mode.el." +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change log: +;; +;; 2008/03/16 dadams +;; Clean-up - e.g. use char-to-string for control chars removed by email posting. +;; Moved example usage code (define-key*, command-selector) inside the library. +;; Require cl.el at byte-compile time. +;; Added GPL statement. +;; 2008/01/06 Jaeyoun Chung +;; Posted to gnu-emacs-sources@gnu.org at 9:10 p.m. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 3, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'cl)) ;; decf, fourth, incf, loop, mapcar* + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defface dropdown-list-face + '((t :inherit default :background "lightyellow" :foreground "black")) + "*Bla." :group 'dropdown-list) + +(defface dropdown-list-selection-face + '((t :inherit dropdown-list-face :background "purple")) + "*Bla." :group 'dropdown-list) + +(defvar dropdown-list-overlays nil) + +(defun dropdown-list-hide () + (while dropdown-list-overlays + (delete-overlay (pop dropdown-list-overlays)))) + +(defun dropdown-list-put-overlay (beg end &optional prop value prop2 value2) + (let ((ov (make-overlay beg end))) + (overlay-put ov 'window t) + (when prop + (overlay-put ov prop value) + (when prop2 (overlay-put ov prop2 value2))) + ov)) + +(defun dropdown-list-line (start replacement &optional no-insert) + ;; start might be in the middle of a tab, which means we need to hide the + ;; tab and add spaces + (let ((end (+ start (length replacement))) + beg-point end-point + before-string after-string) + (goto-char (point-at-eol)) + (if (< (current-column) start) + (progn (setq before-string (make-string (- start (current-column)) ? )) + (setq beg-point (point))) + (goto-char (point-at-bol)) ;; Emacs bug, move-to-column is wrong otherwise + (move-to-column start) + (setq beg-point (point)) + (when (> (current-column) start) + (goto-char (1- (point))) + (setq beg-point (point)) + (setq before-string (make-string (- start (current-column)) ? )))) + (move-to-column end) + (setq end-point (point)) + (let ((end-offset (- (current-column) end))) + (when (> end-offset 0) (setq after-string (make-string end-offset ?b)))) + (when no-insert + ;; prevent inheriting of faces + (setq before-string (when before-string (propertize before-string 'face 'default))) + (setq after-string (when after-string (propertize after-string 'face 'default)))) + (let ((string (concat before-string replacement after-string))) + (if no-insert + string + (push (dropdown-list-put-overlay beg-point end-point 'invisible t + 'after-string string) + dropdown-list-overlays))))) + +(defun dropdown-list-start-column (display-width) + (let ((column (mod (current-column) (window-width))) + (width (window-width))) + (cond ((<= (+ column display-width) width) column) + ((> column display-width) (- column display-width)) + ((>= width display-width) (- width display-width)) + (t nil)))) + +(defun dropdown-list-move-to-start-line (candidate-count) + (decf candidate-count) + (let ((above-line-count (save-excursion (- (vertical-motion (- candidate-count))))) + (below-line-count (save-excursion (vertical-motion candidate-count)))) + (cond ((= below-line-count candidate-count) + t) + ((= above-line-count candidate-count) + (vertical-motion (- candidate-count)) + t) + ((>= (+ below-line-count above-line-count) candidate-count) + (vertical-motion (- (- candidate-count below-line-count))) + t) + (t nil)))) + +(defun dropdown-list-at-point (candidates &optional selidx) + (dropdown-list-hide) + (let* ((lengths (mapcar #'length candidates)) + (max-length (apply #'max lengths)) + (start (dropdown-list-start-column (+ max-length 3))) + (i -1) + (candidates (mapcar* (lambda (candidate length) + (let ((diff (- max-length length))) + (propertize + (concat (if (> diff 0) + (concat candidate (make-string diff ? )) + (substring candidate 0 max-length)) + (format "%3d" (+ 2 i))) + 'face (if (eql (incf i) selidx) + 'dropdown-list-selection-face + 'dropdown-list-face)))) + candidates + lengths))) + (save-excursion + (and start + (dropdown-list-move-to-start-line (length candidates)) + (loop initially (vertical-motion 0) + for candidate in candidates + do (dropdown-list-line (+ (current-column) start) candidate) + while (/= (vertical-motion 1) 0) + finally return t))))) + +(defun dropdown-list (candidates) + (let ((selection) + (temp-buffer)) + (save-window-excursion + (unwind-protect + (let ((candidate-count (length candidates)) + done key (selidx 0)) + (while (not done) + (unless (dropdown-list-at-point candidates selidx) + (switch-to-buffer (setq temp-buffer (get-buffer-create "*selection*")) + 'norecord) + (delete-other-windows) + (delete-region (point-min) (point-max)) + (insert (make-string (length candidates) ?\n)) + (goto-char (point-min)) + (dropdown-list-at-point candidates selidx)) + (setq key (read-key-sequence "")) + (cond ((and (stringp key) + (>= (aref key 0) ?1) + (<= (aref key 0) (+ ?0 (min 9 candidate-count)))) + (setq selection (- (aref key 0) ?1) + done t)) + ((member key `(,(char-to-string ?\C-p) [up] "p")) + (setq selidx (mod (+ candidate-count (1- (or selidx 0))) + candidate-count))) + ((member key `(,(char-to-string ?\C-n) [down] "n")) + (setq selidx (mod (1+ (or selidx -1)) candidate-count))) + ((member key `(,(char-to-string ?\f)))) + ((member key `(,(char-to-string ?\r) [return])) + (setq selection selidx + done t)) + (t (setq done t))))) + (dropdown-list-hide) + (and temp-buffer (kill-buffer temp-buffer))) + ;; (when selection + ;; (message "your selection => %d: %s" selection (nth selection candidates)) + ;; (sit-for 1)) + selection))) + +(defun define-key* (keymap key command) + "Add COMMAND to the multiple-command binding of KEY in KEYMAP. +Use multiple times to bind different COMMANDs to the same KEY." + (define-key keymap key (combine-command command (lookup-key keymap key)))) + +(defun combine-command (command defs) + "$$$$$ FIXME - no doc string" + (cond ((null defs) command) + ((and (listp defs) + (eq 'lambda (car defs)) + (= (length defs) 4) + (listp (fourth defs)) + (eq 'command-selector (car (fourth defs)))) + (unless (member `',command (cdr (fourth defs))) + (setcdr (fourth defs) (nconc (cdr (fourth defs)) `(',command)))) + defs) + (t + `(lambda () (interactive) (command-selector ',defs ',command))))) + +(defvar command-selector-last-command nil "$$$$$ FIXME - no doc string") + +(defun command-selector (&rest candidates) + "$$$$$ FIXME - no doc string" + (if (and (eq last-command this-command) command-selector-last-command) + (call-interactively command-selector-last-command) + (let* ((candidate-strings + (mapcar (lambda (candidate) + (format "%s" (if (symbolp candidate) + candidate + (let ((s (format "%s" candidate))) + (if (>= (length s) 7) + (concat (substring s 0 7) "...") + s))))) + candidates)) + (selection (dropdown-list candidate-strings))) + (when selection + (let ((cmd (nth selection candidates))) + (call-interactively cmd) + (setq command-selector-last-command cmd)))))) + +;;;;;;;;;;;;;;;;;;;; + +(provide 'dropdown-list) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; dropdown-list.el ends here \ No newline at end of file diff --git a/snippets/text-mode/email b/snippets/text-mode/email index b953111..1ac7f94 100644 --- a/snippets/text-mode/email +++ b/snippets/text-mode/email @@ -1,3 +1,3 @@ #name : (user's email) # -- -`user-mail-address` \ No newline at end of file +`(replace-regexp-in-string "@" "@NOSPAM." user-mail-address)` \ No newline at end of file diff --git a/snippets/text-mode/objc-mode/crazy b/snippets/text-mode/objc-mode/crazy deleted file mode 100644 index 6aa0220..0000000 --- a/snippets/text-mode/objc-mode/crazy +++ /dev/null @@ -1,4 +0,0 @@ -#name : foo { ... } ; setFoo { ... } -# -- -I say ${1:hello} and so ${2: goodbye $1} -She also says $2 \ No newline at end of file diff --git a/snippets/text-mode/objc-mode/prop b/snippets/text-mode/objc-mode/prop deleted file mode 100644 index f17ae13..0000000 --- a/snippets/text-mode/objc-mode/prop +++ /dev/null @@ -1,14 +0,0 @@ -#name : foo { ... } ; setFoo { ... } -# -- -- ${1:id} ${2:foo and its ${3:nested} shit} -{ - return $2; - // dont forget we have $3 -} - -- (void)set${2:$(capitalize text)}:($1)aValue -{ - [$2 autorelease]; - $2 = [aValue retain]; -} -$0 \ No newline at end of file diff --git a/snippets/text-mode/snippet-mode/field b/snippets/text-mode/snippet-mode/field new file mode 100644 index 0000000..bdaf0d4 --- /dev/null +++ b/snippets/text-mode/snippet-mode/field @@ -0,0 +1,5 @@ +# name : ${ ... } field +# contributor : joaotavora +# key : $f +# -- +\${${1:${2:n}:}$3${4:\$(${5:lisp-fn})}\}$0 \ No newline at end of file diff --git a/snippets/text-mode/snippet-mode/mirror b/snippets/text-mode/snippet-mode/mirror new file mode 100644 index 0000000..94c8e56 --- /dev/null +++ b/snippets/text-mode/snippet-mode/mirror @@ -0,0 +1,6 @@ +# name : ${n:$(...)} mirror +# key : $m +# contributor : joaotavora +# -- +\${${2:n}:${4:\$(${5:reflection-fn})}\}$0 + diff --git a/snippets/text-mode/snippet-mode/vars b/snippets/text-mode/snippet-mode/vars new file mode 100644 index 0000000..f271767 --- /dev/null +++ b/snippets/text-mode/snippet-mode/vars @@ -0,0 +1,9 @@ +# name : Snippet header +# contributor : joaotavora +# -- +# name : $1${2: +# key : ${3:expand-key}}${4: +# key : ${5:group}} +# contributor : $6 +# -- +$0 \ No newline at end of file diff --git a/yasnippet.el b/yasnippet.el index 192483a..acfcb9c 100644 --- a/yasnippet.el +++ b/yasnippet.el @@ -3,7 +3,7 @@ ;; Copyright 2008 pluskid ;; Authors: pluskid , joaotavora -;; Version: 0.6.0 beta +;; Version: 0.6.0b ;; X-URL: http://code.google.com/p/yasnippet/ ;; Keywords: snippet, textmate ;; URL: http://code.google.com/p/yasnippet/ @@ -27,22 +27,59 @@ ;;; Commentary: ;; Basic steps to setup: -;; 1. Place `yasnippet.el' in your `load-path'. +;; +;; 1. In your .emacs file: ;; (add-to-list 'load-path "/dir/to/yasnippet.el") -;; 2. In your .emacs file: ;; (require 'yasnippet) -;; 3. Place the `snippets' directory somewhere. E.g: ~/.emacs.d/snippets -;; 4. In your .emacs file +;; 2. Place the `snippets' directory somewhere. E.g: ~/.emacs.d/snippets +;; 3. In your .emacs file ;; (setq yas/root-directory "~/.emacs/snippets") ;; (yas/load-directory yas/root-directory) -;; 5. To enable the YASnippet menu and tab-trigger expansion +;; 4. To enable the YASnippet menu and tab-trigger expansion ;; M-x yas/minor-mode -;; 6. To globally enable the minor mode in *all* buffers +;; 5. To globally enable the minor mode in *all* buffers ;; M-x yas/global-mode ;; -;; Steps 5. and 6. are optional, you can insert use snippets without -;; them via: -;; M-x yas/insert-snippet +;; Steps 4. and 5. are optional, you don't have to use the minor +;; mode to use YASnippet. +;; +;; +;; Major commands are: +;; +;; M-x yas/expand +;; +;; Try to expand snippets before point. In `yas/minor-mode', +;; this is bound to `yas/trigger-key' which you can customize. +;; +;; M-x yas/load-directory +;; +;; Prompts you for a directory hierarchy of snippets to load. +;; +;; M-x yas/insert-snippet +;; +;; Prompts you for possible snippet expansion if that is +;; possible according to buffer-local and snippet-local +;; expansion conditions. With prefix argument, ignore these +;; conditions. +;; +;; 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'. +;; +;; M-x yas/find-snippet-file +;; +;; Prompts you for possible snippet expasions like +;; `yas/insert-snippet', but instead of expanding it, takes +;; you directly to the snippet definition's file, if it +;; exits. +;; +;; M-x yas/load-snippet-buffer +;; +;; When editing a snippet, this loads the snippet. This is +;; bound to "C-c C-c" while in the `snippet-mode' editing +;; mode. ;; ;; The `dropdown-list.el' extension is bundled with YASnippet, you ;; can optionally use it the preferred "prompting method", puting in @@ -54,6 +91,7 @@ ;; yas/completing-prompt)) ;; ;; Also check out the customization group +;; ;; M-x customize-group RET yasnippet RET ;; ;; For more information and detailed usage, refer to the project page: @@ -392,20 +430,24 @@ snippet templates") (defvar yas/minor-mode-map (make-sparse-keymap) "The keymap used when `yas/minor-mode' is active.") -(easy-menu-define yas/minor-mode-menu - yas/minor-mode-map - "Menu used when YAS/minor-mode is active." - (cons "YASnippet" - (mapcar #'(lambda (ent) - (when (third ent) - (define-key yas/minor-mode-map (third ent) (second ent))) - (vector (first ent) (second ent) t)) - (list (list "--") - (list "Expand trigger" 'yas/expand (read-kbd-macro yas/trigger-key)) - (list "Insert at point" 'yas/insert-snippet "\C-c&\C-s") - (list "About" 'yas/about) - (list "Reload-all-snippets" 'yas/reload-all) - (list "Load snippets..." 'yas/load-directory))))) +(defun yas/init-keymap-and-menu () + (easy-menu-define yas/minor-mode-menu + yas/minor-mode-map + "Menu used when YAS/minor-mode is active." + (cons "YASnippet" + (mapcar #'(lambda (ent) + (when (third ent) + (define-key yas/minor-mode-map (third ent) (second ent))) + (vector (first ent) (second ent) t)) + (list (list "--") + (list "Expand trigger" 'yas/expand (read-kbd-macro yas/trigger-key)) + (list "Insert at point" 'yas/insert-snippet "\C-c&\C-s") + (list "About" 'yas/about) + (list "Reload-all-snippets" 'yas/reload-all) + (list "Load snippets..." 'yas/load-directory)))))) + +(eval-when-compile + (yas/init-keymap-and-menu)) (define-minor-mode yas/minor-mode "Toggle YASnippet mode. @@ -884,20 +926,40 @@ content of the file is the template." (message "done."))) (defun yas/reload-all () - "Reload all snippets and rebuild the YASnippet menu." + "Reload all snippets and rebuild the YASnippet menu. " + (interactive) - (setq yas/snippet-tables (make-hash-table)) - (setq yas/menu-table (make-hash-table)) - (setq yas/minor-mode-menu nil) - (setq yas/minor-mode-map (make-sparse-keymap)) - (yas/init-keymap-and-menu) - (if yas/root-directory - (if (listp yas/root-directory) - (dolist (directory yas/root-directory) - (yas/load-directory directory)) - (yas/load-directory yas/root-directory)) - (call-interactively 'yas/load-directory)) - (message "done.")) + (let ((restore-global-mode nil) + (restore-minor-mode nil)) + (setq yas/snippet-tables (make-hash-table)) + (setq yas/menu-table (make-hash-table)) + (setf (cdr yas/minor-mode-menu) nil) + (setf (cdr yas/minor-mode-map) nil) + (when yas/global-mode + (yas/global-mode -1) + (setq restore-global-mode t)) + + (when yas/minor-mode + (yas/minor-mode -1) + (setq restore-minor-mode t)) + + (yas/init-keymap-and-menu) + + (if yas/root-directory + (if (listp yas/root-directory) + (dolist (directory yas/root-directory) + (yas/load-directory directory)) + (yas/load-directory yas/root-directory)) + (call-interactively 'yas/load-directory)) + + + (when restore-minor-mode + (yas/minor-mode 1)) + + (when restore-global-mode + (yas/global-mode 1)) + + (message "done."))) (defun yas/quote-string (string) "Escape and quote STRING. @@ -908,23 +970,31 @@ foo\"bar\\! -> \"foo\\\"bar\\\\!\"" string t) "\"")) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Yasnipept Bundle + +(defun yas/initialize () + "For backward compatibility, enable `yas/minor-mode' globally" + (yas/global-mode 1)) (defun yas/compile-bundle (&optional yasnippet yasnippet-bundle snippet-roots code dropdown) "Compile snippets in SNIPPET-ROOTS to a single bundle file. -SNIPPET-ROOTS is a list of root directories that contains the snippets -definition. YASNIPPET is the yasnippet.el file path. YASNIPPET-BUNDLE -is the output file of the compile result. CODE is the code you would -like to used to initialize yasnippet. Here's the default value for -all the parameters: +SNIPPET-ROOTS is a list of root directories that contains the +snippets definition. YASNIPPET is the yasnippet.el file +path. YASNIPPET-BUNDLE is the output file of the compile +result. CODE is the code you would like to used to initialize +yasnippet. Last optional argument DROPDOWN is the filename of the +dropdown-list.el library. + +Here's the default value for all the parameters: (yas/compile-bundle \"yasnippet.el\" \"./yasnippet-bundle.el\" '(\"snippets\") \"(yas/initialize)\") -Last optional argument DROPDOWN is the filename of the -dropdown-list.el library... +.. " (when (null yasnippet) @@ -933,6 +1003,8 @@ dropdown-list.el library... (setq yasnippet-bundle "./yasnippet-bundle.el")) (when (null snippet-roots) (setq snippet-roots '("snippets"))) + (when (null dropdown) + (setq dropdown "dropdown-list.el")) (when (null code) (setq code (concat "(yas/initialize-bundle)" "\n;;;###autoload" ; break through so that won't @@ -1216,7 +1288,7 @@ by condition." (yas/template-env template)) (message "[yas] No snippets can be inserted here!")))) -(defun yas/find-snippet-by-key () +(defun yas/find-snippet-file () "Choose a snippet to edit, selection like `yas/insert-snippet'." (interactive) (let* ((yas/buffer-local-condition 'always) @@ -1234,8 +1306,14 @@ by condition." (car templates))))) (when template - (find-file-other-window (yas/template-file template)) - (snippet-mode)))) + (let ((file (yas/template-file template))) + (cond ((and file (file-exists-p file)) + (find-file-other-window file) + (snippet-mode)) + (file + (message "Original file %s no longer exists!" file)) + (t + (message "This snippet was not loaded from a file!"))))))) (defun yas/guess-snippet-directory () "Try to guess the suitable yassnippet based on `major-mode'" @@ -1256,7 +1334,7 @@ by condition." path)))) -(defun yas/find-snippet (&optional same-window) +(defun yas/find-snippets (&optional same-window) "Find a snippet file in a suitable directory." (interactive "P") (let* ((current-table (yas/current-snippet-table major-mode 'dont-search-parents))