同じ emacs の設定使いたいけど、init.el
が大量のパッケージと依存してて、今の設定を他で再現するのつらい・・・死にたい・・・って時に生きる努力をする。
(defun package-require (feature &optional filename packagename noerror)
"`require' の代わりに使う関数。
PACKAGENAME(or FEATURE) が未インストール時は、`require' する前に
`package-install' によるパッケージインストールを試みる。
NOERROR が non-nil ならば、PACKAGENAME(or FEATURE) が存在しなかったり、
`require' が失敗した時に `error' ではなく、nil を返す。
(`require' の第三引数相当の挙動)"
(unless package--initialized (package-initialize))
(unless package-archive-contents (package-refresh-contents))
(let ((pname (or packagename feature)))
(if (assq pname package-archive-contents)
(let nil
(unless (package-installed-p pname)
(unless package-archive-contents (package-refresh-contents))
;; TODO パッケージ配信鯖が死んでるときの対処
(package-install pname))
(or (require feature filename t)
(if noerror nil
(error "Package `%s' does not provide the feature `%s'"
(symbol-name pname) (symbol-name feature)))))
(if noerror nil
(error "Package `%s' is not available for installation"
(symbol-name feature))))))
↑みたいな関数を用意して、init.el
で↓こんな感じで使う:
;; package-archives の追加するなら、必ず `package-require' の上に書く
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
(add-to-list 'package-archives
'("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)
...
(when (package-require 'tabbar nil nil t)
... ;; tabbar の設定色々
(global-set-key [(control tab)] 'tabbar-forward)
(global-set-key [(control shift iso-lefttab)] 'tabbar-backward) ;; for x window system
)
(when (and (package-require 'anything nil nil t)
(package-require 'anything-obsolete nil nil t)
(package-require 'anything-config nil nil t)
(package-require 'anything-match-plugin nil nil t)
(package-require 'anything-complete nil nil t))
... ;; anything の設定色々
(global-set-key "\M-x" 'anything-M-x)
)
これで、init.el
次回起動時に勝手にインストールして require
してくれる。仮にパッケージ消えててインストールがコケても、`when' のボディー部分が走らないだけになる。
たくさんパッケージインストールしてると・・・
初回起動に時間かかる上に、大量のコンパイルログのバッファがボコボコ出てくる。これが個人的に気になるので、大量にインストールしそうな時は:
$ emacs --batch -l ~/.emacs.d/init.el
と、インストールのロジックだけ走らせてパッケージの再現をする。
TODO パッケージ配信鯖が死んでるときの対処
package-install
しようとして、パッケージ配信してるサーバが死んでいて失敗すると、init.el
の処理が止まってしまうのでどうにかしたい。