1976年はテキストエディターにとっては良い年でした。MITでは、Richard StallmanとGuy SteeleがEmacsの最初のバージョンを書きました。バークレーではBill Joyがviを書きました(viと呼ばれるにはまだ数年を要しましたが)。
2つのエディターはひとつの同じ大きな考え方を元に作られてるんだと還元主義者(reductionist)は言いそうですが、仕方ありません、ここでは還元主義者になりましょう。2014年に目につくもの(訳注 : この記事は2014年に書かれたもの)、つまりSublime TextやAtomといったモダンなエディターを見てみると、Emacsの大きな考え方は完全に理解されている一方で、viのそれは理解されているとは言えないのです。
Emacsと拡張性
Emacsのいい考え方とは、改変と拡張がきれいにできることでした。エディターの機能はコマンドのライブラリーで定義され、さらに個別のキーストロークに結合されています。バッファーの保存(save-buffer
)コマンドはC-x C-s、マークした位置からカーソルまで削除(kill-region
)のコマンドはC-w、というようになっているわけです。
もしキーマッピングが気に入らなければ、変更することもできます。kill-region
をC-kにしたいならさあどうぞ。マッピングを変更するだけではなく、機能を追加したいならビルトインの関数と同じ言語(GNU Emacsの場合Lisp)で独自の関数を書いてしまうことができます。エディターのUIは無限に拡張可能と言ってもいいくらいですし、思いのままに変更してしまうこともできます。
これが当たり前に聞こえるなら、それはEmacsの大きな考え方が広く影響力を持っていて、まともなエディターでは拡張性が今日当たり前の機能だからです。Sublime TextはLispの代わりにPythonを使っていて、AtomはCoffeeScriptを使っていますが、コマンドやキーマップの基本は、コア機能に組み込まれています。VimですらEmacsの拡張性を取り込んでいます。Vim scriptは、コマンドのキーストロークをマッピングできる新しい関数を定義できます。
viとコンポーザビリティー
viの大きな考え方は、同じくらい影響力を持ってきたとはいえません。
viは根本的には、コマンドのコンポーザビリティー(訳注 : 組み合わせによる拡張性)を元に作られました。これは、大きなコマンドを作るオブジェクトを組み合わせるのに使える小さくて多目的なコマンドに向いています。その一方で、Emacsとその哲学を受け継いだ者達(Sublime TextやAtomを含む)は、モノリシックで特定用途のコマンドを使います。
例えば、カーソルを1単語先まで動かす、行末まで動かす、ファイルの末尾まで動かす、段落の末尾まで動かす、という場合を考えてみましょう。
Emacsはこれらの動作に対応するコマンドを持っています。それぞれ、 forward-word
、 move-end-of-line
、 end-of-buffer
、 forward-paragraph
です。Atomには次の3つ moveCursorToBeginningOfNextWord()
、 moveCursorToEndOfLine()
、 moveCursorToBottom()
があります。
Vimにももちろんこれらのコマンドがあります。 w
、 $
、 G
、 }
です。これらはviがプログラマブルでなかった頃の遺産(キーとコマンドが分離できない関係を持っていた)を引きずっているのでひどい名前ではありますが、基本的には同じ土俵に載っていると言えます。
しかしここで、削除のコマンドを見てみましょう。単語を削除する、行末まで削除する、ファイルの末尾まで削除する、段落の末尾まで削除する、という場合です。
Emacsは、 kill-word
と kill-line
という2つの関数しかありません。Atomも同じく deleteToEndOfWord()
と deleteLine()
です。
Vimはしかし違います。Vimは d
、つまり「削除(delete)」という1つのコマンドしかありません。何を削除するのかって?それはまさにあなたが決めるのです。 d
コマンドは、動作に関するコマンドと一緒に組み合わせます。すなわち、 dw
が単語の削除、 d$
が行末まで削除、 dG
がファイルの末尾まで削除、 d}
が段落の末尾まで削除、です。
これが、Vimのコンポーザビリティーが力を発揮するところです。EmacsやAtomには、ファイルの末尾までや段落の末尾まで移動するコマンドはあるのに、削除を行うコマンドがありません。しかしVimでは、そこまで移動できるコマンドがありさえすれば、削除するコマンドもあるのです。
コンポーザビリティーは強力なだけでなく、学習性と一貫性にも意味があります。Vimでテキストをコピーするコマンドは y
です。行末、ファイルの末尾、段落の末尾のそれぞれまでコピーする方法を知っていますか?もちろん分かるはずです。それぞれ、 y$
、 yG
、 y}
です。インデントを追加するコマンドは >
なので、すぐに >$
、 >G
、 >}
が分かります。小文字への変換は gu
なので、もちろん gu$
、 guG
、 gu}
です。
組み合わせて使う必要最小限のコマンドというこの哲学は、UNIX哲学から来た基本原則で、Vimは他のどのエディターとも違ってそれを体現しているのです。
Vimは永遠に使われる?
しかしもちろんVimも完璧ではありません。Vim scriptは誰にも好まれないプログラミング言語です。最初の使い勝手は最悪で、基本的な機能を動くようにするのに半ダースのサードパーティープラグインを(加えてサードパーティープラグインマネージャー自体も)インストールする必要があります。さらにモーダルな仕組みがさらにアプローチを難しくしてますし、拡張性にも根本的な制限がある程度はあります(特にビジュアル面)。
新しいピカピカのモダンなエディターは、その問題点のいくつか(できれば全部)を直せばVimより一歩先んじる存在になりうるでしょう。しかしいずれかのエディターがVimを置き換える前に、1976年が教えてくれるあらゆることがそこに含まれる必要があります。Emacsが教えてくれたことだけでなく、viが教えてくれたこともです。