VS CodeとVimとわたし

目次

プログラミングをするときのテキストエディタを、かれこれ20年くらい使ってきたVimから、VS Codeに乗り換えた。

20年使ってたvimやめて、今週からVS Code使いはじめた。

一番の理由はCopilotで、Copilotの恩恵を一番受けられるのがVS Codeだと思うので。

あと、ここ数年、LSPやらなんやらで、いろいろvimの限界感じてたっていうのもある。

— tai2 (@__tai2__) July 12, 2023

20年という年月は、ぼくにとっては、人生の半分近く、プログラマー生活の大半を締める長い時間だ。そんな相棒とも言えるテキストエディタをなぜ捨てたのか。 実は近年、いいかげんVimに固執するのも潮時かもしれないと思いつつ使っている状態ではあった。 そして、VS Codeに変えようと決心する最後の決め手になったニュースが2023年3月に発表された。GitHubの Copilot X だ。

エディタ遍歴

そもそもなぜぼくはVimを使っていたのか。最初からVimを使っていたわけではなく、それ以前にもいくつかのエディタを経由している。 Vimに辿りつくまでの間、たぶん5年間くらいは他のエディタを使っていた。ぼくのエディタ遍歴は、このような感じだ:

  1. Visual Studio 6.0
  2. サクラエディタ
  3. Meadow (Windows用Emacsクローン)
  4. Vim
  5. VS Code

最初は、専門学校の授業で使っていたのと同じIDE(ちなみに当時のIDEは有料で、学割でも5,6万円くらいした気がする)、次に軽量なテキストエディタと移った。 それからすこしプログラミングに詳しくなってくると、ハッカーはEmacsを使うものだという知識を仕入れて、Meadowを使うようになった。 設定ファイルをあのなんか噂に聞くLispで書くというのもすごそうでシビれた。 Mew を入れてメールクライアントとして使ってみたり、 howm でメモを取ってみたり。 いろいろ拡張を入れて設定するのはたのしかったのだけど、どうも Emacs Lisp (Emacs拡張のためのLisp)がいつまで経ってもちゃんと覚えられない。

そこで、Emacsと並んでハッカー系の文脈でよく話題に上がるVimに興味が向かった。 拡張記述言語として、Lispのような関数型ではない、ふつうの手続型言語(=Vim script)が採用されてるから、きっとEmacsよりも拡張は楽だろうという見込みだった。 結果としては、ぜんぜんそんなことはなく、けっきょくVim scriptもいまに至るまで使いこなせてはいないんだけど、それ以外の部分は大変手に馴染んだ。 当初想像したように自分でばりばりスクリプトを書いてエディタを拡張するようなことはついぞなかった。まあそんなものだろう。

Vimの好きなところ

なんといってもVimのすごいのは、コマンドに「文法」があって体系的に構成されているというところだった。 たとえば、どんなコマンドでも先頭に数字を付与すればその回数だけ繰り返せる。 hjklでカーソルを移動するのは有名だけど、5hと押せば左に5文字、5jと押せば上に5文字移動できる。 ^と$はそれぞれ行頭行末という意味を持つ「テキストオブジェクト」であり、これは正規表現を知っている人には非常に直感的な割り当てになっている。 ^を押せば行頭に、$を押せば行末にカーソルが移動する。非常に直感的だ。 dは削除のコマンドで、現在のカーソル位置から、対象の位置までの文字を削除する。 これらを組み合わせれば、d^とすれば現在位置から行頭まで削除、d$なら行末までという意味になる。 wは次の単語先頭を表すため、dwなら次の単語まで削除という具合だ。 このように、コマンドを表すコードとテキストオブジェクトを表すコードさえ覚えれば、それらを組み合わせて、自由自在にエディタ内を飛びまわって編集できる。

それから、GUIベースのエディタと違って、それ自身ウィンドウを持たないターミナル内のプロセスとして動作するのも気にいっていた。 Vimに興味を持ったころには、単一機能のコマンド群をパイプを使って組み合わせて使うという 「Unix哲学」 に染まっていたので、 ^zとfgでターミナルとエディタを軽快に行き来できるVimの体験は非常に快適だった。

Vimへの不満

とはいえ、最近は不満もあった。とくに、 LSP が出現して以降は、 なにか騙し騙しVimを使っているような感覚があった。Vimにおいても、LSPをサポートするプラグイン自体はもちろんある。 だけど、そもそもターミナルという文字情報だけですべてを表現しないといけないグラフィカルではない環境で、 インテリセンスやツールチップを動作させて狭い領域にたくさんの情報を詰め込んで表示させても、あまり美しくないし、見易くもない。

LSPには、非常にたくさんのコマンド群が用意されている。 そして、たいはんのものにはデフォルトのキーバインドは用意されていない。 が、Vimを使う以上、なるべくキーボードショートカットを設定して使いたい。ぼくにとっては、これが大きな問題だった。 エディタをカスタマイズする上で何が一番嫌いかって、他と衝突しない適切なキーバインドを探すことほど苦痛なことはない。 できることならキーバインドは最初からいい感じに決まっていて、それを覚えるだけで済ませたい。 個人的には、これが、VimでLSPを使う上での障害になっている。

VS Code移行の動機

冒頭でも述べた通り、VS Code移行を決意する直接のきっかけとなったのは、GitHubのCopilot X発表だった。

以前から存在したCopilotについてはある程度知っていたし、ChatGPTの威力もすでに十分わかっていた。 Copilot Xは、それらの最新AI技術をGitHubの各種機能に統合して、AIを全面的に活用していくというメッセージだと受けとった。 ぼくはこれを見て、今後はプログラミングにおいてAIの補助を受けることがあたりまえになって、 プログラミングそのものが、いまとは違う形になっていくんだろうなと直感した。そして、その変化を引っ張っていくのがMicrosoft/GitHubである以上、 将来的にもっともAIプログラミングの恩恵を受けられるのは、VS Codeというテキストエディタなのだろうと思った。

もちろん、建前上、Copilot XはVS Codeだけのための機能ではなく、エコシステムを通じてさまざまな環境に提供されるということになっているけど、 一番開発リソースが割かれて、ユーザー体験として快適に利用できるのはVS Codeになるのだろうと思う。 実際、Copilot Xに含まれる機能のひとつである Copilot Chat は、発表から1年以上経っている現時点でも、Vimでは利用できない。 であれば、まだ今後何十年もプログラミングを続ける以上、使い慣れた快適な環境を捨ててでも、VS Codeに適応すべきだろうと決断した。

VS Codeに移行してみて

ということで、VS Codeに移行して、かれこれ10ヶ月くらい経つ。いまでは業務のコードも含めてすべてVS Codeで書いている。以下は、使ってみた感想を書いてみる。

Copilot/Copilot Chatは思ったほど活用してない

まず一番の動機であるCopilotまわりの機能だけど、いまのところ、思ったよりは活用というか、依存はしてない。 もちろん、VS Codeは隙あらばAIによるコード補完を提案してくるので、使えそうなコードは、そのまま受けいれてはいる。 けど、AIの提案するコード補完は、そこまで高精度というわけではない。 どちらかというと、プロジェクト内の他の場所からコピペしてきて書き換えるという旧来通りのやりかたをいまのところは続けている。 わからないときにAIチャットというのも、たまに使いはするけど、いまだにGoogle検索で済ませてしまうことのほうが多い。これはまあ、慣れの問題かもしれない。

Copilotでひとつ便利だなと思うのは、一括置換をしたいときだ。 これまでは、特定範囲に対して規則的な変換を適用したいときに、それを達成するための正規表現を考案して置換していたけど、だいたい試行錯誤が発生するし、 一発ではできないから複数の正規表現に分割して実行したりする必要があって、そこまで快適ではなかった。 こういうときに、Copilot Chatであれば、変換したい範囲を選択して、どのように変換したいかを自然言語で伝達すれば、 目的の形式に書き直してくれる(ことが多い)ので、けっこう便利。

VS Codeはキーバインドを覚えさせる気がない

VS Codeで一点、どうやってもVimよりも劣っていると言わざるを得ないことがある。 それは、Vimのようにコマンドに「体系」がないことだ。テキストオブジェクトみたいな概念もない。 次や前の単語、括弧、特定の文字に移動したくでもできない。 括弧内、タグ内、ブロック内のテキストを瞬時に選択することができない(がんばればできるのかもしれないけど、Vimのように直感的な操作ではないと思う)。 結果として、カーソル移動やテキスト選択がクソほど貧弱で、Vimのように自由自在にはテキストを編集できない。

VS Code内でVimの操作感を再現する手段として、 Vim拡張 というのがある。 これを使えば、テキストオブジェクトのような概念も実装されて、たしかにほぼVimと同じと言える操作感が実現される。 再現度はかなり高い。はっきりいって、Vimユーザーにとってはものすごく快適だ。 一方で、元々ある機能とコンフリクトしてしまうことがまれにある。 それに、VS Codeに引っ越してきてまで、Vimの体験を引きずり続けるのは、なんだかみっともないような気がする。 郷に入っては郷に従え。むしろ、VS Codeの元々持っているポテンシャルを引き出すような使いかたをしたい。ということで、ぼくはVim拡張を禁じることにした。

ターミナルから使っていたこともあり、Vimを使っているときは、キーボードだけですべての操作を完結させることにこだわっていた。 だから、VS Codeでもなるべくマウスを使わずにキーボードだけで済ませたいと思ってしばらくがんばっていた。 けど、それが間違った考えかたであるっぽいことが、だんたんわかってきた。 もちろん、VS Codeでもすべてのコマンドにキーバインドを設定してキーボードから操作することが可能だとは思うけど、 デフォルトでは、装飾キーを二つ以上同時に押しながらみたいな押しづらく覚えづらいものが非常に多いし、 それらが系統立って整理されているわけでもない。 VS Codeの特徴として、マルチカーソル系の操作がいろいろ充実しているようだけど、ショートカットが覚えられないので、ぼくはほとんど使えていない。

結論として、VS Codeにおいてキーボードだけで作業を完結させるのはあきらめた。 プログラミング中にキーボードから右手をはずしてマウスをポチポチやるというのは、なんだかとても情けない気分だけど、 VS Codeというエディタにおいては、たぶんそれがふつうなんだと思う。 かわりにVS Codeではコマンドパレットがかなり使いやすくなっていて、そこから検索すれば必要な機能に手早くアクセスできる。 このやぼったさがVS Code流のプログラミングスタイル、そう思ってなんとかやりくりしている。

LSPは非常に快適

一方で、VS Code上でのLSPは非常にスムーズだ。 言語ごとに必要な拡張を、マーケットプレース から1クリックでインストールするだけでOKだし、 補完時やホバーでの情報表示などのインテリセンスもいい感じに表示してくれて、とても見易い。 すべてをキーボードショートカットに割り当てて使うのをあきらめたことで、かえって、機能が多いことによるストレスもなくなった。 シンボルに関する情報が見たいときは、マウスカーソルをホバーすればいいだけだ。LSPに関する体験は、全般的に非常に満足度が高い。

ターミナル連携が非常に強力

Vimはそれ自身ウィンドウを持つGUI版と、そうではないCUI版がある。Vimのときは、ターミナルとスムーズに行き来したかったのでCUI版を使っていた。 近年は、Vim内に統合されたターミナルというのも実装されていたけれど、あまりメリットを感じられなかったので使っていなかった。

VS Codeには、CUIモードはないので、ターミナルとの付き合いかたも見直さなければならない。 いい機会なのでターミナルもVS Code付属の統合ターミナルを使うことにしたけど、これが思ったよりも便利だった。 VS Codeのターミナルには、ターミナル上に表示された ファイルパスを自動的に検出してリンクしてくれる機能 がある。 これが地味に便利で、これのおかげでいろいろなCLIコマンドとVS Codeを非常に便利に連携できる。

ぼくは、昔から、IDEについているプロジェクトの検索機能というのが好きになれなかった。 VS Codeのプロジェクト検索機能もご多分に漏れず、検索範囲を手早くしぼりこむことができないし、検索結果も非常に見辛いのであまりつかいたくない。 しかし、このターミナルからのリンク検出があるおかげで、エディタ内の検索機能はまったく使う必要がない。 かわりに、git grepを使えばいい。-nを付ければファイル名の横にコロン区切りで行数がつく。 これは、VS Codeがリンクとして検出してくれるフォーマットになっている。 なので、git grepで検索した結果にたいして、マウスクリックで当該行までエディタ内でジャンプできる。 さらに、git grepに限らず、コマンドの実行結果として表示されたファイルパスを通じて、 コンパイラやリンターなど、いろいろなコマンドともVS Codeを有機的に連携できる。 これはほんとうに便利。

GitHub Pull Request拡張

チームでのコミュニケーションでは、エビデンスあるいは参考として、GitHub上で、特定ファイル行へのPermlinkをとにかく貼りまくりたい。 このために、これまではブラウザを開いて、GitHub上で該当ファイルを探し、その上でPermlinkを取得していた。 GitHub Pull Requests という拡張を使うと、 VS Codeから直接GitHubへのPermlinkを取得できる。これは個人的にライフチェンジングで、これのおかげで、めちゃくちゃコミュニケーションの効率が上がった。

また、この拡張を入れた状態で、リモートのブランチをチェックアウトすると、対応するプルリクエストをVS Code上でレビューできるようになる。 これは、 苦手なコードレビューの体験 をかなり改善してくれた。 最近は、ブラウザ上でのプルリクエストレビューUIもかなり便利にはなっているけど、 VS Codeならすべてのコードがすでにチェックアウト済みで、ローカルファイルシステムから高速にアクセスできる。こちらのほうがより便利だ。 差分を見つつ、ファイルの全体像を確認するのも容易だし、通常のテキストエディタの体験と統合されているので、PRに含まれないファイルを辿ることも簡単にできる。 これのおかげでコードレビューでの苦痛がだいぶ減ったと思う。

まとめ