設定を見直し中 - すぎゃーんメモ シリーズ。
yasnippetを使ったスニペット補完を初めて使い始めている。で、補完の呼び出し方には通常のyas/expand
コマンドを呼ぶ以外に、auto-complete-configに含まれるac-source-yasnippet
を使う方法や、anythingインタフェースで選択するためのanything-c-yasnippetがある。
yasnippet, anything-c-yasnippetのまとめエントリー - IMAKADO::BLOG
個人的にはauto-completeの補完とyasnippetのスニペット補完は別々にしたいな、と思ってanything-c-yasnippetを使おうと思ったのだけど、どうやらコレは最新のyasnippetでは動かないらしい。
yasnippet,anything-c-yasnippetをインストールした - $shibayu36->blog;
yasnippet-0.6.1b(c?)を使うとanything-c-yasnippet.elが動かない - 放牧日記
これらの記事のように、パッチを当てる必要がある。
で、このanything-c-yasnippetやyasnippetのソースを読んでいて気付いたのだけど、今のyasnippetにはyas/prompt-functions
という変数が定義されている。ログ見る限りでは2009-07-13、v0.6.0あたりから出てきたのかな?
(defcustom yas/prompt-functions '(yas/x-prompt yas/dropdown-prompt yas/completing-prompt yas/ido-prompt yas/no-prompt)
複数の補完候補があった場合に、ここに登録されている関数が呼ばれ、ユーザに選択させることになるらしい。それらの関数はプロンプト文字列と、選択候補のリストを引数として受け取り、確定させる場合はそのリスト内の要素を返す。nilが返された場合は次の関数に選択を任せることになるようだ。デフォルトでは上記のように定義されていて、例えばyas/x-prompt
はx-popup-menu
関数を使ってユーザに選択させることになる。同じkeyで異なる定義のスニペットを複数登録してある場合や、2つ以上のスニペットが登録してあるモードでyas/insert-snippet
を呼んだときはコレが呼ばれるはず。
なので、このprompt-functionsを自分で定義してやれば、anythingインタフェースを簡単に作ることができる。
(defun my-yas/prompt (prompt choices &optional display-fn) (let* ((names (loop for choice in choices collect (or (and display-fn (funcall display-fn choice)) coice))) (selected (anything-other-buffer `(((name . ,(format "%s" prompt)) (candidates . names) (action . (("Insert snippet" . (lambda (arg) arg)))))) "*anything yas/prompt*"))) (if selected (let ((n (position selected names :test 'equal))) (nth n choices)) (signal 'quit "user quit!")))) (custom-set-variables '(yas/prompt-functions '(my-yas/prompt)))
丁寧なことにオプショナルな第3引数としてchoicesリストそれぞれの要素(templateのオブジェクト)から登録してあるテンプレート名を引くための関数が渡されてきてくれるので、それを使って候補名のリストを作って、anything-other-buffer
に渡してやるだけで良い。actionでは選択した名前をそのまま渡すようにすることで、変数selectedに選択されたテンプレート名を得ることができる。中断した場合はnilが返ってくるので、quitシグナルを送ってやることで補完も中断される。
これだけで、anything-c-yasnippetを導入してパッチを当てたりしなくても、yasnippetの補完をanythingインタフェースで実現することができた。さくさく選べるようになるのでちょっとしたモノもどんどんsnippetに登録していくと効率が上がりそう。
試しにauto-completeとyasnippetの補完を使ってコードを書く例をyoutubeに上げてみた。
スラスラっと書けるカンジがして良いですね。