Mac OSでexec-path-from-shellをEmacsで使いつつ、ターミナルでfishを使う

fishはPOSIX互換シェルのため、rbenv などがうまく動かなかったり、Bashスクリプトによる初期化がうまく引き継げないなどの問題がおきることがあります。 環境によりますが、PATH他の環境をfishに移行するのも面倒なので、とりあえずArch Linuxの方法を採用しておけば楽でよさそうです。

fish - ArchWiki

一方Mac OS環境ではEmacsGUI起動するにあたって、exec-path-from-shell という素晴らしいパッケージを利用していることがあります。

github.com

そのため、SHELLはBashだけどfishが実行されちゃって、以下のようなEmacs起動時に以下のようなエラーをしてしまうことがあります。

Expected printf output from shell, but got: %S" "Agent pid xxxx\n

とりあえず、Emacsの初期化処理としては環境変数を引き継ぎたいだけで、シェル実行をしたいわけではないので以下のような適当な方法で回避します。

;; in .emacs.d/init.el
(setenv "EMACS" "yes")
(when (memq window-system '(mac ns))
  (exec-path-from-shell-initialize))

.bash_profile他が実行される前に、Emacs環境でEMACS="yes"という環境変数をセットしておいて、.bash_profile側でその場合にexec fishしないようにします。

[[ $EMACS != "yes" ]] && exec fish

これでターミナルはfishになるけど、Emacsはfishを呼ばずにエラー回避できました。