大分長い間use-packageを利用していましたが、一日掛けてleaf.elに移行してみました。leaf.elの利点や移行時の注意などをまとめたいと思います。
use-packageに感じていた問題点
・・・というのは実はあまりないんですが、あえて言えば次のような点でした。
- 設定のgroupingがしづらい
- use-packageはネストすることを前提としていない?ので、packageの設定が分散しがち
- bindの設定方法が独特
- aggressive-indentを使っていると、中々にindentが荒ぶります
- 標準パッケージをきちんと利用する方法がよくわからない
あまり頻繁に.emacs.dを更新していない、というのもあるんですが、端的に言うと まーいいか という状態でした。
leaf.el
leaf.elは、 leaf.el is yet another use-package.
として作成されたpackageです。use-packageと比較してどうか?というのは、作者が書いている記事を見たほうが早いでしょう。
https://qiita.com/conao3/items/dc88bdadb0523ef95878
利用してみた感じでいうと、大体use-packageと同じ使用感ですが、色々と統一感が出るのがいい感じです。また、設定をグルーピングするという目的でも使えるので、use-packageで不自由だった部分が解消されて設定がスッキリしました。
移行後の内容は、以下のrepositoryを見てもらったほうが早いです。
https://github.com/derui/dot.emacs.d/blob/master/conf/package-config.el
まだ修正中なので、いくつか不具合を抱えています。また、packageがあまりかかわらず、設定のフォルダとして利用した例は次のファイルに書いています。
https://github.com/derui/dot.emacs.d/blob/master/conf/emacs-base-setting.el
leaf.elに移行してみて
ただ、leaf.elもいいところばかりではなく、いくつか設定上の問題がありました。
bindingが上手く行かない問題
leaf.elでは、bindingに設定した関数は、基本的にそのpackage内の関数である、とみなそうとします。
(pp (macroexpand '(leaf evil
:bind
(:evil-normal-state-map
("f" . evil-forward-quote-char)
("F" . my:evil-forward))
:config
(defun my:evil-forward () ()))))
;; =>
;; (prog1 'evil
;; (leaf-handler-leaf-protect evil
;; (unless
;; (fboundp 'evil-forward-quote-char)
;; (autoload #'evil-forward-quote-char "evil" nil t))
;; (unless
;; (fboundp 'my:evil-forward)
;; (autoload #'my:evil-forward "evil" nil t))
;; (declare-function evil-forward-quote-char "evil")
;; (declare-function my:evil-forward "evil")
;; (defvar evil-normal-state-map)
;; (leaf-keys
;; ((:evil-normal-state-map :package evil
;; ("f" . evil-forward-quote-char)
;; ("F" . my:evil-forward))))
;; (eval-after-load 'evil
;; '(progn
;; (defun my:evil-forward nil nil)))))
こんな感じに。このとき、特に問題になるのが 自作関数 です。autoloadしようにも、そのpackage内に存在していないので、当然ながらload出来ません。また、こういう関数は、大抵このpackageの関数を使っているので、 :config
内に書いたりしています。そうなると、bindしようにも :config
が実行されるのは、上の例でいくとevilがloadされた後になるんですが、その辺りが上手く動かない、というケースが多発しました。
上記のautoload設定問題があって、例えばevilのkeymapに色々な設定を追加していこうとしても、各々の関数を持つpackage自体に設定が分散してしまう、という問題があります。まぁgrepすれば見つかるものではあるんですが、どうも一箇所でまとまっていない、というのが若干気持ち悪いポイントになっています。
設定の棚卸しは定期的に
今回leaf.elに移行してみて、全体を見直していたのですが、重複していたり矛盾する設定だったりがあり、その整理も出来たのでちょうどよかったです。棚卸しは定期的に行うべきですね。
仕事上ではEmacsだけではなく、Visual Studio CodeやIntelliJとかも利用しており、Emacsだけに依存していません。特にVisual Studio Codeは特に高速性や見た目の良さなどから、Emacsからのいい移行対象だなぁ、と思ったりもします。
ただ、Emacs自体も以前から考えると大分進化しているのと、なんか長いものに巻かれるのも悔しいので、引き続きEmacsを育てていこうと思います。