2019年7月12日金曜日

「行方向のマクロ」

概要

マクロの使い方について考えるうちに「行方向のマクロ」と「列方向のマクロ」という着想を得たので書き残しておく。

「行方向のマクロ」をうまく使えば、カーソル移動や例外的個所の追加編集をなくすことができ、ある種の問題をより少ないキーストロークで解決することができるようになる。



左が「列方向のマクロ」、右が「行方向のマクロ」である。
マクロの具体的な内容については千差万別であり、ここでは問題にしない。
注目するべきは、編集単位と方向である。

「列方向のマクロ」では、編集単位は行であり、列方向にマクロを繰り返し実行する。
一行目に行った編集をマクロに記録し、二行目、三行目というようにマクロを走らせるのである。
Vimのご先祖様のexエディタは行単位での編集を行うラインエディタであったことを考えると、「列方向のマクロ」は自然でとっつきやすいと思う。

「行方向のマクロ」では、編集を適切な単位で行い、行方向にマクロを繰り返し実行する。
最初に「a」の文字を編集し、うまく「b」にカーソルを移すまでをマクロに記録する。
その後、二文字目、三文字目、といったように最後の文字までマクロを走らせるのである。
適切な編集の単位というのが曲者で、ワード系の移動も、改行を経た次行への移動も、同じコマンドで行えなければならない。
モーションコマンドの特性をしっかり認識し、適切なモーションコマンドを合成することが必要である。

具体例

今回は以下の二つの問題について見ていく。

abcde
fghij
klmno
pqrst
uvwxyz
上のファイルを以下のように編集せよ。
a   b   c   d   e
f   g   h   i   j
k   l   m   n   o
p   q   r   s   t
u   v   w   x   y   z


まずは、私が頭をひねって出した回答を見てもらおう。
矩形選択を用いた列単位のアプローチをとっている。
<C-V>LA   <Esc>w.w.w.}i<C-@>ZZ
  1. <C-V>LA   <Esc>
    一列目を選択し、矩形選択領域の後ろに3つのスペースを挿入し、ノーマルモードに戻る。
  2. w.
    次の列に移動し、先と同様の処理を施す。
    これは3回実行する。
  3. }
    zのところまで移動する。
  4. i<C-@>
    インサートモードに入り、最後にインサートモードで挿入した文字(3つのスペース)を挿入してからノーマルモードに戻る(:help i_CTRL-@)。

これで18キーストローク。
出っ張っているZのために、最後に余分な2ストロークが必要になってしまう。

一方で、「行方向のマクロ」を用いた回答を紹介する。
qqeb3a <Esc>wq25@qZZ
  1. qq
    マクロ記録の開始。
  2. eb
    この問題では、"e" は以下のようなモーションを与える
    ①カーソルが行の最後の文字以外にある場合、カーソルはその行の最後まで移動する
    ②カーソルが行の最後の文字にある場合、カーソルは次の行の最後まで移動する。

    "b" は "e" とは違い、カーソルが行の先頭にある場合でもその行にとどまる。

    よって、"eb" は適切な編集単位の移動を与える合成モーションコマンドのようなものとして機能している。
  3. 3a <Esc>w
    スペースを3つ挿入し、ノーマルモードに戻る。
    カーソルが3つ目のスペースにあるので、一つ右方向へカーソルを移す。
  4. q
    マクロ記録の停止。
  5. 25@q
    25回、行方向にマクロを実行する。
  6. ZZ
    ファイルを保存し終了する。

これで16ストローク。
矩形選択の例でzのために生じていた余分な2ストロークが、見事に消え去っている

ちなみに、この問題には現在15ストロークの回答が示されている。
気になる方は、自分の目で確かめてくれ!


,0,1,2,3,4,5,6,7,89
,1,2,3,4,5,6,7,8,90
,2,3,4,5,6,7,8,9,01
,3,4,5,6,7,8,9,0,12
,4,5,6,7,8,9,0,1,23
56,7,8,9,0,1,2,3,4,
67,8,9,0,1,2,3,4,5,
78,9,0,1,2,3,4,5,6,
89,0,1,2,3,4,5,6,7,
90,1,2,3,4,5,6,7,8,
上のファイルを以下のように編集せよ。
0,1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8,9,0
2,3,4,5,6,7,8,9,0,1
3,4,5,6,7,8,9,0,1,2
4,5,6,7,8,9,0,1,2,3
5,6,7,8,9,0,1,2,3,4
6,7,8,9,0,1,2,3,4,5
7,8,9,0,1,2,3,4,5,6
8,9,0,1,2,3,4,5,6,7
9,0,1,2,3,4,5,6,7,8

まずは、矩形選択を用いたアプローチがとられた回答を見てみよう。
<C-V>Mx6$.0pH$PZZ
  1. <C-V>Mx
    矩形選択で、上5行の先頭のカンマを削除する。
  2. 6$.
    六行目の末尾まで移動し、同様に下5行の末尾のカンマを削除する。
  3. 0p
    (六行目の)先頭まで移動し、5行分のカンマを挿入する。
  4. H$P
    一行目の末尾まで移動し、5行分のカンマを挿入する。
  5. ZZ
    ファイルを保存して終了する。

これで13キーストローク。
パッと見で、上半分と下半分でカンマのパターンが違うので、それに合わせてカーソルを行ったり来たりしている。

一方で、「行方向のマクロ」を用いた回答を紹介する。
qqxpeq98@qZZ

  1. qq
    マクロ記録の開始。
  2. xpe
    カンマを削除し、数字1文字の後ろに挿入する。

    この問題では、"e" は以下のようなモーションを与える
    ①カーソルが ",," の一つ目のカンマにある場合、カーソルは二つ目のカンマまで移動する
    ②カーソルが最後の文字にある場合、カーソルは次の行の最後まで移動する。

    実際に動かしてみるとわかるが、"xpe" が適切な編集単位を与える合成コマンドになっているのである!
  3. q
    マクロ記録の停止。
  4. 98@q
    98回、行方向にマクロを実行する。
  5. ZZ
    ファイルを保存し終了する。


これで12キーストローク。
「行方向のマクロ」のアプローチをとることで、編集時の「方向転換」(イメージ的に伝わってくれ!)をさっぱりなくした、目から鱗の回答である。

まとめ

  1. マクロを「行方向のマクロ」と「列方向のマクロ」に分類してみた
    1. 「列方向のマクロ」では、編集単位は行であり、列方向にマクロを繰り返し実行する。
    2. 「行方向のマクロ」では、編集を適切な単位で行い、行方向にマクロを繰り返し実行する。
  2. 「行方向のマクロ」をうまく利用することで、編集時の例外的な編集個所や方向転換をしなくてすみ、キーストロークを減らせる可能性がある

0 件のコメント:

コメントを投稿

コメント表示は承認制に設定しています