Hatena::ブログ(Diary)

hnwの日記 このページをアンテナに追加 RSSフィード

[プロフィール]
 | 

2014年1月13日(月) Emacs起動時に自分好みのelispを自動的にインストールする このエントリーを含むブックマーク このエントリーのブックマークコメント

(2015/04/27追記)Emacs24.4付属のpackage.elでは「野良elispをpackage-installする」が動かなくなっていました。中の人が想定してない使い方で頑張るより、必要なものはMELPAにぶっこんでいくスタイルの方が正しい気がしますね…。


自宅と会社など、複数環境でEmacsを使っていると全環境を同じ状態に保つのは意外と手間がかかります。GitHubなどを利用してinit.elを共有すればそれなりに同じ状態にできますが、完全に同じ状態にしようと思うとelispインストール状態も共有する必要があり、これが案外面倒だったりします*1


そこで、init.el内に自分が必要なパッケージ名を列挙しておいて、起動時にインストールされていないパッケージがあったらpackage.elでインストールする仕組みを導入しました。さらに、URLで指定されたelispをpackage.el管理する仕組みを組み合わせました。これが予想以上に快適だったので紹介します。これは、次の2つの記事を混ぜ合わせたような内容になっています。



僕と同じことをするには、init.elに下記の内容を貼り付ければ準備完了です。GNU ELPA・Marmalade・MELPAで提供されているパッケージの場合はmy/favorite-packagesのパッケージ名を、それ以外の場合はmy/favorite-package-urlsのURLを、それぞれお好みに合わせて書き換えてください。


;; package.el
;; http://qiita.com/catatsuy/items/5f1cd86e2522fd3384a0
;; http://www.robario.com/2013/08/07

(defvar my/favorite-packages
  '(
    php-mode
    haskell-mode
    csharp-mode
    yaml-mode
    open-junk-file
    gtags
    anything
    )
  "起動時に自動的にインストールされるパッケージのリスト")

(defvar my/favorite-package-urls
  '(
    ;; 1ファイルのelispしか管理できません
    ;; パッケージ名はファイル名の.elより前の部分になります
    "http://namazu.org/~tsuchiya/elisp/dabbrev-ja.el"
    "http://homepage3.nifty.com/oatu/emacs/archives/auto-save-buffers.el"
    )
  "起動時に自動的にインストールされるelispのURLのリスト")

;; ネットワーク経由で取得したelispをpackage.el管理する
(defun package-install-from-url (url)
  "URLを指定してパッケージをインストールする"
  (interactive "sURL: ")
  (let ((file (and (string-match "\\([a-z0-9-]+\\)\\.el" url) (match-string-no-properties 1 url))))
    (with-current-buffer (url-retrieve-synchronously url)
      (goto-char (point-min))
      (delete-region (point-min) (search-forward "\n\n"))
      (goto-char (point-min))
      (setq info (cond ((condition-case nil (package-buffer-info) (error nil)))
                       ((re-search-forward "[$]Id: .+,v \\([0-9.]+\\) .*[$]" nil t)
                        (vector file nil (concat "[my:package-install-from-url]") (match-string-no-properties 1) ""))
                       (t (vector file nil (concat file "[my:package-install-from-url]") (format-time-string "%Y%m%d") ""))))
      (package-install-from-buffer info 'single)
      (kill-buffer)
      )))

(defun package-url-installed-p (url)
  "指定されたURLに対応するパッケージがインストールされているか調べる"
  (interactive "sURL: ")
  (let ((pkg-name (and (string-match "\\([a-z0-9-]+\\)\\.el" url) (match-string-no-properties 1 url))))
    (package-installed-p (intern pkg-name))))

(eval-when-compile
  (require 'cl))

(when (require 'package nil t)
  (add-to-list 'package-archives
               '("melpa" . "http://melpa.milkbox.net/packages/") t)
  (add-to-list 'package-archives
               '("marmalade" . "http://marmalade-repo.org/packages/") t)
  (package-initialize)
  (let ((pkgs (loop for pkg in my/favorite-packages
                    unless (package-installed-p pkg)
                    collect pkg)))
    (when pkgs
      ;; check for new packages (package versions)
      (message "%s" "Get latest versions of all packages...")
      (package-refresh-contents)
      (message "%s" " done.")
      (dolist (pkg pkgs)
        (package-install pkg))))
  (let ((urls (loop for url in my/favorite-package-urls
                    unless (package-url-installed-p url)
                    collect url)))
    (dolist (url urls)
      (package-install-from-url url))))

ちなみに、僕は気になるパッケージがあったらpackage.el経由で普通にインストールして、気に入ったらinit.elにパッケージ名を書き写すような使い方をしています。


Emacs24からpackage.elが標準装備になったので、こういうことがやりやすくなりました。Emacs23以前を使っている場合、package.elだけは別の方法でインストールする必要があります。すこし悲しいですね。

*1:他人の書いたelispGitHub管理しちゃうよ派を除く

yasuykyasuyk 2014/01/14 12:06 自分も似たような方法で管理していましたが、パッケージをチェックするのに時間がかかるようになってきました。
最近、Caskでパッケージ管理するように変更しました。CaskはRubyでいうところのBundlerにあたります。
パッケージをチェックすることがなくなったので起動が早くなりました。

http://cask.github.io/

hnwhnw 2014/01/15 01:19 yasuykさん:

上記の方法では都度パッケージのチェックなどは行わないので、起動は十分速いように思います。そのかわり、パッケージの最新版がある場合は手動で追従する必要があります。僕が入れたいパッケージは比較的古めのものが多いので、多少ゆるい管理でもいいと思っていますが、厳密にやる場合は他の方法の方がいいのかもしれませんね。

yasuykyasuyk 2014/01/15 04:12 なるほど!

トラックバック - http://d.hatena.ne.jp/hnw/20140113
 | 
ページビュー
2239086