Vimでマルチカーソルを使う方法と、標準機能だけで代用する方法
VSCodeなどで一般的な「複数箇所を同時に編集する」マルチカーソル機能は、Vim標準には存在しません。ただし、必要ならプラグインで追加できますし、Vimの標準機能だけで同じ結果に到達できる場面も多いです。両方を知っておくと、無闇にプラグインを増やさずに済みます。
目次(8項目)
プラグインで導入する
Vim/Neovim共通で使えるプラグインとしてはmg979/vim-visual-multiが広く使われています。
Plug 'mg979/vim-visual-multi'
Neovim専用であれば、Lua製のmultiple-cursors.nvimやmulticursor.nvimもあり、ノーマル・挿入・ビジュアルモードを問わず多くのコマンドと組み合わせて動く設計になっています。基本的な操作感は共通していて、次のような流れになります。
Ctrl-n " カーソル下の単語を選択し、マルチカーソルを開始
Ctrl-n " (繰り返し押すと)次に一致する単語も対象に追加
c " 選択した全箇所を対象に変更モードへ
Esc " 通常モードに戻る
vim-visual-multi(Vim/Neovim共通)か、Neovim専用のLua製プラグインを選びます。標準機能だけで代用できる場面
Vimmerの間では「マルチカーソルは本当に必要か」という意見も根強くあります。多くのユースケースは、次の標準機能で代用できるからです。
| やりたいこと | 代用手段 |
|---|---|
| 特定の単語を全て一括変更 | :%s/foo/bar/g |
| 複数行の同じ位置に文字を挿入 | ビジュアルブロックモード(Ctrl-v)+I/A |
| 次の一致箇所を1つずつ確認しながら変更 | *で検索してからcgn+.(ドットコマンド)で繰り返し |
ビジュアルブロックモードで複数行の同じ列に文字を足す例です。各行の先頭にコメント記号を挿入するような場面で使えます。
foo(); bar(); baz();
// foo(); // bar(); // baz();
特にcgn+.の組み合わせは、マルチカーソルの「複数箇所を確認しながら1つずつ変更する」感覚に近く、プラグインなしで同等のことができます。この方法は別記事で詳しく扱っています。
使い分けの目安
置換パターンが単純(同じ文字列を同じ文字列に変える)なら:%s///gで一発。行が異なるだけの整形(各行の同じ列に文字を足す)ならビジュアルブロックモード。1つずつ目視確認しながら不規則に変更したいならcgnとドットコマンドの組み合わせ。ここまでで足りないと感じたときに初めてマルチカーソルプラグインを検討する、という順番がプラグインを増やしすぎない考え方になります。
マルチカーソルプラグインを一時期入れていましたが、実際に使う場面を振り返ると9割方は:%s///gかcgn+ドットコマンドで済んでいました。VSCodeから移ってきた直後は恋しく感じますが、Vimの標準機能に慣れるとプラグインを入れる優先度は下がっていくというのが率直な感想です。
代用する手を選ぶ順番
3つの標準機能はどれでも似たことができるので、迷ったら次の順で当てはめると決まります。まず、置き換える前と後が全部同じなら :%s です。範囲を絞りたいならビジュアルモードで選んでから : を押します。
次に、直したい箇所と直したくない箇所が混ざっているなら cgn と . です。1か所目を書き換えたあと、飛ばしたい箇所では n、直したい箇所では . を押します。目で見て判断できるので、置換の巻き込み事故が起きません。
最後に、桁が揃っている複数行の同じ位置に手を入れるなら矩形選択です。この3つで大半は片づき、それでも足りないと感じた時点でプラグインを検討する、という順番なら無駄が出ません。
プラグインを入れたときにつまずくところ
マルチカーソル系のプラグインは多くのキーを奪います。Ctrl-n や Ctrl-下矢印 のような割り当てが既定になっていることが多く、補完や既存のマッピングと衝突します。入れた直後に何かが動かなくなったら、まずここを疑ってください。
もう1つは規模です。数十か所にカーソルを置いた状態での編集は、1文字打つたびに全カーソル位置で処理が走ります。行数が増えるほど反応が鈍くなるので、大きな一括処理には結局 :%s や :g のほうが向きます。
NeovimならLSPのリネームという別解
変数名や関数名を変えたいだけなら、そもそも文字列として置き換える必要がありません。NeovimでLSPを設定していれば、識別子の上で grn を押すことで言語サーバーによるリネームができます。
この方法なら、コメントや文字列リテラルの中にある同じ綴りを巻き込みませんし、他のファイルにある参照もまとめて直ります。マルチカーソルや置換では届かない範囲なので、コードを触る場面ではこちらが第一候補になります。設定の仕方はNeovimのLSP設定にまとめています。
まとめ
マルチカーソルはプラグインで追加できますが、Vimの標準機能(置換・ビジュアルブロック・cgn+ドットコマンド)で代用できる場面が意外と多いです。まず標準機能で試し、本当に足りないと感じたときだけプラグインを検討するのが妥当な順番です。標準機能だけで代用する方向をもう少し詰めるなら、マクロと.の組み合わせが実質的な代替になります。複数箇所を同時に触るという発想を捨てて、「1箇所直して繰り返す」という形に置き換えるのがVimでの定石です。慣れると、対象が離れていても順に当てていけるぶんこちらのほうが確実に感じられます。