MacVim を起動するときコマンドラインから、
$ open -a MacVim
と、やりますよね(おそらく)。
このままエイリアスでもいいのですが、もう少し勝手を良くしようというのが今回の趣旨です。
gvim 関数を作成
エイリアスには限界があるので、関数化しましょう。環境は bash
とします。
gvim(){if[$# -eq 0 ]; thenopen -a MacVim
elseopen -a MacVim "$@"fi return 0
}
素直に、引数がなければ起動するだけ、あれば引数を渡して終了。なのですが、MacVim
は、存在しないファイルが渡された時、CUI のように新規作成してはくれません。
$ gvim myfile
The file /Users/tester/myfile does not exist.
exit 1
新規作成の機能を実装しましょう。
複数ファイルに対応する前に、とりあえず引数は1つしか取れないとしておきます。
1: gvim(){
2: if[$# -eq 0 ]; then3: open -a MacVim
4: elif[$# -eq 1 ]; then5: if[ ! -f "$1"]; then6: touch "$1"||return 1
7: fi8: open -a MacVim "$1"
9: else10: echo"$@: invalid arguments"
11: return 1
10: fi11: return 0
12: }
5-7行目です。ファイルがない場合、作成しています。Permission denied
などで作成できなかった場合のための処理も加えました。
これで一応は機能します。しかし、ちょっとしたバグが潜んでいます。それは、gvim に myfile2
という新規ファイルを渡したいとき、間違って myfile1
の新規ファイル名で渡したとします。:q
などで Vim を終了した時、カレントディレクトリには myfile1
が作られたままになってしまうのです。
$ ls
Desktop/ Documents/
$ gvim myfile1 # ミス。myfile2だった。vim を終了させる
$ ls
Desktop/ Documents/ myfile1 # myfile1 は存在していてほしくない
この対処をしましょう。
ファイルサイズが0ならば、終了後に消す
作成したファイルに何も書き込まれず(ファイルサイズが0)終了したのなら、そのファイルはミスだったと判断していいものとしました。
1: gvim(){
2: if[$# -eq 0 ]; then3: open -a MacVim
4: elif[$# -eq 1 ]; then5: if[ ! -f "$1"]; then6: touch "$1"||return 1
7: fi8: touch -t $( date -v+1S +'%Y%m%d%H%M') ~/.compare
9: open -a MacVim "$1"&&{
10: sleep 0.2
11: if[ ~/.compare -ot "$1"]; then12: [ ! -s "$1"]&& rm "$1"
13: fi14: rm ~/.compare
15: }
16: else17: echo"$@: invalid arguments"
18: return 1
19: fi20: return 0
21: }
これで実装完了です。以下解説。
少し特殊な動きをしているのが、8行目からです。touch
コマンドで時刻指定をし、最新のファイル ~/.compare
を作成します。そして、$1
と比較(11行目)をし、~/.compare
のほうが古かったら、なおかつファイルサイズが0だったら削除するというようにしました。
なぜ、こんな回りくどい方法かというと、単純にファイルサイズ0にすると、もともとあったファイルサイズ0ファイルがこの gvim
関数で開いただけで、削除されるという恐ろしいことになるからです。
それにしても周りくどいような気がします。もっとエレガントに書けるなら教えてください。
あとは、エイリアスをはるなり、以下のように
$ gvim myfile
実行するなりで使用できます。