Emacsパッケージマネージャ決定版:これからのパッケージ管理はstraight.elで決まり!
ども、久々のブログ更新は最近導入したstraight.elというEmacsのパッケージマネージャについて書きます。
7年ほどEmacsを使い続けてきましたが、まだまだ初心者の域を抜け出せずにいる id:nukosuke です。
前置き
全世界76億人のEmacs使いの皆さんはどうやってelパッケージを管理していますでしょうか。
僕はこれまでpackage.elやCask、el-getなどのパッケージマネージャを使ってきましたが、どれも好きになれませんでした。
というのも、僕がパッケージマネージャに唯一求めるのはマシンを買い変えた時の環境再現性(reproducibility)であって、今まで触れてきたものはこれを担保するためにかなりの労力を費やす必要があったからです。
具体的には、
- package.el : そもそもパッケージのバージョンをロックする機能がない・・・
- Cask : python 2系に依存していたためにpython 3に切り替えた途端に動かなくなった・・・
- el-get : リビジョンハッシュを指定しないと最新版のパッケージがインストールされてしまい、いつのまにかパッケージ同士の互換性がなくなっていた・・・
と、パッケージマネージャごとにいろいろな苦しみがありました。
追記 2018/4/11:
id:taraoさんからコメントでel-get-lockというパッケージを教えていただきました。
el-getではこれを使うことでロックファイルを生成することができるようです。
それでもEmacsを愛していたのでなんとかやってこれましたが、そろそろ限界。
そんなときに会社の同期にSpacemacsを勧められました。(straight.elじゃないのかよ)
こういった大きなディストリビューションにはあんまり興味がなかったので最初は乗り気ではなかったのですが、ちょっとだけ触ってみようと思ってインストールしてみたら、これがわりと良い。
設定要らずで必要な機能はほぼ揃うし、ファイル拡張子から必要なモードを自動的に判断してlayer(設定のまとまり)を勝手に設定ファイルに追記するという変態っぷり。layerはSpacemacsのリポジトリがホスティングしているので突然設定が壊れることもありません。最高やないか。
そんなこんなで特に不満を抱くこともなく、気づけば1年弱使っていました。
これだったらAtomでもVSCodeでもなんでもいいじゃないか!(あえてあいつの名前を出さない勇気)
そもそもEmacsを好きになったのは自分の好みを投影できるからであって、
なんというか・・・こう・・・大衆のイメージに染まっていない地下アイドルを応援するような気持ちです。
と、前置きが長くなりましたがそういうわけでもう一度、秘伝のタレ探求に乗り出したわけです。
straight.el
このパッケージマネージャを知ったのはかなり最近です。どういう経緯で行き着いたのか全く覚えてないのですが、気づいたらブックマークに入っていました。
Next-generation, purely functional package manager for the Emacs hacker.
なんともキャッチーじゃないですか?
READMEには他のパッケージマネージャとの比較が書いてあるので、ニーズに応じてどれを使うべきか判断する材料にもなります。
そして、原則にはしっかりと 100% reproducible と書いてありますし、説明を読めば読むほどこれが長年探し求めていたものだと思いました。
しかし、残念なことに以前管理に苦しんでいたときにはこのパッケージマネージャはまだ存在しなかったのです。最初のバージョンがリリースされたのは2017年1月。
つまり最先端なのです。
メリット
straight.elを使うメリットはたくさんあります。
このエントリでは、その中から僕がこのパッケージマネージャを気に入った主な理由を2つ挙げます。
use-packageマクロをstraight.elにフォールバックできる
use-packageはパッケージのrequireやら、load-pathの設定やら、キーバインドの設定やら、その他諸々をひとまとめにできる強力なマクロです。 るびきち先生のこちらの記事でも紹介されているように、use-packageを使うと設定ファイルの可読性が一気に上がります。
また、use-package自体にはパッケージをインストールする機能はないのですが、読み込み時にパッケージが存在しなかった場合に別途パッケージマネージャを使ってインストールする処理にフォールバックすることができます。
そして、use-packageのREADMEには「フォールバック先にはデフォルトでpackage.elを使用するが、use-package-ensure-function
を上書きすることで別のパッケージマネージャを使うことができる*1」と記述があります。
いわく、現在*2この拡張に対応しているのはstraight.elだけとのことです。
これでuse-packageが無敵になりました。
lockファイルを生成できる
はっきり言って導入の決め手はこれです。Caskやel-getでもバージョンを固定することはできましたが、自分で指定する必要がありました。
でもstraight.elを使えば、もう温もりの手作業でリビジョンハッシュを設定ファイルに書き込む必要はないんです。
M-x straight-freeze-versions
を実行すると ~/.emacs.d/straight/versions
という名前のlockファイルが生成されるので、これをgitで管理しておくことで、設定を行ったときと同一のバージョンでパッケージ構成をいつでもどこでも再現できるのです。
設定例
ちゃんと仕様を知りたければもちろん公式のREADMEを読んだ方がいいです。
ここでは僕がstraight.elを使い始めるにあたって最初に行った設定を紹介します。
;; 何も考えず公式のREADMEからコピペすればいいコード ;; straight.el自身のインストールと初期設定を行ってくれる (let ((bootstrap-file (concat user-emacs-directory "straight/repos/straight.el/bootstrap.el")) (bootstrap-version 3)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) ;; use-packageをインストールする (straight-use-package 'use-package) ;; オプションなしで自動的にuse-packageをstraight.elにフォールバックする ;; 本来は (use-package hoge :straight t) のように書く必要がある (setq straight-use-package-by-default t) ;; init-loaderをインストール&読み込み (use-package init-loader) ;; ~/.emacs.d/init/ 以下のファイルを全部読み込む (init-loader-load "~/.emacs.d/init")
これであとは ~/.emacs.d/init/
いかにそれぞれのパッケージの設定ファイルを置けばいいだけになりました。
例えばcompanyの設定ファイルはこんな感じです。
インストール、読み込み、変数の設定からキーバインドまで一挙に行うことができます。
(use-package company :init (setq company-selection-wrap-around t) :bind (:map company-active-map ("M-n" . nil) ("M-p" . nil) ("C-n" . company-select-next) ("C-p" . company-select-previous) ("C-h" . nil)) :config (global-company-mode))
さいごに
新しいということもあってか、これまでのパッケージマネージャに抱いていた不満がstraight.elでは全て解消されていました。
これを使って設定ファイルを書き直してからまだ一度も壊れていませんし、そもそも100% reproducibleの言葉どおり、毎回同じバージョンが降ってくるので壊れようがありません。プライベート用のPCで作った設定を編集することなく、仕事用PCで全く同じ環境を作ることにも成功しました。
僕のようにいろんなパッケージマネージャを渡り歩いてきた方、 特に環境移行の際に設定ファイルのメンテナンスコストに悩まされているという方はstraight.elを試してみてはいかがでしょうか。