久しぶりにVSCodeVimの設定を見直してみました。
そこから得た知見の一部をVimの設定にも反映させました。

Table of Contents

経緯

ツールによらないキーバインド統一化を目指す過程で、VSCodeのキーバインドを見直し始めたのがきっかけです。
以前からモヤモヤしていたVSCodeVimに関する設定も整理しようと思って始めました。

ツールによらないキーバインド統一化

普通、キーバインドはツールごとに異なります。
ある程度統一されている部分もありますが、細かな違いが脳のコンテキストスイッチの切り替えコストを増大させます。

全てのツールで同じキーバインドを実現することにより、それらの問題を解決するプロジェクトです。
まだ実行には至りませんが、2019年中に完成させたいと思っています。

VSCodeVimとは

VSCodeでVimのような各種操作を実現するための拡張機能です。

以下のようにとても人気があり、私にとってもVSCodeを使う上で欠かせない拡張機能です。

  • ダウンロード500万超
  • インストール100万弱
  • ★4.3

なんとVersion1.0を越えていました! 😄

Plenty of thanks to every one of developers!!

基本設定

基本はREADMEに従っていきます。まずは基本設定です。

OSクリップボードとの同期

OSのクリップボードとの同期はコラボレーションに必須です。

"vim.useSystemClipboard": true

検索結果のハイライト

無効にする理由がありませんので有効にします。

"vim.hlsearch": true

*で配下の単語を検索

無効にする理由がありませんので有効にします。

"vim.visualstar": true

折りたたまれた場所を乗り越える

折りたたまれた箇所について、表示された通りに移動するかどうかのフラグです。
せっかく折りたたんだ箇所が展開されるのはストレスなのでtrueにします。

"vim.foldfix": true

フラグがfalseの場合

フラグがtrueの場合

NeoVim

NeoVimの説明は割愛しますが、以下の様に設定することでいくつかの機能を使えます。

"vim.enableNeovim": true

Chocolateyでインストールして環境変数PATHが通っていない場合はvim.neovimPathの指定が必要です。

"vim.neovimPath": "C:\\tools\\neovim\\Neovim\\bin\\nvim.exe",

できること

以下の2つができるようになります。

  • :normalコマンド(:normコマンド)
  • :gコマンド

詳細はここでは触れません。

マルチカーソルモード

個人的に最もエレガントな項目がこれです! 素晴らしい!!! 😂

私がVimmerになったのは2018年1月ですが、最後まで悩んだことが『マルチカーソルを捨てられるか』でした。
当初、VSCodeVimはマルチカーソルに対応していなかった(動作が不安定あった)のですが遂に…という感じでしょうか。

利用イメージ。
※ 押したキー: steh <C-k><C-k><C-k> cvscode<ESC> ^ $a,<BS> <Space>--vim <ESC><ESC>

カーソルを増やすデフォルトのキーバインドはgbですが、<C-k>に変更しています。

settings.jsonに追加した設定
"vim.normalModeKeyBindings": [
  {
    "before": [
      "<C-k>"
    ],
    "after": [
      "g",
      "b"
    ]
  }
],
"vim.visualModeKeyBindings": [
  {
    "before": [
      "<C-k>",
    ],
    "after": [
      "g",
      "b"
    ]
  }
],
キーバインド設定が上手くいかない...

キーバインド設定はハマリポイントが多いです。
以下を確認しましょう。

beforeとafterが逆転していないか

beforeafterの正しい役割は以下の通りです。

  • before: 割り当てたいキー
  • after: beforeを押した時、代わりにどのキーを押したことにするか

beforeは現在割りあたっているキーではありません😢

vim.visualModeKeyBindingsの設定がされているか

たとえNORMALモードでも、一度目は単語選択をするため必ずVISUALモードに移行します
そのため、vim.visualModeKeyBindingsの設定をしなければ、カーソルを増やすことはできません。

extension.vim_ctrl+?にキーが割りあたっているか

今回の場合、VSCodeのキーバインド設定にて、extension.vim_ctrl+kCtrl+kが割りあたっていなければいけません。
Ctrl+kをVSCodeVimのキーバインドと判別できるようにするためです。

プラグイン

VSCodeVimにプラグイン機能はありません。
その代わりに著名なプラグインをエミュレートするオプションが用意されています。

vim-airline

見た目が格好良くなると思いますが、パフォーマンスが劣化すると書かれていたため無効にしています。

⚠️ There are performance implications to using this plugin. In order to change the status bar, we override the configurations in your workspace settings.json which results in increased latency and a constant changing diff in your working directory (see issue#2124).

vim-easymotion

表示された領域内に少ないタイプ数で移動できます。

"vim.easymotion": true,

利用イメージ。
※ 押したキー: svsk cw<ESC> smau cw<ESC> smai cw<ESC>

sを押した後にキーを入力すると、該当箇所にMarkerが表示されます。
Markerに表示された文字を押すと移動します。

デフォルトのMarkerは好みに合わなかったので設定でカスタマイズしました。

"vim.easymotionMarkerBackgroundColor": "rgba(0, 0, 0, 0.7)",
"vim.easymotionMarkerForegroundColorOneChar": "pink",
"vim.easymotionMarkerWidthPerChar": 12,
"vim.easymotionMarkerHeight": 24,
"vim.easymotionMarkerFontSize": "24",
"vim.easymotionMarkerYOffset": 5,

また、デフォルトではsを押した後のキーが1つなので、2つにするため以下の設定をしました。

"vim.normalModeKeyBindings": [
  {
    "before": [ "s" ],
    "after": [ "<leader>", "<leader>", "2", "s", "<char>", "<char>" ]
  }
],

1つだと候補が多数存在するため、かえって非効率だからです。

jump-motionsで移動前のカーソル位置に戻れない..

vim-easymotionと後述するvim-sneakも…<C-o>で直前の位置に戻ることができませんでした。
シンボルへの移動などjump-listで対応しきれないVSCodeのアクションがいくつかあるようです。

Feature/improved jump list #3028

VSCodeの機能として存在するGo ForwardGo Backの挙動にしたければ、settings.jsonでそのように設定しましょう。

settings.jsonの設定例
{
  "before": [
    "<C-o>"
  ],
  "commands": [
    {
      "command": "workbench.action.navigateBack"
    }
  ]
},
{
  "before": [
    "<C-i>"
  ],
  "commands": [
    {
      "command": "workbench.action.navigateForward"
    }
  ]
},

vim-surround

指定範囲を記号で囲むことができます。
SでVISUALモードのときも使えることは知りませんでした…。

利用イメージ。
※ 押したキー: ysiw) W cs]} B lds)

vim-commentary

指定範囲をコメントイン/コメントアウトできます。
gcオペレータの後にモーションを指定するだけなのでイメージは割愛します。

vim-indent-object

インデント単位で指定できるtext-objectです。
このプラグインは初めて知りましたが、 便利だったのでVimの方にも逆輸入しました。

利用イメージ。
※ 押したキー: vai d

Pythonなどインデントが重要な位置づけを持つ言語では役立ちそうですね。

vim-sneak

f/tをシンプルなまま高機能にできます。

Markerが表示ず、押した瞬間に移動するので候補が少ない場合は強みを発揮します。
一方、候補が多い場合は移動するまで;を押し続けなければいけないのでパフォーマンスが落ちます。

私の場合、VSCodeではvim-easymotionを使うことにしました。
一方、Vim版のoriginalではMarkerを表示するオプションがあるため、vim-easymotionから乗り換えました。

どちらも基本操作は似ているので、コンテキストスイッチの切り替えコストは低そうです。

せっかくなのでVim版の利用イメージを載せておきます。
※ 押したキー: sre;;; <C-o> sret

その他

VSCodeVimならではのショートカットキーがいくつかあります。
私が使っているのは以下の2つです。

  • af: 選択範囲拡張
  • gh: マウスカーソルでホバーしたときの情報を表示

選択範囲拡張は以下の様にラフな使い方ができます。
※ 押したキー: vafafafafaf

総括

VSCodeVimの設定見直しをして、VSCode環境が大きく改善しました。

Vimmerとして…VSCodeのファンとして… これからもVSCodeVimの進化を陰ながら応援させて頂きます🙇