el-get.elでEmacs Lispパッケージをインストール・アップグレードする
Emacs Advent Calendar jp: 2010 の9日目の記事です。 去年のauto-install.el に引き続き、今年もインストーラの紹介です。
昨日は id:yaotti さん(anything関数を好きな言語で実装できるanything-with-everything.el (Emacs Advent Calendar 2010 8日目) - yaotti's diary)でした。 anything-with-everything.elは以前から作ろうと思っていたら先越されてしまいました。 明日は id:handlename さんです。
つい最近になって、Emacs Lispのインストールを管理するel-get.elが登場しました。 Emacs Lispのインストールといえば、auto-install.elやその前身のinstall-elisp.elがあります。 しかし、これらはEmacs Lispファイルそのものがインターネットに公開されている場合でしか使えません。 M-x auto-install-batchで複数ファイルで構成されているEmacs Lispをインストールできますが、ひとつひとつのEmacs Lispファイルに対応するURLが存在する場合に限られます。 Emacs Lisp『パッケージ』のインストーラとしては力不足なのが現状です。
el-get.elは、単体ファイル、Emacs Lisp Package Archive、Git、Git-Svn、bzr、CVS、darcs、apt-get、fink、tar、EmacsWiki、pacman、hgに対応しています。 tarやgitで公開されているEmacs Lispのインストール・アップグレードをEmacsの中で行うことができるようになります。
インストール
ELPA
まず最初にELPAをインストールします。 ELPAとは、Emacs Lisp版のaptみたいなシステムで、Emacs Lispパッケージのインストール・アンインストールを管理します。 ただ、登録されているパッケージの数が少ないという欠点があります。
M-x install-elisp http://tromey.com/elpa/package-install.el
ちなみに、Emacs24ではELPAが標準になるようです。
el-get.el
その後でel-get.el本体をインストールします。
Emacsに以下の式を貼り付けて評価してください。 最後の括弧にカーソルを置き、C-x C-eを押します。
これは、URLからel-get.elのインストーラをダウンロードして実行します。
(url-retrieve
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
すると、 ~/.emacs.d/el-get というディレクトリが作られ、それ以下にel-get含め、インストールしたパッケージが格納されます。
el-get-ext.el(暫定版)
素のel-get.elはまだ使いものにならないので、僕が拡張しました。
M-x install-elisp http://www.rubyist.net/~rubikitch/junk/2010-12-09-095707.el-get-ext.el
このコードは暫定版であり、作者に取り込んでもらう予定なので、あえてEmacsWikiには置いていません。 反映され次第、上のコードは不要になります。
以下の設定を.emacsに加えてください。
;; (save-window-excursion (shell-command (format "emacs-test -l %s %s &" buffer-file-name buffer-file-name))) (add-to-list 'load-path "~/.emacs.d/el-get/el-get/") (require 'el-get) (load "2010-12-09-095707.el-get-ext.el") ;; 初期化ファイルのワイルドカードを指定する (setq el-get-init-files-pattern "~/emacs/init.d/[0-9]*.el") (setq el-get-sources (el-get:packages)) (el-get)
標準機能
el-get.elのパッケージの一部は最低限の設定もやってくれます。 しかし、ロードすらしないパッケージもあります。 el-get.elはどこまで面倒を見るかは、まだ定まっていないようです。
現時点では、設定はおまけみたいなものであり、あらゆる方法によるインストールを統一化するという位置付けで考えるのが無難です。 少なくともload-pathの面倒は見てくれるので、後でrequireすれば使える状態になっています。
パッケージを見る
残念ながら、現時点では、パッケージ一覧を見るインターフェースは存在しません。 そう難しくないので、anything.elインターフェースを作るかもしれません(笑) とりあえず現時点では、 ~/.emacs.d/el-get/el-get/recipes/ を見てください。 100以上のパッケージが登録されています。
パッケージファイルの中身はパッケージ名やURLやload-path等、インストールに必要なメタデータです。 このメタデータのことを「レシピ」と呼びます。 レシピはEmacs Lispです。 レシピのファイル名から拡張子(.el)を取り除いたものを「レシピ名」と呼ぶことにします。
インストールしたいものがあったとき、レシピ名を el-get-sources に加えておく必要があります。 しかし、後述する方法でel-get-sourcesを意識しなくて済むようになります。 そして、Emacsを再起動すれば、起動時にインストールされます。
M-x el-get-installでインストールする
レシピ名を el-get-sources に加え、el-get-sourcesを更新(setq el-get-sourcesの行末でC-x C-eする)すれば、再起動なしでもインストールできます。 M-x el-get-install で加えたパッケージ名を指定すればよいです。
M-x el-get-updateで更新する
すでにインストールされているパッケージを更新するには、M-x el-get-updateを使います。 URLやインストール方法を覚えていなくてもこのコマンド一発で更新できるのが、el-get.elの魅力です。
M-x el-get-removeで削除する
パッケージを削除するには、M-x el-get-removeです。 このコマンドを使うことはほとんどないです。 というのは、el-get-sourcesに書かなければ、そのパッケージは使われないからです。
レシピの構造
レシピは ~/.emacs.d./el-get/el-get/recipes/ 以下に配置されています。 中身を見てみると、1組のS式が書かれてあります。
たとえば、anything.elのレシピは次のようになっています。
(:name anything :type git :url "git://repo.or.cz/anything-config.git" :load-path ("." "extensions") :features anything)
少し見慣れないリストだと思います。 コロンから始まるのはキーワードといって、シンボルのひとつです。 キーワード、値の繰返しのリストになっています。 このようなリストを属性リスト(plist)と呼びます。 連想リスト同様、キーと値の対応関係を表現します。
それでは、ひとつひとつ見てみます。
- :name :: パッケージ名
- :type :: インストールのタイプ
- :url :: Emacs LispあるいはリポジトリのURL
- :load-path :: load-pathに加えるディレクトリで、バイトコンパイル対象(任意)
- :features :: el-getでrequireするライブラリ(任意)
featuresキーワードにより、el-getでanything.elがロードされるようになっています。 御存知のとおり、anything.elはただの入れ物なので、使うためにはanything-startup.elをロードする必要があります。 しかしanything-startup.elはいろいろなライブラリに依存しているため、早い段階でロードするとエラーになってしまうでしょう。 レシピでは、anything.elのみロードしておくか、何もロードしないでおくのが無難です。
次はEMMSの例です。
(:name emms :type git :url "git://git.sv.gnu.org/emms.git" :info "doc" :load-path ("./lisp") :features emms-setup :build ("make autoloads" "make") :build/darwin `(,(concat "make EMACS=" el-get-emacs " autoloads all")))
これもgitからですが、インストールにはmakeを使う必要があります。
- :info :: infoが格納されているディレクトリ
- :build :: ビルド時に実行するコマンド(複数化)
- :build/darwin :: system-typeの値がdarwinのとき、ビルド時に実行するコマンド
build/darwinはsystem-typeで判断しています。 Linuxの場合はbuild/gnu/linuxとなります。
他にもキーワードはいろいろ定義さているので、興味ある人は <f1> v el-get-sources で見ることができます。
問題点
「使い方」を読んでみて、面倒だと思ったでしょう。
- 手で el-get-sources を操作する必要がある
- レシピがないEmacs Lispの場合、複雑なレシピを自作しなければならない
せっかく複数ファイルに対応しているとはいえ、これでは利便性がなさすぎです。 インストーラといえば、auto-install.elのように、やっぱりURLを入力してコマンド一発でできなければなりません。
解決策
これではあんまりなので、自分なりに解決策を編み出しました。 その解決策がel-get-ext.el(暫定版)です。
実は、el-get-sourcesについては、手書きする必要はありません。 なぜなら、.emacs を走査しておくことで求められるからです。 el-get.elでは、インストールまでは面倒を見ていても、「設定」については .emacs に書く必要があります。 設定する部分でel-get.elを使うという「印」をつけておけば解決します。
レシピについても、だいたい決まったパターンが存在します。 そのため、URLからレシピを自動生成してしまえば9割方うまくいきます。 Emacs Lispが入っているディレクトリが異なる場合などには、レシピに手を加える必要がありますが… レシピを修正した場合は、M-x el-get-updateを実行すれば反映されます。
よって、URLを指定するだけで高確率でel-get.elによる楽々インストールが実現します。
auto-install.el風インターフェース
auto-install.elやinstall-elisp.el愛用者のために、URLやEmacsWikiから直接インストールするインターフェースを作りました。 gistやauto-install-batch等もサポートする予定ですが、間に合いませんでした。
M-x el-get-from-url でURLを入力してインストールする
M-x el-get-from-urlはURLからインストールします。 type(インストールのタイプ。httpやらgitやらtarやら)とname(パッケージ名)を自動判別します。 自動判別はたまに間違うこともあるので、プロンプトが出てきます。
また、レシピがあるならばレシピを使い、なければレシピを自動生成します。 レシピの作成場所は、el-get本体とは別に持っておけば自動生成されたものと区別できます。
たとえば、8日目の anything-with-everything.el をインストールする場合は、
- M-x el-get-from-url https://github.com/yaotti/anything-with-everything.el
- Package name: →anything-with-everything.el
- Type: →git
の順に操作します。
自動生成されたレシピは別ウィンドウに表示されます。 もし不都合があれば、レシピを修正し、「M-x el-get-update パッケージ名」 を実行します。
M-x el-get-from-emacswiki でEmacsWikiからインストールする
EmacsWikiにある場合は、「M-x el-get-from-emacswiki ファイル名」を使うのが簡単です。 auto-install.elがあるならば、ファイル名の補完が使えます。 この場合は単純なので、レシピは自動生成され、100%インストールは成功します。
el-get-sourcesを手書きしないようにする方法
auto-install.el風インターフェースにより、インストールの問題は解決しました。 今度は設定の問題があります。
el-get-sourcesを手書きすると、el-get-sourcesの行と、実際のパッケージの設定部分が離れてしまいます。 これでは、新たにパッケージをインストールしたら、設定を加えるだけでなく、el-get-sourcesの行も更新しないといけません。 そこで、el-get.elがインストールしたパッケージに「印」をつけ、それを元にel-get-sourcesを自動設定しておきます。
その印とは (el-get:use パッケージ名) というS式を行頭に加えることです。 たとえば、 anything-with-everything.elの設定では、こんな感じになります。
(el-get:use anything) (require 'anything) (el-get:use anything-with-everything.el) (require 'anything-with-everything) ;; 以下略
el-get:useの実体は空マクロなので、実行時には何も起こりません。 Emacsの初期化ファイル(.emacsや分割した場合はそれらのファイル)から el-get:use の行をgrepし*1、el-get-sourcesを設定します。
(setq el-get-init-files-pattern "~/emacs/init.d/[0-9]*.el")
(setq el-get-sources (el-get:packages))
(el-get:packages)の返り値のリストには、きちんとanythingとanything-with-everything.elが含まれています。
まとめ
el-get.elは出来たてで、未完成なところもありますが、今後の成長が望めるインストーラです。 2011年は主流になるといいですね。
*1:このへんの実装はまだ手抜き