LoginSignup
3
4

More than 5 years have passed since last update.

NTEmacs + cygwin or msys2 で exec-path-from-shell

Last updated at Posted at 2015-09-16

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 に書き直しが必要。

init.el
(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"))))
3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4