Vim昔語/激闘編

思えばあの頃は常に何かと戦っていた、そんな思い出話。

思えばあの頃は常に何かと戦っていた、そんな思い出話。

Vimスクリプトで大きなアプリケーションを書くことで、スクリプトのみならずVim全体の弱点が見えてきていた。なんでもスクリプトで書いてやろうとしたがなんでもは書けるわけもなく、Vim本体に手を入れてでもスクリプトでいろいろできるようにしたりもした。mattnさんのボツになったパッチのうちソケットやプロセス操作などのほとんどがこの文脈にあったと記憶している。そんなmattnさんの玉砕を時に加担したりやっぱりねと横目に見たりしつつ、私はといえばある青写真を描いてその実現に舵を切っていた。

私たちが何故そうまでしたのか。その問に答えるのは簡単だ。戦っていたのだ。相手はEmacsであり、Visual StudioやEclipseといったIDEである。Emacsは説明するまでもない万能エディタで、始まりからしてアプリという枠を超え統合された環境だった。アドバンテージといえばEmacsはLispというアベレージユーザには決して使いこなせない難解な言語で構成されていた点と、あまりに統合されすぎていたためにいかんともし難くなっていた足回りの遅さ。片やIDEはプログラミング・開発という決して広くない分野へ特化したために、多くの使いやすい機能を手に入れた攻撃力のとにかく高いアプリケーション。特に当時Visual StudioのC++においてIntellisenseと言われたコンテキトに応じた補完機能は他の追随を許さないほど完成された、それでいて誰にでもわかりやすい恩恵のある機能だった。特化しているゆえのアドバンテージ、それだけに汎用性に乏しいことが弱点もなり得た。

Vimにはもともと高度な補完機能が備わっている。複数の補完方法をユーザが随時決定できるのだ。特にinsertモードにおけるCTRL-N/Pはキーワード補完と言い、入力済みのキーワードで始まる単語をすべてのバッファから検索し順次補完候補として仮入力してくれる優れものである。ただしこれは使いこなすのが難しい。慣れてしまえば簡単なことなのだが、現在Vimが持つバッファの内容を、どこにどんな単語が入っているかをおおよそ把握しておけば良いだけだ。実際の開発業務において、言語が決まってライブラリフレームワークが定まってしまえば使うべき語彙はさほど多くない。ある程度の熟練者であれば「これこれこういう処理を書きたい」「そのために必要な関数はあそこで使っていたな」「たしかこんなキーワードで始まるぞ」というような思考のもとで、キーワード補完はIntellisenseが不要なほどの絶大な効果を発揮する。これは嘘でも大げさでもない、JAROも不要である。

だがしかし、2chでIDEのIntellisenseを引き合いにだされ「だからVimはダメなんだ」と主張されれば、最終的に勝ち目がないことを悟るにはかなりの時間とファビョることを必要とした。幾度となく遠回りをした結果IntellisenseをVimで実現することに決めた。結局のところ補完だ。Vimにできないことではない。実際言語やライブラリを固定できるのであれば補完機能を作るのは難しくない。特にJavaなどは性質が良すぎてアルゴリズムが簡単に思い浮かんだ。だが必要なのはソレじゃない。どんな言語フォーマットでも補完でき、場合によってはIMEすら記述しうるフレームワークだ。しかも世界中のVim開発関係者、誰もが納得する形にしなければならない。ややこしい議論に巻き込まれてしまえばフォローしきれない。

アイデアはこうだ。まずVimに新たな補完方法を増やす。その補完方法ではスクリプトで補完候補を決定する。そして補完候補一覧を表示するメニュー機能を実装する。こうすればあとからいくらでも補完機能を増やすことができる。IntellisenseもIMEも実装し放題だ。私はメニュー機能は棚に上げ(私には必要なかった)、早々にスクリプト補完までを実装し機会を待った。

その機会は思いのほか早くやってきた。世の中のトレンドがそういう時期にあったのだろう。海外のあるユーザがWindows専用のJava(だったよね?)の補完機能を作成しvim-devに提案したのだ。私は却下されるだろうと思っていたし実際そうなった。「それWindows以外のプラットフォームどうすんだよ」理由まで予想したとおりで、待ってましたとすかさず議論に参加する。その時のメールの文面はだいたいこんな感じだった。

VimがUIを提供したらどうかな? Vimには補完機能があるけど今はファイル(バッファ)からしか持ってこれないよね。もしもスクリプトで補完候補を作ることができ、メニューみたいなUIがあればIntellisenseみたいな機能をいろんな言語について実装できるじゃん。そうそうココに僕の作った補完候補のパッチがあるんだよ。こんな風に使うんだけどどうかな? これに補完候補を表示するフローティングウィンドウがあれば、VimでIntellisenseを理論上は全てのプラットフォームと言語に展開できるだろ。

日本人が大好きな「こんなこともあろうかと」をしれっと実行したのである。しかもメニューUIの実装は丸投げで。

さてこのパッチ、当時は議論されることはなかった。すぐに取り込まれることもなかったと思う。確か7.0へのメジャーアップグレードでマージされ、メニューUIもその時におそらくBram氏により実装された。つまり私の提案に賛同してくれていたと解釈して良いだろう。最初のメニューUIは特にマルチバイト絡みでかなりBuggyで、mattnさんが相当に頑張ってデバッグしてくれていたと記憶している。私が提案した機能は名前やキーマップこそ変わったものの、ほぼそのまま取り込まれていた。現在の補完関数の奇っ怪な引数の仕様がその証拠である。興味がある人は:help complete-functionsを見て欲しい。

こうしてVimにはIntellisenseも実装しうる汎用の補完機能が実装された。この機能は後にneocomplcache.vimなどに代表される補完系のスクリプトに繋がることになる。私が当初意図したIntellisenseにとどまらず、その先の機能へ昇華したことは心の底から嬉しい。「あれはワシが育てた」ならぬ「あれはワシが生んだ」そんな心境だ。

以下、続くかもしれない。

ちなみに私はそれらのスクリプトを一切使用していない。いったいどういった了見なのだろうw