※原文: http://yasnippet.googlecode.com/svn/trunk/doc/snippet-organization.html
重要: このドキュメントは YASnippet の SVN trunk に対して適用されるものです。 SVN trunk はこちらから取得できます。 他のバージョンに対するドキュメントはこちらで見られます。
スニペットの定義は、ファイルシステム上のファイルの中に格納されます。 よりシンプルな "bundle" バージョンを使っているのでなければ、それらのファイルは YASnippet が snippet table に読み込めるように配置されています。 トリガーメカニズム(Expanding snippets を参照)はこの snippet table を調べ、(望むらくは)あなたの意図するスニペットを展開します。
"bundle" 版でないバージョンの YASnippet は、それを展開(解凍)した時点で、完全なディレクトリ構成を備えています。 あなたはそれをどこにでも好きなところにコピーして使うことができます。 また、他にもディレクトリを作ったりダウンロードしたりすることができます。
これらのディレクトリ群を適当な場所に置いたら、その場所を yas/root-directory
変数で参照するようにしてください。
また、その場所を yas/load-directory
で読み込んでください。
;; Develop and keep personal snippets under ~/emacs.d/mysnippets
(setq yas/root-directory "~/emacs.d/mysnippets")
;; Load the snippets
(yas/load-directory yas/root-directory)
(yas/load-directory
を直接呼び出すのではなく)yas/root-directory
を使うのは、
"~/emacs.d/mysnippets
" をスニペットの開発のための場所とみなすためです。
こうすることで、あなたは yas/new-snippet
やその他の「Writing Snippets」で記述されているようなコマンド群を使うことができます。
この変数をリストにして、複数の値を格納することができます:
;; Develop in ~/emacs.d/mysnippets, but also
;; try out snippets in ~/Downloads/interesting-snippets
(setq yas/root-directory '("~/emacs.d/mysnippets"
"~/Downloads/interesting-snippets"))
;; Map `yas/load-directory' to every element
(mapc 'yas/load-directory yas/root-directory)
すぐ上の例では、すべてのディレクトリが読み込まれ、そこにあるスニペットは展開すべきものとみなされます。
それでいながら、開発は依然として最初の要素である "~/emacs.d/mysnippets
" で行われます。
yas/root-directory
の設定ができたら、これらのディレクトリのサブディレクトリにスニペットを格納することができます。
スニペットの定義はプレインテキストファイルに置かれます。 それらのファイルはサブディレクトリに配置されます。 snippet table にはこれらのディレクトリの名前がつけられます。
snippet table の名前は、あなたがスニペット展開を行わせたい Emacs モードに一致しています。
たとえば、c-mode
に対するスニペットは、c-mode
という名前のサブディレクトリに置かれます。
とあるモード向けのスニペットを含むディレクトリ階層の抜粋を以下に示します:
$ tree
.
`-- text-mode
|-- cc-mode
| |-- c-mode
| | `-- printf
| |-- for
| |-- java-mode
| | `-- println
| `-- while
|-- email
|-- perl-mode
| |-- cperl-mode
| `-- for
`-- time
親ディレクトリは、そのサブディレクトリすべての parent table の役割を果たしています。
これは、異なる Emacs メジャーモードがスニペットの定義を共有するための方法のひとつです。
上の例にあるように、c-mode
と java-mode
は同じ親 cc-mode
を共有しており、その while
スニペットを共有しています。
また、すべてのモードは text-mode
に由来する time
スニペットを共有しています。
この仕組みは alias (別名)としても使えます。cperl-mode
は perl-mode
を親とする空のディレクトリです。
.yas-parents
ファイルparent table を設定するもうひとつの(より好まれる)方法は、サブディレクトリのひとつに .yas-parents
という名前のプレインテキストファイルを置くことです。
こうすると、ディレクトリがネストして複雑になってしまうのを回避することができます。
.yas-parents
ファイルの中には、モードの名前を空白で区切って書くだけです。
このファイルは、スニペットの階層化に柔軟性と可読性をもたらします。
$ tree
.
|-- c-mode
| |-- .yas-parents # contains "cc-mode text-mode"
| `-- printf
|-- cc-mode
| |-- for
| `-- while
|-- java-mode
| |-- .yas-parents # contains "cc-mode text-mode"
| `-- println
`-- text-mode
|-- email
`-- time
.yas-make-groups
ファイル各モードのディレクトリのひとつに .yas-make-groups
という名前の空のプレインテキストファイル(訳注:矛盾してますね・・・)を置くと、
これらのサブディレクトリの名前はスニペットのグループの名前とみなされます。
これにより、The YASnippet Menu は、ずっと明確に整理されます(右の画像のように)。
同じことをするためのもうひとつのは、# group:
ディレクティブをスニペット定義の中に置くことです。
Writing Snippets の章を参照してください。
$ tree ruby-mode/
ruby-mode/
|-- .yas-make-groups
|-- collections
| |-- each
| `-- ...
|-- control structure
| |-- forin
| `-- ...
|-- definitions
| `-- ...
`-- general
`-- ...
通常、ファイル名はスニペット展開の省略形(これは snippet key または snippet trigger とも呼ばれますが ‥‥ Expanding Snippets の章を参照)として使われます。
また一方で、yas/ignore-filenames-as-triggers
変数を true に設定するか、または、
.yas-ignore-filename-triggers
という名前の空のファイルを置くか、どちらかをすると、
ずっと説明的なファイル名を使えるようになります。
ひとつのモードに対するたくさんのスニペットが同じ trigger key を共有しているような場合にこの仕組みは役に立ちます。
$ tree rails-mode/
rails-mode/
|-- .yas-make-groups
|-- .yas-ignore-filename-triggers
|-- Insert ERb's <% __ %> or <%= __ %>.yasnippet
|-- asserts
| |-- assert(var = assigns(%3Avar)).yasnippet
| |-- assert_difference.yasnippet
| |-- assert_no_difference.yasnippet
| |-- assert_redirected_to (nested path plural).yasnippet
| |-- assert_redirected_to (nested path).yasnippet
| |-- assert_redirected_to (path plural).yasnippet
| |-- assert_redirected_to (path).yasnippet
| |-- assert_rjs.yasnippet
| `-- assert_select.yasnippet
YASnippet 向けのスニペットを定義するもっとも便利な方法は、モードごとに配置されたディレクトリの中にスニペットの定義を置いて、
yas/load-directory
でそれらを読み込むことです。
しかし、多くのスニペットがある場合、この方法だと Emacs の起動スピードが遅くなるかもしれません。
Emacs-lisp ファイルの中で特定のモードに対するスニペット群を定義するためには、yas/define-snippets
を使うことができます。
このやり方はメンテナンスが大変なので、もっといい方法があります: ディレクトリの中でスニペットを定義しておいて、
そのスニペットを変更したときには、そのスニペット定義をバンドルファイルにコンパイルするために M-x yas/compile-bundle
を呼ぶ、というやり方です。
YASnippet では、リリースされているバンドルファイルは yas/compile-bundle
によって生成されています。
バンドルは、スニペットを定義するために yas/define-snippets
を使っています。
これにより、スニペットを読み込む際の I/O および構文解析のオーバヘッドを回避することができます。
もっと言ってしまうと、生成されたバンドルファイルは独立したファイルであり、yasnippet.el
に依存していません。
YASnippet でリリースされているバンドルファイルは、すべてこのやり方で生成されています。
これらの機能に関する内部向けのドキュメントとしては以下をご覧ください:
M-x describe-function RET yas/define-snippets RET
M-x describe-function RET yas/compile-bundle RET
yas/root-directory
各メジャーモードに対するスニペットを格納しているルートディレクトリ。
この変数を .emacs で定義する場合、複数のルートディレクトリを指定するために、文字列のリストとすることもできます。
リストにした場合、その最初の要素は常にユーザ作成スニペット用のディレクトリとなります。
それ以外の要素は、yas/reload-all
での全スニペットの再読み込みの対象となります。
yas/ignore-filenames-as-triggers
nil で無い場合、ファイル名から tab trigger を派生させません。
これは、スニペットについて、tab trigger を指定する # key:
ディレクティブが書かれていないものとみなすことを意味します。
(日本語訳: Seaoak, 2010/Dec/15)