https://vi.stackexchange.com/a/818/227での回答と同様に、グローバルコマンドを使用できます。
これを使用すると、パターンに一致する行を検索し、そのコマンドを実行するようにvimに指示できます。
あなたのケースでは、「レベルN:」で始まる行にテキストを付加したいので、グローバルコマンドは次のようになります。
:g/^Level \d:/{COMMANDS}
コマンドの代替コマンド(正規表現置換)の使用
コマンドはもっと楽しいです。変数は使いやすいので、私は通常、このようなものの正規表現の置換を行うのが好きです。
あなたの質問の例
:let i = 1 | g/^Level \d:/s/^/\=printf("%02d ", i)/ | let i = i+1
使い方
置換コマンドの置換セクションでは、式を使用できます。
最初に、変数i
を開始番号に設定します。1を選択しましたが、いくつでもかまいません。let i = 1
次に、一致した行でアクションを実行するように設定するグローバルコマンドを実行します。 g/^Level \d:/
グローバルコマンドで値を挿入し、substitutionコマンドとletコマンドを使用してカウンターをインクリメントします。 s/^/\=printf("%02d ", i)/ | let i = i+1
置換コマンドの正規表現は、行の先頭を見つけて^
それを式に置き換えます。この式は、フォーマットされた印刷の結果になります。C言語と同様に、vimのprintfはフォーマットパラメータを受け取ります。%02d
は、引数を10進数のように変換し、d
少なくとも2つのスペース2
を使用し、0を埋め込むことを意味します0
。詳細およびその他の変換オプション(浮動小数点フォーマットを含む)については、を参照してください:help printf
。printfにカウント変数i
を渡し01
、1回目、02
2回目などを与えます。これは、置換コマンドで使用されて、行の先頭を置き換え、printfの結果を先頭に効果的に挿入します。
d:の後にスペースを置いていることに注意してください"%02d "
。あなたは質問でそれを要求しませんでした(そして私は出力例を見ませんでした)が、私はあなたが「レベル」という単語から数を分離したいと思ったのではないかと思いました。レベルのLのすぐ隣に数値を挿入するには、printfに指定された文字列からスペースを削除します。
最後に、それはlet i = i + 1
各置換の後にカウンターをインクリメントします。
これは一般に、他の基準と一致する行の一部を任意の機能データで置き換える場合に適用できます。
通常のコマンドを組み合わせて使用する
これは、単純な挿入や複雑な編集に適しています。置換の場合と同様に、マッチングにはグローバルを使用しますが、正規表現の代わりに、ユーザーが入力したかのように一連の操作を実行します。
あなたの質問の例
:let i = 1 | g/^Level \d:/execute "normal! I" . printf("%02d ", i) | let i = i+1
使い方
使用される値は置換に非常に似ています(私たちはまだprintfを使用して、2桁で0が埋め込まれるように数値をフォーマットしています)が、操作は異なります。
ここでは、文字列を受け取り、exコマンド(:help :exe
)として文字列を実行する実行コマンドを使用します。「normal!I」とデータを組み合わせた文字列を作成します。最初は「normal!I01」、2回目は「normal!I02」となります。
このnormal
コマンドは、通常モードと同じように操作を実行します。この例では、通常のコマンドはI
で、行の先頭に挿入されます。使用dd
した場合、行を削除しo
、一致した行の後に新しい行を開きます。これはI
、通常モードで自分で入力した(または他の操作を行った)場合と同じです。!
after を使用して、normal
マッピングが邪魔にならないようにします。を参照してください:help :normal
。
次に挿入されるのは、代用を使用する最初の例と同様に、printfの値です。
execute "normal! ^2wy" . i . "th$p"
テキストの先頭に^
移動し、2ワード前に移動し2w
、i番目の 'h'文字までヤンクしy" . i . "th
、行の最後に移動し$
、を貼り付けることができるため、この方法は正規表現よりも洗練されている場合がありますp
。
これは、マクロの実行とほとんど同じですが、実際にはレジスターを使い果たしておらず、任意の式の文字列を組み合わせることができます。これは非常に強力だと思います。
各レベルに独自のカウンターがあるアプローチ
各レベルで独自のカウンターを取得する必要がある場合があります。事前にレベルの最大数がわかっている場合は、次の操作を実行できます(最大レベルを見つけるために追加のコードを追加することはそれほど難しくはないかもしれませんが、この回答は長くなりすぎます。これは実際に長くなっています)。
まず、すでに整数として使用している場合に備えて、iを解放します。iをリストに変換することはできません。そのように作成する必要があります。
:unlet! i
次に、レベル数を含むリストをiに設定します。あなたはあなたの質問に2を示しましたが、それを楽しむために10と仮定しましょう。リストのインデックス付けは0ベースであり、リストのように1ベースを修正する手間をかけたくないので、十分な数の要素(11)を作成し、0インデックスは使用しません。
:let j = 0
:let i = []
:while j < 11 | let i += [1] | let j += 1 | endwhile
次に、レベル番号を取得する方法が必要です。幸いなことに、関数としても代替を使用できるので、それに行を追加してレベル番号を抽出しますsubstitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")
これでiは11 1
のリストになっているため(各インデックスはレベルのカウンターです)、上記の例のいずれかを調整して、この置換の結果を使用できます。
代替コマンドを使用:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | s/^/\=printf("%02d ", i[ind])/ | let i[ind] += 1
通常のコマンドで:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | execute "normal! I" . printf("%02d ", i[ind]) | let i[ind] += 1
入力例:
Level 1: stuff
Level 1: Stuff
Some text
Level 3: Other
Level 1: Meh
Level 2: More
出力例:
01 Level 1: stuff
02 Level 1: Stuff
Some text
01 Level 3: Other
03 Level 1: Meh
01 Level 2: More