Cygwin内から外のgvimを使う

Cygwinでgitを使うようになってから一週間ほど経ったんだけど、ひとつだけ不満がある。
それはコミットメッセージを書くときのエディタなんだけど、これを普段使い慣れているgvimにしたかった。

gvimにできない理由

gitで使うエディタは環境変数GIT_EDITORに設定すればいいわけだけど、Cygwinの中の世界と外の世界ではファイルパスが異なる*1ので上手くいかない。


もうひとつ、Cygwin上からプロセスを起動すると当然ながらCygwin上の環境変数を継承するので、$HOMEなどをはじめ色々とまずそうな感じもある。

gvimにしたい理由

コンソール上で動くvimに比べてgvimの方が色々と勝手がよいので可能ならgvimが使いたい。
個人的に感じてるメリットとしてはこんなところか。

  • IMEの制御ができる
  • クリップボードが使える
  • タブが分かりやすい
  • フォントが変えられる
  • 端末に依存せずにカラーが使える
  • 端末やscreenのキーバインド干渉に悩まされない

他にも個人的にはあまり関係ないけど、

とかあるかもしれない。
まぁ全般的に画面周りはgvimのほうが細かく設定できたりしてよい。


この中で最重要なのが一番最初のやつで、インサートモードを抜けたらIMEをオフにするとか、そういうのが操作性を大きく左右する。

環境変数と引数を加工してからgvimを起動するスクリプト

問題は主に環境変数とパスなので、適当に加工してからgvimを起動するスクリプトを間に挟むことで解決を試みてみた。
具体的には$HOMEを削除して、渡された引数のうちオプションじゃなさそうなのをcygpathでWindowsパスに変換してから起動するという感じ。

#!/bin/bash
WINDOWS_GVIM=$(cygpath -ua "/c/apps/vim/gvim.exe")
if [[ ! -x "$WINDOWS_GVIM" ]]; then
  WINDOWS_GVIM=$(cygpath -ua "/d/apps/vim/gvim.exe")
fi
if [[ ! -x "$WINDOWS_GVIM" ]]; then
  WINDOWS_GVIM=$(cygpath -ua "$USERPROFILE/apps/vim/gvim.exe")
fi

# なんか空白が入ったパスだとrunがうまくいかない
WINDOWS_GVIM=$(cygpath -da "$WINDOWS_GVIM")

unset HOME SHELL

GVIM_OPTIONS="--remote-tab-silent"
if [[ $# -ne 0 ]]; then
  for x in "$@"
  do
    if [[ ${x:0:1} == "-" ]]; then
      GVIM_OPTIONS=""
      break
    fi
  done
fi

if [ $# -eq 0 ]; then
  run "$WINDOWS_GVIM"
else
  args=()
  for arg in "$@"
  do
    # 実在するファイルか"-", "+"で始まらなければcygpathに通す
    if [ -e "$arg" -o \( ${arg:0:1} != "-" -a ${arg:0:1} != "+" \) ]; then
      args=("${args[@]}" "$(cygpath -wa "$arg")")
    else
      args=("${args[@]}" "$arg")
    fi
  done

  run "$WINDOWS_GVIM" $GVIM_OPTIONS "${args[@]}"
fi

WINDOWS_GVIMの部分は適当に修正してやってください。


これを$HOME/bin/wgvimとか適当に置いて、GIT_EDITORに設定した。
環境変数についてはもう少しWindows環境に近づけた方がいいのかもしれないけど、面倒くさかったのでとりあえずHOMEだけ消した。PATH、TEMP、TMPあたりも加工した方がいいのかもしれない。


引数もgit限定なら$(cygpath -wa "$1")とかでいい気もしたけど、ちょっとだけ頑張って複数ファイルとかオプションつけても大丈夫にしてみた。
ただ、判定がざっくりすぎるのであまり汎用的には使えないかも。

PATHの優先順位がおかしい?

ところで最初は上記のスクリプトを$HOME/bin/gvimとして置いたんだけど、gvimと叩くと何故かスクリプトではなくC:\apps\vim\gvim.exeが直接起動するという現象が。
PATHを見る限りだと$HOME/binが最初に来てるのでそっちが優先されると思うんだけど……。
パスを指定して実行すればもちろんスクリプトの方を起動できるんだけど、そんなの面倒くさいし仕方がないのでwgvimという名前にした。

*1:Cygwin外のパスは/cygdrive/c/Documents and Settingsなどになる