DT日記

家を離れた自宅警備員の日記

Emacsのeshellにzshの環境変数を取り込む

全然使ひかたを覚えられない Emacs を飼ひ馴らさうと、最近また時間をとってカスタマイズしようとしてます。で、餅は餅屋、Emacs を使ふなら eshell だよってことらしいので、これも飼ひ馴らさうかと。

基本的には M-x eshell とやれば最低限動くのだけれど、僕の Ubuntu の環境では ruby/home/megurine/.rbenv/shims/ruby にあったり、Mercurial (hg) が /home/megurine/.pythonz/pythons/CPython-2.7.3/bin/hg にあったりするので、これらは上手く動かないんですね。いやあ、困った困った。

もちろんこれらは、メインで使ってる zsh ではちゃんと設定してあるので、eshell でも同じ設定をしなほすのは二度手間ですね。ってことで、zsh から環境変数を取り込んでみます。

(let ((zshpath (shell-command-to-string "/usr/bin/zsh -c 'printenv PATH'")))
  (let ((pathlst (split-string zshpath ":")))
    (setq exec-path pathlst))
  (setq eshell-path-env zshpath)
  (setenv "PATH" zshpath)))

事前に $HOME/.zshenv でちゃんと $PATH を設定してあることとします。.zshrc じゃだめですよ。ログインシェルではなくて、インタプリタとして実行するときに読まれません。$PATH を設定すべきは .zshrc です。

zsh の設定ファイルが読まれるタイミングなんかは、漢のzsh (1) 最強のシェル、それは「zsh」を参照のこと。

shell-command-to-string はシェルコマンドを実行して文字列にして返す函数です。zsh -c '...' は、引数に渡したスクリプトワンライナーで実行します。printenv HOGE環境変数 HOGE の内容を出力します。

といふわけで、(shell-command-to-string "/usr/bin/zsh -c 'printenv PATH'")zsh の PATH を頂いてこられるわけです。やりましたね!

let特殊形式 (スペシャルフォーム) で、束縛ですね。zshpath, pathlst といふ名前に値を束縛します。(setenv "HOGE" value) といふ函数Emacs の PATH 環境変数を書き換へる副作用を持ち、書き換へられた HOGE の値を返します。

ぐぐる先生で検索してみると (setq eshell-path-env (setenv "HOGE" value)) みたいに書いてるコードが見つかったりするけれど、値を返すからってこの書き方はきもいです…ってことで setqsetenv は分けて書きます。

なんで chsh でデフォルトのログインシェルを zsh に設定してるのに Emacs は読んでくれないのかなー、と考へてみたりしたんですけど、きっと Gnomezsh環境変数を読んでくれなくて、EmacsGnome 上のランチャから起動されてるからなんですね。

よくわかんないので、その辺りは後々の宿題といふことでひとつ。