ZZの話 をするたび、多くの人が「なぜ自分はZZを使わないか」をひどく熱心に語ってくれる。まあ人にはそれぞれ事情があるのだろうから、別に使わないでいるのは自由だと思うし、なんならEmacsを使っていただければよいのではないかと思うのだが……。最新のエピソードは「右手でシフトキーを押せないので大文字のZが押しづらい」という話だった。ちなみに自分は左手をちょっとずらして、左手の小指でシフト、薬指でZを押している。viを使うにあたってホームポジションがずれることに抵抗はない。さもないとhjklでカーソル移動なんてできっこないのだ。
さてまつもとりーさんのブログの追記や前後のTweetを見て、自分なりに「なぜ人はZZを使わないのか」を考えてみた。その結果ひとつの仮説が浮かび上がってきた。それはZZがviを終了させるにあたって、他のエディタにはない特徴があるということだ。
ふつーのエディタでファイルを開き、編集してみよう。そして「終了」させてみよう。たとえばEmacsだ。Emacsを終了させるには C-x C-c だが、ファイルが変更されているとこんな画面になる。
他のエディタ、たとえばWindowsのアプリは、ほぼすべてが、こんな感じで警告してくれる。
このように、ふつーのエディタはファイルに変更があると、親切にも「保存してもよろしいか?」と確認してくれるのだ。そしてviのZZのように、黙って上書き保存してしまうようなコマンドは見つからなかった。
もし、エディタに対して「終了時に、ファイルに対して変更があったら確認してセーブして欲しい」と思うなら、viは最悪のエディタだ。この動作を一発で行えるコマンドが存在しないからだ。viはインタラクティブなコマンドがほとんど存在せず(vimは知りません)、ユーザに対して許可を取ろうとすることはない。というのもviの態度は「ユーザはもちろん自分がやろうとしていることを熟知してますよね、だから自分は言われたことを黙って直ちにやります」だからだ。
これはたとえば、readonlyのファイルに対して:wしようとすると分かる。viは権限がないファイルに対して「書けなかったよ(書きたかったら!つけなよ)」と言う。決して「書き込めませんでした。強制的に書き込みますか? y/n」とは言わない。
なぜviはこんなにヘンなのだろう? ……実をいうと、viはUnixコマンドとしてごく普通の振る舞いをしているだけで、特別にヘンというわけではない。viの無愛想なところ、「ユーザは自分がしようとしていることを知っている」という態度はUnix哲学として知られ、多くのUnixコマンドが備えていた特徴だった。たとえば30年前のジョークにこんなものがある。もしMicrosoftが自動車を作ったら、というものだ。Microsoft社製の自動車を運転していて、道路を外れて街路樹に向かってハンドルを切ると、フロントガラスにこんなダイアログが出るのだ。
このジョークは、Unixユーザならこんな質問はされたくない、という皮肉が込められているから完成するものだった。だが現代ではどうだろうか。Emacsですら「セーブしますか?」と聞いてくるのだから、まあ言わずもがなというところだろう。
もちろん「勝手に上書き保存されては困る」というのもよくわかる。しかし、ただそれだけの理由で「じゃあviはあきらめたら?」というのも極端だ。その結果として、:qを使う運用が編み出されているのだろう、というのが本稿の仮説の論旨だ。
さて、それでは一体どうするのがよいのだろう? 実は自分ではよく分からない。自分はviが日本語化する前の空白期間にMule/Emacsを使っていたこともあるのだが、そのころどのように終了させていたかと言うと、ほとんど反射的にC-x C-s C-x C-cと4ストロークで終わらせていたのだ。Emacsはセーブの必要がないと何もしないので、これでZZの代替になるのだった。またWindowsアプリなどでも、C-sでセーブ動作をした後(これも大抵のアプリは必要がなければ何もしない)、有無を言わさず終了するという動作をしているので、提案としてはそれに近いことをviでやることになるだろう。つまり
- C-gでバッファのModifyフラグを見る
- セーブしたければ:wqして終了
- セーブの必要がなく終了できるなら:q
- セーブしたくないのなら:q!で強制終了
あるいは
- とりあえず:q
- 失敗したら:wqか、意図しない変更だったのなら:q!
だろうか。これは効率という面からは途方もない話に見えるが、心理的安全性という観点では十分妥協しているのではないかと思う。ちなみに、自分はnoshowmode派であるのでフラグを常時表示するようなvim的ハックも受け付けない。
自分はviが大好きだが、その理由はviにしかない機能があって、それが代えがたいからだ。「何も聞かずに上書き保存して終了してくれる」というのもそのひとつだというのが今回分かって、とてもすばらしい気持ちになった。viには他にもたくさんの「viにしかない機能」があるが、また別の機会に取り上げたいと思う。
追記:Emacsのsave-buffers-kill-terminal
本稿を公開したところ、@n_sodaさんから早速指摘をいただいた。
「そしてviのZZのように、黙って上書き保存してしまうようなコマンドは見つからなかった」 についてですが、 emacs だと、「C-u C-x C-c」でこういう動作になります。というわけで別にvi系に特有というわけではないです。
https://twitter.com/n_soda/status/1143797644579373057
さすがEmacs、ちゃんとそういう機能があるということだ。@n_soda さん曰く、本来の C-x C-c (save-buffers-kill-terminal) は終了時に確認しながらセーブするが、引数をつけると確認なしでセーブするという動作になる。C-u は save-buffers-kill-terminal に引数を渡すために指定するのだそうだ。
C-x C-c runs the command save-buffers-kill-terminal, which is an interactive compiled Lisp function. It is bound to C-x C-c, <menu-bar> <file> <exit-emacs>. (save-buffers-kill-terminal &optional ARG) Offer to save each buffer, then kill the current connection. If the current frame has no client, kill Emacs itself. With prefix ARG, silently save all file-visiting buffers, then kill. If emacsclient was started with a list of filenames to edit, then only these files will be asked to be saved.
@n_soda さんありがとうございました。