PVの存在は知っていたのだが、ライブ版の映像は初めて見た!!!!!
「POP HILL」というイベントは石川県で行われていた野外ロックフェスだとのこと。残念ながら最近は開催されていないらしい。
この映像の最後のところで、次の曲(あ゛〜、タイトルが出てこない。歌えるのに)へのイントロが入っているんだけど、続きの映像はないのだろうか!? 観てみたいなぁ。
本日開催された「第2回PHP懇親会」へ参加してきた。会場は新宿三丁目の「ファンデリ」。参加者全員が5分の持ち時間でライトニングトークするという構成だったので、オレも発表してきた。
今回は(また?)PHP本体じゃなく、その周辺の話。
おととい「yasnippetがすごい!!!!1112345!」というエントリを見て、「なにー!それは見てみなければ!」と思って見てみたものの、php-mode用の snippet が無かったので勢いで作ってみたのだが、それをネタとして発表した。
php-mode 用の snippet を作るにあたって、HowtoDefineSnippetを読んでいたのだが、英語だとなかなか頭に入らない人なのでチマチマと意訳していった。それをちょっと整形してここにさらしてみる。
翻訳でなく意訳なので、正確なニュアンスの表現はできていないし、間違っている箇所は沢山あると思われるので、怪しいな?と思ったら原文の参照を推奨。
HowtoDefineSnippet
snippet の定義のやり方
snippet は yas/define 関数を通して定義します。または、
yas/load-directory 以下にファイルを置いて使う事も可能です。ご自身で作成
したカスタム snippet も yas/compile-bundle を使って stand-alone bundle
としてコンパイルすることが可能です。stand-alone bundle は、ライブラリの
ロードが楽(require するだけ!)ですし、毎回ディレクトリ階層をパースす
るよりも高速です。
関数
yas/define
基本的な yas/define のシンタックスは次の通りです。
(yas/define MODE KEY TEMPLATE &optional NAME)
パラメータは次の通りです。
MODE: snippet を定義するモードの名称
KEY: snippet のトリガーとなるキー
TEMPLATE: snippet を展開するテンプレート
NAME: snippet の簡単な説明。これはメニューに表示されます。この部分を省
略すると、KEY の部分が NAME として利用されます。
例:
(yas/define 'c-mode "if" "if (${condition})
{
$0
}" "if (...) { ... }")
TEMPLATE の書式については、この後のセクションを見てください。
同じキーで複数の snippet を定義する事が可能です。
例:
(yas/define 'c-mode "if.one-stmt" "if (${condition})
$0" "if (...) ...")
snippet を定義する際のトリックですが、KEY はファイル名のように扱われま
すが拡張子は取り除かれます。この例で言えば「.one-stmt」は取り除かれます。
もし、本当に同じ KEY で定義した場合は、後から定義した方が以前の定義を上
書きします。しかし、最初の定義とは違うサフィックス(または拡張子)を追
加した場合は、同じ KEY に複数の snippet を割り当てられます。
ある KEY に複数の snippet が割り当てられている場合、ポップアップメニュー
が表示されます。メニューには snippet の NAME が表示されます。これは、
NAME を表示させておく良いアイデアとなっています。
yas/define-snippets
yas/define-snippets を使って、沢山の snippet を定義することができます。
基本的なシンタックスは次の通りです。
(yas/define-snippets MODE SNIPPETS &optional parent)
例:
(yas/define-snippets 'text-mode
'(("email" "`user-mail-address`" "User's email address")
("time" "`(current-time-string)`" "Current Time")
("foo" "blablablabla")))
例を見てください。 SNIPPETS は snippet 定義のリストになります。それぞれ
の定義のシンタックスは yas/define に identical です。最後にあるオプショ
ンパラメータである PARENT は、特定の親モードの時に利用する事ができます。
snippet の検索構造は、まず、現在のモードの snippet テーブル、次に親モー
ドの snippet テーブルを再帰的に検索します。
yas/load-directory
yas/load-directory の基本的なシンタックスは次の通り:
(yas/load-directory DIRECTORY)
使い方は簡単です。
(yas/load-directory "~/.emacs.d/snippets/")
M-x yas/load-directory と入力し、どのディレクトリを読み込むかをインタラ
クティブに指定することも可能です。指定されたディレクトリ以下にある一致
したモード名のサブディレクトリを contains します。そして、それらのサブ
ディレクトリ以下は、それぞれのモードの snippet の定義となります。典型的
なディレクトリ構造はこのようになります。
snippets/
+-- c-mode
| +-- if
| +-- for
| `-- main
+-- java-mode
| +-- if
| `-- class
`-- ruby-mode
+-- each
`-- select
snippet のファイル名は snippet の KEY となります。TEMPLATE と NAME は、
ファイルの中身からパースされます。典型的な snippet ファイルの中身はこの
ようになります。
#name : select { |...| ... }
# --
select { |${1:element}| $0 }
「# --」の行があるとき、この行の前まではコメントとして扱われます。そし
て、その行以降の全てのコンテンツが、TEMPLATE として扱われます。
コメントセクションには特定の変数を利用することができます。現在サポート
されている変数のリストは次の通りです(現在はひとつしかありません)。
name: snippet の NAME
変数のシンタックスは次の通りです:
#variable-name : variable-value
もし「# --」の行が無かった場合、ファイル内容の全体が TEMPLATE として扱
われます。
ファイル末尾の改行もテンプレートのコンテンツになることに注意してくださ
い。snippet の最後に改行を含めたくない場合は、ファイル末尾に改行を加え
ないようにしてください。また、あなたの利用しているエディタが自動的に挿
入しないようにしてください。
バージョン 0.2.0 から、ディレクトリ構造は再帰的なサブディレクトリを使え
るようになりました。次のようにです(ディレクトリのみを表示しています)
snippets/
+-- cc-mode/
| +-- c-mode/
| +-- c++-mode/
| +-- java-mode/
`-- text-mode/
この場合、cc-mode は自動的に c-mode、c++-mode、java-mode の親モードとし
て扱われます。
yas/compile-bundle
yas/compile-bundle の基本的なシンタックスは次の通りです。
(yas/compile-bundle YASNIPPET YASNIPPET-BUNDLE SNIPPET-ROOTS)
パラメータは次の通り:
YASNIPPET: yasnippet.el のパス(path)
YASNIPPET-BUNDLE: 出力するバンドルのパス(path)
SNIPPET-ROOTS: snippet のディレクトリ(ディレクトリのリスト)
例:
(yas/compile-bundle "~/.emacs.d/plugins/yasnippet/yasnippet.el"
"~/.emacs.d/plugins/yasnippet-bundle.el"
'("~/.emacs.d/plugins/yasnippet/snippets"))
snippet のルートディレクトリがひとつの場合、最後のパラメータは次のよう
なシンプルな書き方も可能です。
(yas/compile-bundle "~/.emacs.d/plugins/yasnippet/yasnippet.el"
"~/.emacs.d/plugins/yasnippet-bundle.el"
"~/.emacs.d/plugins/yasnippet/snippets")
これはなにをするのか?
yasnippet.el を yasnippet-bundle.el としてコピーする。
いくつかの初期化コードを追加する(実際は (yas/initialize) のみ)
ディレクトリ内の snippet 定義をパースし、それらの snippet の適切な
yas/define を yasnippet-bundle.el へ追加する。
この結果、 yasnippet-bundle.el は単独で利用できる .el ファイルとなりま
す。あとは、作成されたファイルを load-path へ置き、、あなたの ~/.emacs
ファイルへ (require 'yasnippet-bundle) と書くだけです。するとシステムが
自動的に snippet の読み込みと初期化を実行してくれます。
シンタックス
snippet TEMPLATE のシンタックスを説明します。
プレインテキスト
snippet が展開されるとき。キーはテンプレートと置き換えられます。テンプ
レートは任意のテキストを含むことができます。例外は $ と ` です。これら
は特別なキャラクタとして扱われますので、直前に \ を加えてエスケープをす
る必要があります。perl-mode を例は次のようになります。
eval {
${1:# do something risky...}
};
if (\$@) {
${2:# handle failure...}
}
if (\$@) { の行に注意してください。$ がエスケープされています。
時折は \ 自身をエスケープする必要がでてきます。例えば、\$ を記述したい
時には \\$ と書く必要があります。
組み込みの elisp コード
テンプレートの中で elisp コードが使えます。この場合は、バッククォート
(`)内に記述します。
`some elisp arbitrary code`
このコードは snippet が展開されるときに評価されます。snippet が展開され
るバッファ内での評価となります。c-mode の場合の例です。
#ifndef ${1:_`(upcase (file-name-nondirectory (file-name-sans-extension (buffer-file-name))))`_H_}
#define $1
$0
#endif /* $1 */
これは、現在の buffer-file-name を取得し、ディレクトリ部分と拡張子部分
を削除し、大文字にした上でヘッダファイルのガードマクロ定義として利用し
ます。
タブストップ
タブストップは、TAB キーと Shift + TAB キーを使って、前後へ移動できる
フィールドのことです。これは、$ に続いて数字を記述します。
$N
$0 は snippet の脱出場所という特別な意味を持ちます。全てのフィールドを
行き来し追えたときに行く最後の場所です。代表的な例は次の通りです。
<div$1>
$0
</div>
snippet が展開されたとき、最初に移動するポイントは $1 の部分になります。
この部分にテキストを入力をした後(入力しなくても良い)、TAB キーを押す
と $0 のポイントへ移動します。
プレイスホルダ
タブストップはデフォルト値(プレイスホルダとして知られています)を持つ
ことができます。シンタックスの例はこのようになります:
${N:default value}
これらはタブストップのデフォルト値として振る舞います。しかし、タブストッ
プで何かを入力したら、デフォルト値は入力した値に入れ替わります。
ミラー
プレイスホルダ付きのタブストップをフィールドとして参照することができま
す(?)。フィールドは、ミラーを持つ事ができます。フィールドのテキスト
を変更すると共にミラーのテキストも変更されます。次の例を見てください:
\begin{${1:enumerate}}
$0
\end{$1}
あなたが ${1:enumerate} の部分で「document」と入力したとき、「document」
は \end{$1} の部分にも挿入されます。動画(YouTube もしくは avi ビデオ)
を見てもらえばもっと良く分かると思います。
同じ番号を持つタブストップは、ミラーとして扱われます。タブストップが初
期値を持っていない場合、最初に選択されたフィールドがその他のミラーとし
て扱われます。
数字が入っていないフィールドの例です:
if (${condition})
{
$0
}
この例は同じ番号を持つタブストップがないため、ミラーを持てません。ふた
つの番号がないフィールドは違う番号を持つものとみなされます。
トランスフォーメーション
$ で始まるフィールドのデフォルト値がある場合、それはデフォルト値のトラ
ンスフォーメーションコードとして扱われます。トランスフォーメーションは、
フィールドに入力されたテキストに応じて評価される任意の elisp コードです
(訳注:この部分、非常に怪しい翻訳。。。)
Objective-C のコード例です。
- (${1:id})${2:foo}
{
return $2;
}
- (void)set${2:$(capitalize text)}:($1)aValue
{
[$2 autorelease];
$2 = [aValue retain];
}
$0
${2:$(capitalize text)} を見てください。これはプレイスホルダからトラン
スフォーメーションするものです。実際のプレイスホルダは、最初の行の
${2:foo} です。${2:foo} にテキストを入力した時に評価が行われ、トランス
フォーメーションされたテキストが挿入されます。この例だと、フィールドに
baz と入力すると、トランスフォームされたテキストは Baz となります。この
例についても動画に動作が収録されています。
rst-mode 用の例です。reStructuredText では、ドキュメントのタイトルは
「===」で括られます。「===」はテキストと同じ長さにすべきです。
=====
Title
=====
この場合は正しいタイトルとなりますが、
===
Title
===
こちらは違います。 rst のタイトル用の snippet は、次のようになります。
${1:$(make-string (string-width text) ?\=)}
${1:Title}
${1:$(make-string (string-width text) ?\=)}
$0
入力したタイトルの長さに合わせた「=」が自動的に挿入されます。
どのあたりまでphp-mode用のスニペットを作成されたのかわかりませんが、こんなのもあったりするのでチェックしてみるといいかもしれません。<br>http://hg.apgwoz.com/yasnippet-php-mode/
うぉー、情報ありがとうございます。<br>すげー充実してますね。<br><br>僕が作ったスニペット(10個くらい)も全て入っている気配です。。。