シェルと Emacsの PATHを共有する

追記 2013/OCT/23

exec-path-from-shellを使う方がおすすめです.

Emacsでの環境変数の設定に exec-path-from-shellを使うようにした - Life is very short




ターミナルエミュレータEmacsを起動する場合は環境変数
引継ぎが行われるので問題ないですが、ランチャ等から GUI版を起動する
ときなどは、.zshrc等で設定した環境変数が反映されないという問題が
あります。


よくある問題なので、対応を書かれている方も大勢います。


.emacsの方に PATHを直接書いてしまうと二重に管理することになる
のでそれは避けたいですよね。

対応

以前書いたのですが、
ワンライナー化 + exec-pathに対応したので、改めて書きます。


.bashrc, .zshrc等の末尾に以下の Perlワンライナーを追加します。

## create emacs env file
perl -wle \
    'do { print qq/(setenv "$_" "$ENV{$_}")/ if exists $ENV{$_} } for @ARGV' \
    PATH > ~/.emacs.d/shellenv.el

これで .zshrcを読み込むたびに最新の PATHが書かれた、S式のファイルが
できます。PATH以外も設定したい場合はコマンドライン引数に追加して下さい.


.emacsに以下を追加します。

;; load environment value
(load-file (expand-file-name "~/.emacs.d/shellenv.el"))
(dolist (path (reverse (split-string (getenv "PATH") ":")))
  (add-to-list 'exec-path path))

add-to-listはすでに要素があれば何もしません。また先頭から追加していく
ので、PATHのリストを reverseしています。"PATH=~/hoge/bin:$PATH"ではなく、
"PATH=$PATH:~/hoge/bin"と書く人は reverseは削除してください。
PATHに変更があった場合は .zshrcに記述, "source ~/.zshrc" or 新たな
シェルを立ち上げる等し、上記のS式を評価し直せばよいです。


exec-pathの内容をリセットしたいという場合は

(setf exec-path nil)

を scratchバッファにでも書いて評価(C-x C-e)して、再設定すれば
よいでしょう。


これでシェルと(ほぼ)同じ PATHの設定が Emacsでもできました。

おわりに

Emacsとシェルで PATHを共有する方法を示しました。