読者です 読者をやめる 読者になる 読者になる

$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

yasnippetの見直しをした

tech emacs

 昔yasnippetすごいなーと思って、少しだけ使っていたのだけれど、なんかうまく使えていないなーと思ったので見直しをした。

設定

 これまではyasnippet,anything-c-yasnippetをインストールした - $shibayu36->blog;の時に設定した時のまま(version 0.6.1)だったのだが、見直しをしたら0.8までversionが上がっていて、しかもいろいろ関数名とか変わってたので、そのままでは動かなかった。
 最終的に以下のようになった。

(require 'yasnippet)

(setq yas-snippet-dirs
      '("~/.emacs.d/snippets"))
(yas-global-mode 1)

(custom-set-variables '(yas-trigger-key "TAB"))

;; anything interface
(eval-after-load "anything-config"
  '(progn
     (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))
                                       choice)))
              (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)))))

 昔はanything-c-yasnippetみたいなのを使っていたのだが、いろいろ動かないというのと、yasnippet自体からanythingに対応できるようなので、それを使うようにした。コード自体はsugyanさんが書いてたanything-c-yasnippetを使わずにyasnippetをanythingインタフェースで選択する - すぎゃーんメモのをそのままもらった。

幾つかsnippet作る

 とりあえずperl用に幾つかsnippet作ってみた。snippetの書き方については、yasnippet 8.0の導入からスニペットの書き方、anything/helm/auto-completeとの連携あたりが分かりやすい。今の構成は下のような感じになってる。

emacs.d/snippets/
├── cperl-mode
│   ├── foreach
│   ├── ife
│   ├── method\ sub
│   ├── method_test
│   ├── package
│   ├── package_test
│   ├── script
│   ├── sub
│   └── unless
└── html-mode
    ├── xslate-for
    ├── xslate-if
    └── xslate-if-inline

method

method用snippet

# -*- mode: snippet -*-
# name: method sub
# binding: C-c C-c C-m
# --
sub $1 {
    my ($self$2) = @_;
    $0
}

script

script書くときの最初のやつ

# -*- mode: snippet -*-
# key  : script
# name : Perl script template
# binding: C-c C-c C-s
# --
#!/usr/bin/env perl
use strict;
use warnings;

$0

package

packageのsnippet。

# -*- mode: snippet -*-
# key: package
# name: package
# binding: C-c C-c C-p
# --
package ${1:`(yas/perl-package-name)`};
use strict;
use warnings;

$0

1;

これは``で囲むとelisp実行できるというのを利用して、以下を定義しておいて実行することで、lib/Sample/Package.pmとかだと、Sample::Packageとかを展開してくれるようにしてる。

(defun yas/perl-package-name ()
  (let ((file-path (file-name-sans-extension (buffer-file-name))))
    (if (string-match "lib/" file-path)
        (replace-regexp-in-string "/" "::"
                                  (car (last (split-string file-path "/lib/"))))
      (file-name-nondirectory file-path))))

xslate用FOR

 xslateのFOR IN構文。

# -*- mode: snippet -*-
# name: [% FOR ... IN ... %] ... [% END # ... %]
# key: xslate-for
# binding: direct-keybinding
# --

[%- FOR ${1:val} IN ${2:array} -%]
$0
[%- END # FOR $1 IN $2 -%]

 ミラーリング機能を使うことによって、

[%- FOR var IN array -%]
...
[%- END # FOR var IN array -%]

みたいな感じにわかりやすく書くようにしてみた。

結論

 とりあえずもう一度見なおして、いくつか定義してみた。0.8になって結構いろいろ出来るみたいなので、今後も試してみたい。