#exec-path-from-shell#
exec-path-from-shell (https://github.com/purcell/exec-path-from-shell) は、GUI での起動時に、指定した環境変数をシェルから引き継いでくれます。楽チンです。
詳細は以下のリンクを参照
http://qiita.com/catatsuy/items/3dda714f4c60c435bb25
http://syohex.hatenablog.com/entry/20130718/1374154709
ただし、windows はサポートしてないし、そのままでは動きません。ですが、NTEmacs と cygwin/msys2 を楽して連携したいので、それを何とかしてみます。
以下の環境で検証
- Windows 7、msys2、NTEmacs 24.5.1、exec-path-from-shell melpa の最新版
#パスの形式の問題#
cygwin/msys2 のシェルで扱うパスは unix 形式であり、cygwin or msys2 の環境変数もそうなっています。一方、NTEmacs は WIN32 アプリケーションのため unix 形式のパスは読み込めません。exec-path-from-shell がうまく動かない問題はこれが原因です。よって、 unix 形式のパス → windows 形式のパスのように変換できればいいわけです。
#cygpath#
cygwin/msys2 には unix 形式のパス と windows 形式のパスを相互に変換する cygpath コマンドがあります(詳細は以下のリンク参照)。
http://takuya-1st.hatenablog.jp/entry/20110910/1315644196
このリンク先には紹介されていませんが、-p
オプションを使うと、環境変数で使われるパスのリストを一気に変換してくれます。
$ cygpath -amp "/bin:/usr/bin" # unix 形式のパスリスト
D:/msys64/usr/bin;D:/msys64/usr/bin # windows 形式のパスリスト
$ cygpath -aup "D:/msys64/usr/bin;D:/msys64/usr/bin" # windows 形式のパスリスト
/usr/bin:/usr/bin # unix 形式のパスリスト
よって cygpath を NTemacs から実行すればうまくいきそうです。
#NTEmacs の設定#
以上を踏まえて、init.el あたりに以下を設定すればいいようです。
注1) bash と cygpath のフルパスは各自の環境にあわせて変更してください
注2) cygwin でもおそらく動きますが、msys2 の設定部分はコメントアウトなりしてください
注3) NTEmacs 24.3 以前を使用している場合 新 advice は動作しないので 旧 advice に書き直しが必要。
(setq shell-command-switch "-c")
;; シェルからの起動では exec-path-from-shell を実行しない
(let ((shell-level (getenv "SHLVL")))
(when (or (not shell-level) (string= "0" shell-level))
(when (eq system-type 'windows-nt)
;; bash のフルパスを指定
(setq shell-file-name "d:/msys64/usr/bin/bash")
(defvar explicit-shell-file-name)
(setq explicit-shell-file-name shell-file-name)
(setenv "SHELL" shell-file-name)
;; msys2 のみの設定 mingw64 とパスを共有
(setenv "MSYSTEM" "MINGW64")
;; 環境変数 PATH のときのみパスの変換を実行
(defun ad-exec-path-from-shell-setenv (orig-fun &rest args)
(when (string= (car args) "PATH")
(setf (nth 1 args)
(with-temp-buffer
(call-process "d:/msys64/usr/bin/cygpath" nil '(t nil) nil "-amp" (nth 1 args))
(unless (bobp)
(goto-char (point-min))
(buffer-substring-no-properties (point) (line-end-position))))))
(apply orig-fun args))
(advice-add 'exec-path-from-shell-setenv :around 'ad-exec-path-from-shell-setenv))
;; 引き継ぎたい環境変数を列挙
(exec-path-from-shell-copy-envs '("PATH" "MANPATH" "PKG_CONFIG_PATH"))))