Vim やめます

# はじめに

この度、長年連れ沿ったVimとお別れをすることにしました。移行先はVSCodeです。
正直に言うと、かなり前からVSCodeへの移行は検討していました。実際過去に何度もVSCodeへの完全移行は試しており、その度に挫折してきていました。
今回は挫折していた理由も含めてお話ししていこうと思います。


## なぜ移行しなかったのか

まず第一に、Vimをあまり普段使いしていないひとは驚くかもしれませんが、VSCodeに備わっている機能のうち、Vimではまったく出来ていなかったことというのは多くありません。Vimのlanguage serverとの連携は強固であり、定義ジャンプや補完・自動フォーマットといった動作もVSCodeとかわらず実現できます。Vimの中からGit関連の操作をすることも、ファイル操作も、デバッガを動かすことも、スニペット機能もmarkdownのプレビューも出来ていました。

それらの機能を実現するためのプラグインを導入していたのです。
プラグインさえいれてしまえばVSCodeの機能の多くは実現可能でした。

この事実はVimを離れるという決断を大きく遅らせていたと思います。

![vim_smal.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196544/d09d2092-7177-c3c8-4cbe-e6dea12f5520.gif)
 図： VimでのGo言語の補完の様子

また、僕のなかで、他のエディタへと移行するにしても, Vimモードは外せないものとして考えていました。
それほどまでにVimのキーバインドは優れており、一種の麻薬と化しています。何年も連れ沿っただけはあり、もはや脳ではなく筋肉がVimのキーバインドを覚えてしまっています。
こういった動作をしたいと考えたときにはすでに、指が勝手にそれを実現するためのコマンドを打ち始めているといった状態が実現されていたのです。そのため、移行するとすればVSCodeにVim extentionを乗せた状態、これは大前提として考えていました。

問題はこの[Vim extension](https://github.com/VSCodeVim/Vim)にありました。
このVSCodeVimは長年、僕の目から見てVimをエミュレートしきれているとは言い切れない要素を多々はらんでいました。
例えば、新たなキーマップを登録しようとしたときに, Ctrlと他のキーの同時押しをフックにするといったことはぱっと設定出来る範囲ではほぼ不可能な状態が続いていました。[^1]
Vimを使っている人であれば、自分の思う通りにキーバインドを設定出来ないストレスが如何ほどのものか分かっていただけるのではないでしょうか。

## なぜ移行するのか

移行しなかった理由の項目であげた、プラグインによって実現していた機能の殆どはVSCodeであればインストールしてきた時点で利用可能な機能ばかりです。Vimのようにわざわざそれらの機能を実現するためのプラグインを探し、インストールする必要はありません。
Vimでも[dein.vim](https://github.com/Shougo/dein.vim)や[coc.nvim](https://github.com/neoclide/coc.nvim)を使ってプラグインやlanguage serverの半自動セットアップは実現していました。
それでもやはり、わずらわしさは残ってしまいます。
dein.vimを使ってもプラグインを探す動作から解放されるわけではありません。coc.nvimは自動インストールに対応していないlanguage serverも多く、自分でlanguage serverをインストールしたあとにcoc.nvimと連携する設定を書かなければならないシーンが発生していました。

強いて言うのであれば、この「わずらわしさ」が自らの手で自ら使う道具をカスタマイズしていく喜びを上回ってしまったように思います。
もちろんVSCodeに移行したからといって完全にそういった作業から解放されることはないとは認識していますが、VimにはNeovimのような派生も存在しており、プラグイン側がどこまでサポートしているのかといったことも調べなければならず、こういった作業が軽減できるのではないかという判断です。

また、徐々に、徐々にではありますが、Vim Extensionに存在していた「移行しなかった理由」も潰されつつあります。
先述したCtrl+何かのフックも可能になりました。同様のissueが乱立していて分かりにくいのですが https://github.com/VSCodeVim/Vim/issues/757 や関連するissueを確認してもらえば分かるとおもいます。

settingファイルに下記のような設定を記載するだけで実現できるようになりました。

```json
"vim.insertModeKeyBindingsNonRecursive": [
    {
        "before": [
            "<c-j>",
        ],
        "after": [
            "<Esc>"
        ],
        "when": "editorFocus"
    },
],
```

 ※ ここでは例としてinsert mode時にCtrl+jでノーマルモードに戾す設定を記述しています。

当然、Vimでも同様のことは可能です。

```vim
inoremap <C-j> <Esc>
```

こう見ると、Vimのほうが記載量が短かく、楽なようにも見えますが, imap, nmap, vmap,inoremap, nnoremap, vnoremapといったVim用の記載方法は慣れ親しんだ人たちにとっては簡易に思えても、やはり直感的でない部分が残るように思えます。

VSCodeのRemote Developmentの追加も僕のなかでは非常に、非常に大きなアップデートでした。
普段僕はSSH先で作業をすることが多いのですが、その時にもVSCodeを使っていて困るということが無くなってしまいました。

## まだまだ残る課題

もちろん、VSCodeに移行して、いままで出来ていたことが全て実現出来たかと言うとそうではありません。実現出来ていない機能は多々残っています。
たとえば、本来のVimはショートカットを最長一致しようとするのに対し、VSCodeVimは最短一致させようとしてきます。そのため、たとえば[`ss`のようなショートカットを振ることができません](https://github.com/VSCodeVim/Vim/issues/1821)。これは`s`にもともとカーソル下の文字を消してインサートモードへ入るといった機能が振られているためです。そのためVSCodeVimでは`s`を押した時点でその動作を実行してしまい、次の`s`はインサートモードでの入力と解釈してしまいます。

[`virtualedit=onemore`は設定出来ません](https://github.com/VSCodeVim/Vim/issues/1632)。これは本来のVimでは行の最後に空白があるかのように振るまうようになる設定です。これによってinsertモードに入るときにiを押すべきなのか, aを押すべきなのかといったわずかな迷いを減らすことが出来ていました。

Vimの優れたpluginたちを利用することが出来ません。[主要なpluginは組み込まれてはいますが](https://github.com/VSCodeVim/Vim#-emulated-plugins)、それ以外のVimのプラグインを利用することは出来ません。これによっていままではキーボードから手をはなさずに出来ていた動作がわざわざマウスまで手を伸ばさないといけなくなるといったことが多々発生しています[^2]

## おわりに

僕の記憶が正しければVimを使いはじめたのは15歳のころだったので、もう7年以上もVimを使って開発してきたことになります。
特に2年ほどまえに上京してきてからしばらくの間はVimに関する勉強会が手の届く範囲で開催されていることがとてもうれしく、多くの勉強会に参加させていただきました。Vim-jpのslackやvimrc読書会などへも積極的に参加してきました。(僕自身の対人能力の低さのせいであまりコミュニケーションはとれていませんでしたが...)
そういった活動のなかで様々な知見を獲得できたことを嬉しく思っていますし、開催に携わってくれた方々には深く感謝しています。 

Vimを使いはじめた当時は周りにVimを使っているひとなど誰一人としておらず、唯一当時所属していた高専の教授にemacs使いがいたくらいでした。その影響でemacsも使ってみたは良いものの、小指が自分の手からではなくCtrlキーから生えているような気分になってきたのですぐにVimに戻ってしまいました。他にも様々なエディタ、IDEに浮気してはもどりを繰り返してきました。もしかしたら今回もその一環かもしれません。こんなポエム記事を公開しておきながら、数週間後にはしれっとまたVimmerに戻っているという可能性も無いわけではありません。そのときはまた暖かく迎えいれて頂ければ非常に嬉しくおもいます。

長々と読んでいただきありがとうございました。


[^1]: Windowsでは動くがMacでは出来ないといった環境依存要素もあったように記憶しています。
[^2]: 逆に言えばマウスまで手をのばせば出来ないことはすくないように思えます