EmacsのYasnippet環境を整える

深夜に突然yasnippetの良さについて完全に理解したので諸々ちゃんと設定してみた。snippetはorgで管理するようにした。


全体的な設定は以下のURLで Yasnippet で検索をすると出る。

何はともあれ、Yanisppetを導入する。僕はleaf.elユーザなので以下のように記述をした。

(leaf yasnippet
  :ensure t
  :init (yas-global-mode 1)
  :custom
  (yas-snippet-dirs . '("~/.emacs.d/yasnippets")))

ivyとcompanyの設定もする。今のご時世、swiperがないのは考えられない。

companyのyasnippet関係の記述は別pluginではなく、 company-mode/company-mode - company-yasnippet.elにあるので設定が楽。

(leaf company
  :ensure t
  :defvar company-backends
  :init
  (global-company-mode)
  :config
  (add-to-list 'company-backends 'company-yasnippet)
  :bind
  (:company-active-map
   ("C-n" . company-select-next)
   ("C-p" . company-select-previous)))

(leaf ivy-yasnippet
  :ensure t
  :after (yasnippet)
  :bind (("C-c y" . ivy-yasnippet)
         ("C-c C-y" . ivy-yasnippet)))

次は一番肝心のsnippet管理方法だ。

普通ならAndreaCrotti/yasnippet-snippetsを使うのが一般的だろう。

ただ、以下の点が気にくわないので直接使うのを見送った。

  • orgで管理できない
  • 普段書かないmodeのsnippetは不用なので削除したい
  • 普段書くmodeでも要らないsnippetが結構ある
  • ファイル数が膨大すぎてメンテ性が悪い

そこで以下のような手順を踏んでorgで管理できるようにした

  1. AndreaCrotti/yasnippet-snippetsをcloneする
  2. ざっとmodeやsnippetを見て不用なものを削除していった
  3. snippetの記述をorgに出力する雑なscriptを書いた
  4. conao3/org-generate.elをインストール
  5. M-x org-generate~/.emacs.d/yasnippet/**-mode/* に展開されるようにした
  6. Makefileにhtmlを出力するようなscriptを書いた

3に関して、適当にファイル名とsnippetを取得してbufferにinsertするscriptを書いた。使い捨てなので酷いけど御愛嬌。

(defun tmp ()
  (interactive)
  (mapcar #'(lambda (mode)
              (insert (s-concat "\n*** " mode))
              (mapcar #'(lambda (file)
                          (insert
                           (s-concat
                            "\n**** " file
                            "\n#+BEGIN_SRC snippet\n"
                            (f-read-text (f-join "~/.emacs.d/snippets" mode file))
                            "\n#+END_SRC")))
                      (directory-files (f-join "~/.emacs.d/snippets" mode) nil "[^.]")))
          (directory-files "~/.emacs.d/snippets" nil "[^.]")))

4に関して、 ~/.emacs.d/yasnippets.orgorg-generate-file に指定してgenerateできるようにした。

(leaf org-generate
  :ensure t
  :custom
  (org-generate-file . `,(locate-user-emacs-file "yasnippets.org")))

6に関して、適当なMakefileを書いた。https://takeokunn.github.io/.emacs.d/yasnippets.html でsnippet一覧をみることができる。

$(HTMLIZE_FILE):
    wget https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el

.PHONY: org-to-html
org-to-html: $(HTMLIZE_FILE)
    $(EMACS) yasnippets.org -Q --batch --eval "(progn (load \""$(HTMLIZE_FILE)"\") (setq org-html-htmlize-output-type 'css) (org-html-export-to-html))"

今後のTODOは以下。

  • conao3/org-generate.el の仕様では h1/h2 という形でしか出力できないので h1 で出力できるように改造したい
  • AndreaCrotti/yasnippet-snippetsのコードを部分的に拝借しているのでライセンス的にどうなのか調査する
  • snippetをどんどん増やして利便性を上げる
  • 自作org-themeの開発

まだまだ改良の余地があるが、格段に利便性が上がったので引続き整えていきたい。