理系学生日記

おまえはいつまで学生気分なのか

exec-path-from-shell による Emacs とシェルの変数共有

exec-path-from-shell、思った以上に便利だった。package.el 使ってたら、M-x package-install exec-path-from-shell でインストールできる。
これ使うことで、シェルに設定される環境変数が、Emacs 側でも参照できるようになる。

MacOS で GUI の Emacs 使ってると、シェルを介して Emacs を起動しないので、PATH だったり MANPATH だったりといった環境変数はシェルで設定しているものとは基本的に全く別のものになる。このせいで悩み、疲れ、黒魔術やバッドノウハウに手を出し、最終的にダークサイドに堕ちるエンジニアが大量にいる、みたいな状態だった。
それを exec-path-from-shell は解決してくれる。exec-path-from-shell が使っている方法がバッドノウハウなのではないか、というのは宗教戦争になると思うので判断つきませんということにしておきます。

混乱しがちなところの詳細は

にまとめられていたりするのだけれど、

  • Emacs 内で使用する exec-path
  • .zshrc (or .bashrc)

とかで混乱しがちなところは、この exec-path-from-shell によって抽象化されることになる*1


使い方についてはまぁ書いてある通りで、

(when (memq window-system '(mac ns))
  (exec-path-from-shell-initialize))

としておけば、とりあえず MANPATH と PATH 環境変数が共有される。共有の方向としては、シェル→Emacs。Emacs で設定した環境変数をシェルにバックポートする、という機能はない。

共有する環境変数を増やしたいときは、exec-path-from-shell-variables に追加してやれば良い。

(add-to-list 'exec-path-from-shell-variables "NODE_PATH")


この共有の仕組みだけど、elisp から $SHELL をインタラクティブに起動して、都度シェルに環境変数の値を問い合わせるという形になってる。興味ある人は、exec-path-from-shell-getenvs あたりのソースを追うと分かるかんじ。

*1:exec-path-from-shell-setenv の実装を見れば分かるように、PATH を共有する場合は、exec-path とともに eshell-path-env も統一される