0

この基本的な形式のファイルがあります。

>> (N0) "string X0"
...
>> (N1) "string X1"
...
<< (N1+2) "string X1"
...
<< (N0+2) "string X0"

ご覧のとおり、ネストされた構造です。数値 N0、N1、N* の周りに括弧はありません。これらはどんな深さでも入れ子にすることができます。文字列は引用符で囲まれていますが、番号が付けられておらず、まったく同じです。また、ネストされた文字列は、外側の文字列と同じにすることができます。

データを分析しやすくするために、これらのネストされたすべてのアイテムをインデントするマクロを作成するつもりでしたが、N + 2 を検索する方法がわかりません。

vim でできない場合は、perl スクリプトを作成する必要があると思いますが、vim で実行できるかどうか疑問に思っていました。

入力と出力のより具体的な例をここに追加しましたが、このデータセットはもはや重要ではありません。2 ずつインクリメントされた見つかった数値の次の出現を見つける方法を見つけることにもっと興味があります。

>>5「ふー」
...
>> 2「バー」
...
<< 4 "バー"
...
<< 7 "ふー"
>>5「ふー」
  ...
  >> 2「バー」
   ...
  << 4 "バー"
  ...
<< 7 "ふー"

5つまり、基本的には、数字を見つけて、次の5+2、つまりを見つけたいと考えています7。その後、その間の行をインデントすることができます。

何か案は?ありがとう。

4

1 に答える 1

2

あなたの例から、あなたの>><<がペアになっていることに気付きました。したがって、各ペアで、

closing number = starting number +2

番号を確認していなかっただけです。でインデントを計算するだけ<< and >>で、ニーズを満たすかどうかを確認できます。

最初にこの関数をソースします。

fun! GetIndent(line_num)

    let lnum = a:line_num
    if lnum == 0
        return 0
    endif
    let sp = '^\s*>> \d'
    let ep = '^\s*<< \d'
    let l = getline(a:line_num)
    if l =~ sp    
        while lnum > 0
            let lnum = prevnonblank(lnum-1)
            if getline(lnum) =~ sp
                return indent(lnum)+&tabstop
                break
            endif
        endwhile    
    endif

    if l =~ ep
        while lnum > 0
            let lnum = prevnonblank(lnum-1)
            if getline(lnum) =~ sp
                return indent(lnum) 
                break
            endif

            if getline(lnum) =~ ep
                return indent(lnum) -&tabstop
                break
            endif
        endwhile    
    endif
    return indent(a:line_num - 1)
endf

次に、ファイルのバッファで次を実行します。

:setlocal indentexpr=GetIndent(v:lnum)

gg=Gこれで、テキストの書式設定に使用できます。例えば:

これ

>> 1 "foo"
...
>> 2 "bar"
...
>> 3 "bar"
...
>> 4 "bar"
...
>> 5 "bar"
...
>> 6 "bar"
...
<< 6 "bar"
...
<< 5 "bar"
...
<< 4 "bar"
...
<< 3 "bar"
...
<< 2 "bar"
...
<< 1 "foo"

gg=Gは次のようになります。

>> 1 "foo"
...
    >> 2 "bar"
    ...
        >> 3 "bar"
        ...
            >> 4 "bar"
            ...
                >> 5 "bar"
                ...
                    >> 6 "bar"
                    ...
                    << 6 "bar"
                    ...
                << 5 "bar"
                ...
            << 4 "bar"
            ...
        << 3 "bar"
        ...
    << 2 "bar"
    ...
<< 1 "foo"  

私が言ったように、私はあなたのテキストの番号をチェックしませんでした. インデントを明確に示すためだけに、開始ペアと終了ペアの両方に番号 1 ~ 6 を使用しました。かもしれません1-3, 2-4, 3-5 ...。私の関数があなたが望むことをしない場合、number+2 をチェックする必要があります。一致した行から番号を抽出してチェックすることができます。私の機能から始めましょう。

幸運を!

正規表現は、数学計算を行う正しい方法ではありません。基本的に言えば、正規表現(単独)ではできません。– ケント 5 月 6 日 9:29

于 2013-04-30T21:58:43.463 に答える