VSCode+Vim バインディングでフロントエンド開発


「きっと違う世界を生きていくんだな」　
VPS で出会い、Sublime Text の Vintage Mode や Atom の vim-mode と向き合った青春。
自分には解り続けることはできなかった。

あれから10年近くが経つ。
憧れは、淡く去っていくだけだと思っていた...

## はじめに
縁あって本年度よりフロントエンドエンジニアとして働かさせていただいています。
プログラムを書くのは趣味で、たまに自分の欲しいものを作るに留まっていました。
業務レベルになると至らない点が多々ありますが、日々楽しく学ばさせていただいています。

働き出して真っ先に驚いたのはエディタ操作の高速さです。
ショートカットを駆使し、コードを奏でる先輩方。ちょーかっこいい。

自分もそうなりたい。真っ先に思い出したのは青春時代の記憶でした。
未熟な自分は Vim を使えば効率が落ちるだけでしたが、思想に魅せられていたのでたまに使っては挫折を繰り返していました。

そして2021年。エンジニアになったのでせっかくだから練習して仕事で使いたい。これは絶対楽しくなるな、と。なので Vim を業務で使えるよう整備しようとしましたが、どうやら開発には共通の VSCode 拡張機能を使うことがあるようです。

そのため VSCode 上で Vim のバインディングを実現し、フロントエンド開発を行うエディタを整備します。

## VSCodeVim の問題点
求めている環境を実現するために、真っ先に挙がるのは [VSCodeVim](https://marketplace.visualstudio.com/items?itemName=vscodevim.vim) です。拡張機能のところで Vim と検索すると真っ先に出てくるヤツ。拡張機能として追加するだけで Vim のエミュレートを行うことができる、手軽さが魅力です。しかし、フロントエンド開発にて多用する Emmet を用いた展開時に、Visual モードに移行してしまう[バグ](https://github.com/VSCodeVim/Vim/issues/5884)が存在しました。その都度、モードを変更するのはなかなかのストレスです。加えて若干起動が重くなるデメリットもあります。

2021/01/26 追記：
VSCodeVimを Version 1.16 にダウングレードを行うことで Emmet での展開できるようになるそうです。
ダウングレード方法については[こちら](https://stackoverflow.com/questions/62299687/how-to-install-previous-version-of-python-extension-for-vscode/66134500#66134500)

## VSCode Neovim という解決策
VSCode 上で Vim のバインディングを実現する手段はいくつかありますが、一番しっくりきたのは [VSCode Neovim](https://github.com/asvetliakov/vscode-neovim) です。他の拡張機能とは違いエミュレートではなく、Neovim[^1] を立ち上げ VSCode とやりとりし動作するのが特徴。Emmet の展開も問題なく行うことができ[^2]、動作も VSCodeVim と比べ軽量です。

## 環境構築

### 筆者環境
macOS Big Sur 11.6
VSCode 1.62.3
homebrew 3.3.3

### 構築の流れ
1. Neovim のインストール
2. VSCode Neovim　（ VSCode 拡張機能）のインストール・設定
3. カーソル移動が連続入力できるように

#### 1. Neovim のインストール

```terminal:terminal
$ brew install nvim
$ nvim -v
> NVIM 0.6.0
```

#### 2. VSCode Neovim ( VSCode 拡張機能 ) のインストール・設定

以下URL、もしくは拡張機能から検索
https://marketplace.visualstudio.com/items?itemName=asvetliakov.vscode-neovim

Neovim　のパスを拡張機能側に設定します。

```terminal:terminal
$ which nvim
> /usr/local/bin/nvim
```

取得したパスを元に、 VSCode の setting.json　に以下の項目を追記します。

```json:setting.json
"vscode-neovim.neovimExecutablePaths.darwin": "/usr/local/bin/nvim",
"vscode-neovim.neovimInitVimPaths.darwin": "/Users/ユーザー名/.config/nvim/init.vim"
```

#### 3. カーソル移動が連続入力できるように
デフォルトでは hjkl を用いたカーソル移動が連続入力できないので、以下を実行します。

```terminal:terminal
$ defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false
$ defaults write com.microsoft.VSCodeInsiders ApplePressAndHoldEnabled -bool false
```
実行後、再起動して完了。

#### 【任意】 ESC の割り当て
多くの Vim 設定で用いられるであろう、インサートモードの`ESC`を`jj`・`jk`にバインディングすることも可能です。[^3]自分は下記の設定を　VSCode の keybindings.json に追記しています。

```json:keybinding.json
{
    "command": "vscode-neovim.compositeEscape1",
    "key": "j",
    "when": "neovim.mode == insert && editorTextFocus",
    "args": "j"
},
{
    "command": "vscode-neovim.compositeEscape2",
    "key": "k",
    "when": "neovim.mode == insert && editorTextFocus",
    "args": "k"
}
```
上記の設定では`jj`と入力しても`ESC`になります。`jj`に対しては反応せず、`jk`のみに反応という設定は今のところ対応していないようです[^4]。

## まとめ
お気に入りのエディタにほぼ毎日触れるのが幸せです。最近は[実践 Vim](https://tatsu-zine.com/books/practical-vim) を読ませていただいています。VSCode Neovim　には Vim のプラグインを追加して拡張することも可能なので、そちらの方面も[^5]調べてみたいです。憧れまでは程遠いけど、確実に1歩目を踏み出せたのかな、と思っています。

## 参考文献
超融合!時空を越えた絆 Neo Vim(VSCode)を試してみた
https://zenn.dev/yutakatay/articles/vscode-neovim

VSCode NeoVim拡張　使うまでに詰まったところ
https://zenn.dev/bun913/articles/02785aed0ba50e

VSCode for Macでvimキーバインドにしたとき連続入力できない問題
https://twismik0.hatenablog.com/entry/2017/08/14/115502

## 謝辞
熱心な Emacs ユーザーでありながら洗脳[^6]しようとしなかった研究室の T 教授に心から感謝します。

[^1]: https://qiita.com/lighttiger2505/items/440c32e40082dc310c1e
[^2]: デフォルトでは JSX 内の展開はできません。VSCode 側の設定を[変更する](https://qiita.com/rei67/items/f19983a755998cee6bef)必要があります。
[^3]: 開発に Nunjucks を用いる場合は、jj 割り当てがおすすめです。（拡張子と競合）。
[^4]: https://github.com/asvetliakov/vscode-neovim
[^5]: 紹介できるほど使いこなせていませんが、[vim-surround](https://github.com/tpope/vim-surround) がお気に入りです。
[^6]: しれっと Spacemacs は勧めてきたけど！