Vimのマクロで複雑な繰り返し作業を自動化する
同じ形の修正を10行、20行と繰り返す作業は、手打ちだとミスも増えますし飽きます。.コマンドでは対応できない複数ステップの操作は、マクロに記録してしまうのが早いです。
| キー | これだけ覚える |
|---|---|
| qa 〜 q | レジスタaへ操作を記録 |
| @a | 記録した操作を実行 |
| 10@a | 10回まとめて実行 |
| @@ | 直前に実行したマクロをもう一度 |
記録・実行・確認の基本
qa " レジスタaへの記録を開始
... " 記録したい操作
q " 記録終了
@a " レジスタaの内容を実行
10@a " 10回実行
@@ " 直前に実行したマクロをもう一度
記録中は画面の隅に「記録中」の表示が出ます。記録した内容はレジスタとして保存されているので、:registers(省略形:reg)で中身を確認できます。マクロの正体は「名前付きレジスタに記録したキー入力を、あとから再生する」仕組みにすぎません。
マクロを編集する
記録し損ねた1手を直したいときは、いちいち録り直さなくても中身を直接編集できます。
"ap " レジスタaの内容をバッファに貼り付け
(貼り付けた内容を編集)
"ay " 編集後の内容をレジスタaへ再格納(ビジュアル選択してヤンク)
貼り付け、編集、選択してヤンクし直す、という3ステップでマクロの中身を書き換えられます。録り直すより早いことが多いです。
実行開始位置に依存させない
マクロを複数行に適用するとき、想定と違う位置で崩れることがあります。原因の多くは「カーソルが特定の位置にある前提」で記録してしまっていることです。マクロの先頭で行頭や行末に移動する操作を入れておくと、多少カーソル位置がずれていても安定して動きます。
よく使う具体例
行末にセミコロンを追加して次の行へ移動するマクロは、コードの整形でよく使います。Aで行末からインサートモードに入り、;を打って<Esc>でノーマルモードに戻り、jで次の行へ移動します。
let a = 1
let b = 2
let c = 3
2@a
let a = 1; let b = 2; let c = 3;
これをqa〜qで記録しておけば、対象の行数だけN@aで一気に処理できます。
複数ファイルへまとめて適用する
記録したマクロは1つのファイルだけでなく、開いている複数のファイルに一気に適用することもできます。:bufdoと組み合わせれば、同じ修正をファイル横断でまとめて実行できます。
:bufdo normal! @a
この場合はファイルごとにカーソル位置が異なるため、マクロの先頭で行頭移動などを入れて開始位置に依存しない記録にしておく重要性がさらに増します。windo/bufdo/tabdoそのものの使い分けは別記事にまとめています。
最初は記録に失敗するたびに録り直していましたが、レジスタの中身を直接編集できると知ってからは無駄なやり直しがかなり減りました。特にマクロの途中に1手足したいだけのときに、毎回最初から録り直すのは時間の無駄だったと今は感じます。
まとめ
マクロは複数ステップの操作を繰り返すための機能で、実体はレジスタへのキー入力の記録です。編集も応用もレジスタの仕組みを理解していれば難しくありません。まずは行末への文字追加のような単純な作業から試すと感覚をつかみやすいです。1回だけの単純な繰り返しなら、マクロを組むより.のほうが手軽です。記録した内容はレジスタに入るので、名前付きレジスタの扱いを知っておくと保存や使い回しがしやすくなります。