Emacsのパッケージ管理をel-getに移行しました

すごい広島#34にエア参加しました。
Emacsのパッケージをgitsubmoduleで管理していたのですが、
あんまりパッケージ管理出来てない事に気づいたので
el-getに移行しました。

やってみたこと

  • el-getのインストール
  • 野良パッケージをel-getに登録
  • パッケージ毎の初期化用elisp作成
  • el-get用にgitignore作成

el-getのインストール

el-getのインストールは、公式の方法だと

1
2
3
4
5
6
7
8
9
10
11
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")

(unless (require 'el-get nil 'noerror)
  (with-current-buffer
      (url-retrieve-synchronously
       "https://raw.github.com/dimitri/el-get/master/el-get-install.el")
    (let (el-get-master-branch)
      (goto-char (point-max))
      (eval-print-last-sexp))))

(el-get 'sync)

というelispをinit.elに書けば良いらしいです。

自分の環境だとうまくいかなかったので、
el-getとhelmだけgitsubmoduleで管理することにしました。

1
2
3
$ cd ~/.emacs.d
$ git submodule add https://github.com/dimitri/el-get.git
$ git submodule add https://github.com/emacs-helm/helm.git

これでひとまずインストールは完了です。
自分の環境だと、el-getの初期化処理は以下の様になりました。

1
2
3
4
5
6
7
8
9
10
11
(add-to-list 'load-path "~/.emacs.d/el-get")

(setq el-get-dir "~/.emacs.d/el-get-packages")
(setq el-get-recipe-path (list "~/.emacs.d/el-get-user-recipes"
                               "~/.emacs.d/el-get/recipes/emacswiki"
                               "~/.emacs.d/el-get/recipes"))
(setq el-get-user-package-directory "~/.emacs.d/el-get-init-files")

(require 'el-get)

(el-get 'sync)

setqしている変数ですが、用途は以下の通りです。

変数名 用途
el-get-dir el-getでパッケージをインストールする際のインストール先
el-get-recipe-path el-get用のパッケージ定義ファイル置き場
el-get-user-package-directory パッケージがrequireされた時に実行される初期化用elisp置き場

あとは、M-x el-get-installでひたすらパッケージをインストールします。

野良パッケージをel-getに登録

M-x el-get-installでパッケージをインストールしていくと、
リポジトリに登録されていない野良パッケージの存在に気付かされます。

el-getに野良パッケージを登録するには、
el-get-recipe-path
に設定したディレクトリ配下にレシピファイルを作成します。

作成例ですが、yard-mode.el用のレシピファイルと、

yard-mode.rcp
1
2
3
4
5
(:name yard-mode
       :type git
       :website "https://github.com/pd/yard-mode.el"
       :description "Rudimentary support for fontifying YARD tags and directives in ruby comments."
       :url "https://github.com/pd/yard-mode.el.git")

auto-save-buffers用のレシピファイルです。

auto-save-buffers.rcp
1
2
3
4
(:name auto-save-buffers
       :type http
       :description "auto-save-buffers"
       :url "http://homepage3.nifty.com/oatu/emacs/archives/auto-save-buffers.el")

:typeで、gitからcloneするか、httpでファイルをそのまま取ってくるかなどの取得方法を指定出来るようです。
:urlはリポジトリやファイルのURLを指定します。

上記ファイルを作成すれば、M-x el-get-installでインストール出来るパッケージの候補として選べるようになります。

パッケージ毎の初期化用elisp作成

これまで私はinit.elにパッケージ毎の初期化処理を書いていたのですが、
el-getでは、el-get-user-package-directory内に
init-パッケージ名.elという初期化用elispを用意しておくことで
パッケージがrequireされたタイミングで上記のelispを実行してくれるようです。

最終的に、~/.emacs.dのディレクトリ構成は以下の様になりました。

~/.emacs.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
~/.emacs.d
├── el-get
├── el-get-packages
│   └── (省略)
├── el-get-init-files
│   ├── init-auto-save-buffers.el
│   ├── init-jaspace.el
│   ├── init-magit.el
│   ├── init-php-mode.el
│   ├── init-popwin.el
│   ├── init-rcodetools.el
│   ├── init-ruby-mode-github.el
│   └── init-undo-tree.el
├── el-get-user-recipes
│   ├── auto-save-buffers.rcp
│   ├── cucumber.rcp
│   ├── findr.rcp
│   ├── ruby-mode-github.rcp
│   └── yard-mode.rcp
└── init.el

init.elが肥大化していたので、require時に実行したい処理は
init-パッケージ名.elに書くようにすれば、
だいぶスッキリするのではないかと思ってます。(まだやってない)

el-get用にgitignore作成

el-getを導入後は、elファイルをコンパイルしたelcファイルや、
M-x el-get-installでインストールしたファイルが
git status実行時にUntracked files:として表示されるようになりました。

これらを非表示とするため、以下の.gitignoreファイルを作成しました。

.gitignore
1
2
3
4
*.elc
.loaddefs.el
el-get-packages/
!.status.el

.status.elは、M-x el-get-installを実行するとel-get-packages/内に作成されます。
どのパッケージをインストールしたのか、このファイル内に持ってるらしいので
gitで管理する場合は、このファイルもリポジトリに入れた方が良い様です。

まとめ

el-getに移行したことで、Emacs起動時に全てのパッケージが勝手にインストールされるようになりました。
これで、各PC毎にgit submodules updateしたりせずに済みます。

野良パッケージもちゃんとレシピファイル準備すれば
el-getの恩恵にあずかることができます。

autoloadとかの仕組みをちゃんと理解出来てないので、
init-パッケージ名.el書きながら慣れていきたいところです。

作成した~/.emacs.d配下のファイル類はgithubで公開してます。
https://github.com/ogatomo/emacs/tree/el-get

Comments