1

これは、 Vim での複数行の正規表現の使用に関する私の質問へのフォローアップです。

簡単な説明: でタグ付け#tagsされ、空白行で区切られたテキスト ブロックがあります。特定のタグを含むすべてのブロックを除外したい。ここで正規表現を手伝ってくれたので (ありがとう!)、次のコマンドを作成しました。

command -nargs=1 TagSearch g/^\(.\+\n\)\{-}.*#<args>.*/y a | vnew | put a | %s/^#.*<args>.*\n/&\r 

したがって、次のことを行う:TagSearch tag必要があります。

  1. を検索し#tagます。
  2. 対応するすべてのテキスト ブロックを新しい垂直バッファーに貼り付けます。
  3. 新しいバッファのテキスト ブロックの間に空白行を追加します。

Q1 : 各ステップを個別に実行すると、すべてが機能します。ただし、マルチコマンドは、最初に一致したテキスト ブロックのみを新しいバッファーに貼り付けます。なんで?

Q2 : コマンドが複数の引数を受け入れるようにするにはどうすればよいですか (複数を一度に検索したい場合#tags)? ありがとう!

4

2 に答える 2

1

私はこれで古き良き遊びをして、その過程でかなりのことを学びました! ここでいくつかの問題が発生しているようです。

これが私がそれを機能させるためにどのように取り組んだかですが、vimには非常に多くのアプローチがあるため、おそらくもっときちんとした方法があるでしょう.

g コマンドの形式は g/pattern/command です。起こっていたと思うのは、あなたの元の形、| 新しい | | を入れて %s... コマンドの一部が、TagSearch コマンドの一部として 1 回ではなく、g コマンドで行ごとに実行されていました。問題を解決する代わりに、g コマンドを「実行」するように変更しました。例えば)。これが、最初の行しか得られなかった理由です。これにより、次のようになります (「%s」コマンドのタイプミスを修正します):

command! -nargs=1 TagSearch execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y a' | vnew | put a | %s/^.*#<args>.*\n/&\r

しかし、これは問題を逆転させたようで、新しいバッファの最後の行しか得られません。g コマンドのもう 1 つの問題は、/ya を実行すると、毎回 a レジスタが上書きされることです。代わりに、大文字のレジスタ名 (/y A) を使用して vim をレジスタに追加する方法があります (:help quotea を参照)。このようにするには、最初に let を使用してレジスタを空白に初期化する必要があります。これにより、次のようになります。

command! -nargs=1 TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#<args>.*/y A' | vnew | put a | %s/^.*#<args>.*\n/&\r

最後に、複数のタグで実行できるようにするために<args>、少しいじって (TagSearch tag1 tag2 を呼び出すと、args は文字通り文字列 'tag1 tag2' になります)、次のように正規表現に収まるようにしました。

command! -nargs=* TagSearch let @a='' | execute 'g/^\(.\+\n\)\{-}.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*/y A' | vnew | put a | execute '%s/^.*#\(' . substitute('<args>', ' ', '\\|', 'g') . '\).*\n/&\r'

これにさらに機能を追加する場合は、代わりに小さな vimscript 関数などで遊んでみることをお勧めします。そうしないと、保守がかなり難しくなる可能性があります。テキスト ブロックを素敵なリストにまとめて、実際に入力しているかのようにすべてを行うよりも、もう少し簡単に処理できる可能性があります。利用可能なものについては、:help 関数を参照してください (ただし、他の場所の vimscript のヘルプに、より適切な出発点があるかもしれません)。

于 2012-05-15T09:12:57.380 に答える
1

次の実装を使用できます。

command! -nargs=* -bar TagSearch call CollectParagraphs([<f-args>])

function! CollectParagraphs(tags) range
    let tags = len(a:tags) > 0 ? a:tags : [expand('<cword>')]
    let pats = map(copy(tags), '"\\.\\*#" . escape(v:val, "\\")')

    let v = winsaveview()
    let [sr, @/; lines] = [@/, '\V' . join(pats, '\&')]
    g//call extend(lines, getline(search('\n\n\zs', 'bnW'), line("'}")))
    let @/ = sr
    call winrestview(v)

    exe 'vnew' escape(join(tags), ' %#|\')
    set buftype=nofile bufhidden=hide noswapfile
    call setline(1, lines)
endfunction
于 2012-05-15T11:43:55.687 に答える