読者です 読者をやめる 読者になる 読者になる

$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

elispをpackageとel-get両方で管理する

emacs tech

関西Emacsに行って、elispをちゃんとpackage管理みたいなので管理しないとなあという機運が高まったので、管理の方法を見なおしてみました。

これまでの管理方法としては、

  • 基本的にはelispcurlで落とし、git管理
  • 最近はel-getを使ってみていた

という感じにしていました。

しかし、el-getは結構はまるところがあったり、elispをあまり使えない身としてはなかなか厳しいところがありました。そこでpackage.elにしてしまおうかなと思っていました。

ただし、package.elにも一つだけ問題があって、MELPA等に登録しないとpackage管理できないということです。そのため、個人でちょっと書いてgithubにおいてあるelispをpackage管理できません。

そこで以下の様な方針で管理することにしました。

  • 基本的にはpackage.elを使う
  • package.elで扱えないものや、たまに自分で作ったものとかはel-getで入れる

package.elとel-getはそれぞれ共存も出来るので、とりあえずこの方法を試して見ることにしました。

package.elとパッケージ管理

初期設定

package.el(ELPA)はEmacs 24から標準搭載されたelisp package管理システムです。利用するarchiveを増やすこともできるので以下のように設定してMELPA等を追加しておき、利用します。

(require 'package)

;; package.elでelispを入れるdirectoryの設定
(setq package-user-dir "~/.emacs.d/elisp/elpa/")

;; MELPAを追加
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)

(package-initialize)

あとはpackage-list-packagesやpackage-installなどを利用してelispをいれます。簡単ですね。

package.elでの管理elispをリストアップしておく

僕は入れたelispを全部gitで管理してしまっていますが、何かの拍子でおかしくなった時に、packageで入れたelispを全部消して、一気にセットアップしたい時もあります。
そういう時のために以下のように入れたpackageを手動でリストアップしておくという事をしています。

;; Packages to install from MELPA
(defvar my/packages
  '(git-gutter
    open-github)
  "A list of packages to install from MELPA at launch.")

さらに以下のように設定しておくことで、リストアップされているのにインストールされていないpackageは起動時に自動でインストールさせることもできます。

;; Install Melpa packages
(dolist (package my/packages)
  (when (or (not (package-installed-p package)))
    (package-install package)))

これで何かおかしくなった時にはelpaディレクトリに入っているやつを一旦消して、起動するだけでとりあえず全部インストールし直しとかも出来るようになりました。

el-getとパッケージ管理

初期設定

el-getの場合、インストールする必要があります。その方法についてはel-getを使ってみる(インストール編) - $shibayu36->blog;にまとめました。

さらに以下のように設定しておきます。

(setq el-get-dir "~/.emacs.d/elisp/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")
    (goto-char (point-max))
    (eval-print-last-sexp)))

(el-get 'sync)

recipeの追加

自分が適当に作ってgithubに置いたものをel-getで管理するには以下のようにrecipeを追加する必要があります。el-getではel-get-sourcesのリストを作っておくとel-get-installコマンドでインストールできるようになります。

;;; define el-get repository
(setq el-get-sources
      '(
        (:name open-github-from-here
               :type github
               :description "open github from here"
               :pkgname "shibayu36/emacs-open-github-from-here"
               :branch "development")
        (:name anything-git-files
               :type github
               :pkgname "tarao/anything-git-files-el")
        ))

上のような設定により、open-github-from-hereはgithubのshibayu36/emacs-open-github-from-hereのdevelopmentブランチから、anything-git-filesはgithubのtarao/anything-git-files-elのmasterブランチから取得してくれるようになります。手軽に自分の上げたelispをpackage管理したい場合は便利ですね。

el-getで管理しているelispをリストアップしておく

el-getは時々おかしくなって.loaddefs.elがうまく読み込めなくなったりします。その時のため、もう一回installし直しみたいなのを簡単に出来るようにしておきたいところです。

こちらもpackage.el同様リストアップしておいて、起動時に入っていないpackageを全インストールすることができます。

;; Packages to install from el-get
(defvar my/el-get-packages
  '(
    open-github-from-here
    anything-git-files
    )
  "A list of packages to install from el-get at launch.")

(el-get 'sync my/el-get-packages)

今のところmy/el-get-packagesにこれまでインストールしたファイルを列挙しておいて、おかしくなった時は.loaddefs.elとかを消したり、el-getディレクトリ以下を全部消して入れ直したりする運用でなんとかなったりしています。

まとめ

今回はpackage.elとel-getの両方を使った管理について考えてみました。現状だとややこしいですが、以上のようにして管理しています。

今回のようにpackage管理の仕組みを二つ使う根本的な理由としてはpackage.elがMELPAなどに登録しないと管理に含めることが出来ないためなので、簡単にlocalでレシピを書いて入れられるようになると嬉しいですね。

また、今はpackage.elとel-getでいれたものもgitで管理していますが、きちんとpackage管理し、初回起動したら全部セットアップされるようにしておけば、基本的にこの辺りのファイルはgitで管理しなくても良いかもしれませんね。