[emacs][zsh][vim]CarbonEmacsでzshとかvimをまともに使う方法 

需要があるのか謎なのですが,Carbon Emacs内部でzshとかvimをまともに使う方法について書いておきます。この手法は別にCarbonEmacsじゃなくてEmacsとかでも使えるまする(Terminalで確認済み)。

とりあえず始めにEmacsで使えるshellの種類について簡単に触れておきます。 Emacsで使えるshellは大別してshell派とterm派の二派閥があります。

  • shell派はEmacs側が殆ど実装しており?,挙動が普通のshellっぽくないのが特徴です。zshはshell派でも普通に使えるんですけどこの中でvimとか実行するとおぞましい事になります。
  • term派はEmacs側で実装というよりは普段使っているshellをEmacsで使うという感じのshellです。vimを実行する場合当然こっちを選択します。当然今回もこっちに関する説明となります。

ちなみに、termにはterm,ansi-term,termの拡張版のmulti-termなど色々と種類がありますが挙動は殆ど同じっぽいです。

Emacsでterm派のshellを使うにおいて重要になる事はzsh環境変数であるTERM,TERMINFO,TERMCAPを如何にうまく取り扱うかにかかっています。

結論からいうと,TERMを変えておけば,TERMINFO,TERMCAPについてはあまり考える必要はないです。

Emacsでterm関連のコマンドを実行するとバックスペースが効かないとかEnterが効かないという現象が起こりますが、これはzsh環境変数、特にTERMINFO,TERMCAPがうまく設定されていない事が原因のようです。TERMINFOはmacだと/sw/share/terminfo/ファルダから参照されます(たぶん)。参照されるTERMINFOはzshの変数として設定しておかなくとも,TERMの種類をshellの環境変数として設定しておけば自動的に参照されます(設定してなくても勝手に設定されますが)。例えば、zshでTERM=xtermと設定されている場合には/sw/share/terminfo/x/xtermのTERMINFO情報が自動的に参照されるっぽいです。


TERMの種類は環境変数に登録されておリ,echo $TERMで確認が出きます。ちなみに,当方の環境だとTerminalだと$TERM=xterm-color, iTermは$TERM=xtermとなっていました。

さて、これがEmacsで実行されるtermの環境だとどうなるのか?というわけですが、当方の環境だとTERM=eterm-colorとでました。というわけでこのTERM=eterm-colorをTERM=xterm-colorと変更すれば,普通のTerminalと同じTERMINFO情報が引用されて端末挙動もTerminalと同じ感じになります。

というわけで.zshrcに以下のような設定を追加します。

 [[ $TERM = "eterm-color" ]] && TERM=xterm-color

この設定だけでも,EmacsからzshをTerminal.appと同じような感じで操作出来るようになると思います。


ちなみに,Terminal.appとEmacs内部のTerminalの環境変数についても触れておきますが、これは当然ながら全然違います。Emacs内部実行Terminalの環境変数にはTerminal.appにはない項目がいくらかあります。例えば以下のような項目があります。

EMACSDATA=/Applications/Emacs.app/Contents/Resources/etc
EMACSPATH=/Applications/Emacs.app/Contents/MacOS/libexec:/Applications/Emacs.app/Contents/MacOS/bin
TERMCAP=eterm-color:li#43:co#160:cl=\E[H\E[J:cd=\E[J:bs:am:xn:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:ce=\E[K:ho=\E[H:pt:al=\E[L:dl=\E[M:DL=\E[%dM:AL=\E[%dL:cs=\E[%i%d;%dr:sf=^J:dc=\E[P:DC=\E[%dP:IC=\E[%d@:im=\E[4h:ei=\E[4l:mi::so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:md=\E[1m:mr=\E[7m:me=\E[m:UP=\E[%dA:DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:kl=\EOD:kd=\EOB:kr=\EOC:ku=\EOA:kN=\E[6~:kP=\E[5~:@7=\E[4~:kh=\E[1~:mk=\E[8m:cb=\E[1K:op=\E[39;49m:Co#8:pa#64:AB=\E[4%dm:AF=\E[3%dm:cr=^M:bl=^G:do=^J:le=^H:ta=^I:se=\E[27m:ue=\E24m:kb=^?:kD=^[[3~:sc=\E7:rc=\E8:r1=\Ec:
__CF_USER_TEXT_ENCODING=0x1F5:1:14
TERMINFO=/Applications/Emacs.app/Contents/Resources/etc/

ちなみに、環境変数であるTERMCAP,TERMINFOの設定についてはTERM=xterm-colorと設定した場合には/sw/share/terminfo/x/xterm-colorの情報が優先されるのでスルーされます。

次にterm内でvimを使う方法ですが、これはshellコマンドを実行した場合とは全く挙動が違い普通に使えます。注意としてはEscがEmacsのコマンドと競合したりBSが使えない?という点くらいかと思います。まあ、そこら辺はキーの割り当てがされていない部分に設定しとけばいいんだと思います。例えば以下のような感じで.vimrcに設定を追加しておけばいいかと。

imap <C-B> <Left><Del>
nmap <C-B> <Left><Del>
cmap <C-B> <Left><Del>
imap <C-f> <Esc>
nmap <C-f> <Esc>

まあこんな感じですね。これでelscreen + zsh + screen(zsh内) + vim的な事が出来るようになるので面白いんじゃないかと思いまする。