16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EmacsAdvent Calendar 2019

Day 18

use-package.elからleaf.elに移行した

Last updated at Posted at 2019-12-17

この度、use-package.elからleaf.elに移行した。
どうして移行したのかや、その時の調査した周辺技術や、移行に関する知見を、せっかくだしメモしておく。

なお、内容を書くにあたって、Emacs 26.3とGitHubレポジトリのコードで調査している。

背景

Emacsのパッケージとその設定を、以下のように管理している。

  • dotfiles全般の一部としてGitHubにてGit管理している
  • package.elを使っている
    • Emacs24から標準だしね
  • use-package.elを使っている
    • メジャーなパッケージ設定を構造的に管理するパッケージ
    • 今年の春くらいに導入したばかり
    • パッケージ設定が構造的に書けて最高の気持ち
  • 野良パッケージを、git addgit submodule addを使って管理している
    • 野良パッケージはpackage.elの管理外のパッケージを指す
    • MELPAに登録されてないものや既存パッケージを一部変更したものがある
      • 例えば、手元のsml-modeにSML#のキーワードを追加している

問題点

  • GitHubのbranchやforkなどの野良パッケージを、Emacs Lispでキレイに扱いたい
    • use-package.elにこの機能はない
    • この解決のためにgit submoduleを使っているが、
      submoduleの初期化や更新など操作がフクザツなため止めたい
  • use-package.elを導入したばかりなので、コストは低く解決したい

結論

  • use-package.elとその拡張を使うのをやめた
    • 今回の調査では、満足できるuse-package.elの拡張が見つからなかった
  • use-package.elからleaf.elへ移行した
    • コストはそこそこ高かったが、完全移行してよかった点が多かった
    • leaf.elはいいぞ
  • 一部のgit submoduleは止めれていない
    • 今回は議論しないが、snippetのレポジトリをうまく扱う方法を考えていない

トライしたメモ

use-package.elはキーワードを拡張できるため、多数の統合拡張がある。
そこで、use-package.elの拡張を初めに調査した。
また、use-package.el以外にも良いパッケージ設定管理ツールがないか調査した。
特に、use-package.elとキーワードが似通っているとなお良い。

ざっくり調査すると以下の3つを見つけ、それぞれ試すことにした。

  • use-package.el + quelpa.el
  • use-package.el + straight.el
  • leaf.el

なお、パッケージ管理のバックエンドとしてはpackage.elは使うことにし、
これ以外のバックエンドの調査はしていない。

use-package.el + quelpa.el

Quelpaはパッケージのビルド・インストールを行うツールである。

これ自身にはuse-package.elのようなパッケージ設定管理の機能はない。
代わりに、quelpa-use-packageというインテグレーションが用意されている。

良かった

  • use-package.elとのインテグレーションがあるため移行コストが低い
    • use-package節内で:quelpaキーワードが使えるようになる
  • :quelpaキーワードを使って、GitHubのbranchが指定できる
  • package.elのパッケージ状態を認識してくれる
    • 依存関係などがいい感じに解決される
    • Quelpaでインストールするとpackage.elのインストールマークをつけてくれる
    • quelpa/buildでビルドしてelpaにコピーしているようだった

悪かった

  • 存在しないパッケージを(quelpa PACKAGE ...)で指定してもエラーが出ない
    • まじか???
    • :quelpaだとさすがにuse-package.elがエラーを出してくれる
  • 開発が終了している

use-package.el + straight.el

straight.elは次世代の純粋関数型のパッケージマネージャらしい。
なお、どの辺が純粋関数型なのかはよくわからなかった。
他のパッケージマネージャとの比較を、しっかりしているのに好感が持てた。

これも自身にはパッケージ設定管理の機能ははない。
代わりに、use-package.elとのインテグレーションを持っている。

良かった

  • use-package.elとのインテグレーションがあるため移行コストが低い
    • use-package節内で:straightキーワードが使えるようになる
  • :straightキーワードでGitHubのbranchやforkの指定ができる
    • 機能としてもドキュメントとしても便利
  • :straightキーワードを使うと、デフォルトでEmacsMirrorのパッケージも
    探索してくれて便利だった

悪かった

  • package.elとの相性が悪い
    • package.elのインストール状態を認識せず、
      straight.elは独自で依存関係も込みでインストールする
    • 結果、依存関係のパッケージが大量に重複してインストールされる

leaf.el

leaf.elはYet Another use-packageで、パッケージ設定管理のパッケージの1つ。
Emacs Advent Calendarにも多数寄稿している@conao3さんが開発している。
昨年12月にバージョン1.0.0が出た比較的新しいパッケージ。

何度かQiita記事でも目にしており、気になっていた。
YA use-package.elということで、移行コストを低く抑えつつ、
よりよい機能が得られるのではと思って試した。

良かった

  • package.elのパッケージ状態を認識してくれる
    • Quelpaと同上、というかpackage.elをバックエンドとして使っている?
  • GitHubのbranchが指定できる
    • el-get.elとのインテグレーションがあり、:el-getを使い実現できる
  • leaf節で:el-getを使ってインストールすると依存パッケージを解決しない
    • そもそもpackage.elの管理外のものを導入しようとしているため、
      依存関係などを自分で管理するのは妥当と思える
    • leaf節をネストして書けるため、依存関係も書きやすい
    • 導入元がpackage.elとel-get.elとで違うものを、ちゃんと分離して管理できる
  • leaf節をネストして書けるため、関連する設定をまとめられる
  • 移行しただけでEmacsの起動時間が半分になった
    • use-package.elでは:defer tで遅延読み込みの指定がいるが、
      leaf.elではデフォルトで遅延読み込みなのも効いていそう
    • use-package.elは起動時間の統計をとるなどリッチな機能を持っており、
      そもそも遅いのも効いていそう
    • 詳細な原因調査はしていない
    • な に も し て な い の に Emacs が は や く な り ま し た

悪かった

  • ネストしたleaf節がつくるツリー構造が、パッケージの関係性に合わないものがあった
    • あるモードの設定を、グローバルモードとメジャーモードのどちらに
      まとめるか問題
    • 例えば、company-jediはpython-modeでcompanyの補完を提供するが、
      機能としてcompanyにまとめるべきか、modeとしてpythonにまとめるべきか
    • 好きにすればいいと思った、書ける自由度があるのは良い
  • use-package.elと書き方違いが多少あり、まあまあ移行コストがかかった
    • 1,000行ほどの元のelファイルに対して、500行ほどのdiffがあった

leaf.el移行での変更点や感じたこと

  • キーワード名が一部違うことがある
    • :defer tに対応するのは:leaf-defer tなど
  • :customの引数のデータ構造と許される値が違う
    • :customの引数がリストではなくドットペア
    • :custom (x . (1+ a))のような未評価部は許されていない
      • defvar b (1+ a)とかして:custom (x . b)とする
  • デフォルトでパッケージがrequireされない
    • requireが必要なパッケージには:require tをつける
  • 遅延読み込みがデフォルトとなっている
  • :bindでのmap名の書き方が違う
    • (:map xxx-mode-map ...)(:xxx-mode-map ...)にする
16
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?