Vim advent calendar 2024(Adventar) 5 日目の記事です。参加者募集中 & Vim に関係していれば何でも OK とのことでした。
Vim じゃない Vim たち
Vim/NeoVim 以外の Vim のエミュレーションを使うと、生の Vim とはちょっと違う挙動が見れて面白いことがあります。一例を紹介します。
お題: 複数行編集
以下のテキスト編集を実施してください。各行の行頭・行末を両方編集する必要があります。
A
BB
CCC
DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
以下では 5 通りの編集方法を紹介します。
僕が好みは方法 3. ドットリピートです。
方法 1: マクロ
マクロは、一連のキー操作を記録し、繰り返し実行できる機能です。この記事を見つけるような人は、マクロにも親しんでいると思いますから、結果のみ紹介します。
A
BB
CCC
DDDD
* A :tag:
BB
CCC
DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
とても良いですが、マクロの記録開始・終了と呼び出し操作がちょっと手間だと思います。
方法 2: Dmacro (Evil, Vim)
dmacro は直近の操作履歴をマクロのように利用できる機能です。レコードしなくて良いマクロ! Evil から利用してみます。
A
BB
CCC
DDDD
* A :tag:
BB
CCC
DDDD
* A :tag:
*BB
CCC
DDDD
* A :tag:
* BB :tag:
CCC
DDDD
* A :tag:
* BB :tag:
* CCC :tag
* DDDD :tag:
魔術的ですね。ぜひ道具箱に追加してください。
Vimmer は tani/dmacro.vim で dmacro
が使えるそうです。 Vim でキー操作を監視するのは相当大変そうで、 tani さん凄過ぎでした。 Dmacro の存在自体、 tani さんから知りました。
方法 3: ドットリピート (Evil)
これはVim にはできないと思います。 本家 Vim 詳しくないため不正確です が、 Vim だと改行がドットリピートの対象になりません。ところが Evil ではドットリピートでカーソル移動まで繰り返しできます。
A
BB
CCC
DDDD
* A :tag:
BB
CCC
DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
Evil や VSCode のドットリピートはマクロっぽいと言えます。僕はこちらの振る舞いが好きで気に入っています。 この動作は Vim でも可能ですか? 情報募集中です。
方法 4: 複数行 insert を 2 回行う
Visual-line モードからの insert を 2 回実施します。ちょっと面倒くさいと思います。
A
BB
CCC
DDDD
* A
* BB
* CCC
* DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
方法 5: 複数行 insert を 1 度のみ行う (Evil, VSCodeVim)
Evil では C-a
や C-e
で normal モードへ戻らずにカーソルをジャンプさせることができます。これがリピートの対象となるため、複数行に対し行頭・行末の編集を一括で実施できます。
A
BB
CCC
DDDD
* A :tag:
BB
CCC
DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
VSCodeVim では複数行編集がマルチカーソルになり、これも一括処理が上手く行きます。
A
BB
CCC
DDDD
* A
* BB
* CCC
* DDDD
* A :tag:
* BB :tag:
* CCC :tag:
* DDDD :tag:
その他の方法
置換を使うなど、様々な方法がありそうです。やきもきしている方、よければコメントでご共有ください >_<
おまけ: 複数行編集 (改行を含む)
次のテキスト編集を実施してください。
A
BB
CCC
DDDD
* A :tag:
xxxx
* BB :tag:
xxxx
* CCC :tag:
xxxx
* DDDD :tag:
xxxx
今度は行毎に改行も追加したいということです。
方法 1: マクロ
マクロならできますね。
方法 2: Dmacro
Dmacro でもできます。
方法 3: ドットリピート (Evil)
Evil ならドットリピートできます。
方法 4: 複数行 insert を 1 度のみ行う (VSCodeVim)
Evil なら……できません。繰り返し適用の位置が (line, column) 値で記録され、改行すると位置の対応がズレるためです。
* A :tag:
* xxxx :tag:
* xxxx :tag:
* xxxx :tag:
xxxx
BB
CCC
DDDD
中身をハックできる人なら、わりと簡単に改良できそうです。やっぱり Evil 良くないですか?
VSCodeVim なら、複数行編集がデフォルトでマルチカーソルですから、問題なく実施できます。
まとめ
- Dmacro を導入してみましょう。
- Evil のドットリピートがマクロっぽくて好きです。
- VSCodeVim で複数行 insert がマルチカーソルなのは意外と良いです。マルチカーソルのプラグインを試してみるのもありかと思います。