特定の構文領域でパターンを検索する方法は?


10

ラテックスドキュメントの編集にvimを使用しています。変数の名前を別の名前に変更したいことがよくあります。ただし、変数名を検索するときに無関係な一致を調べなければならないのは少し面倒です。tex構文ファイルで定義されている「数学ゾーン」のみを検索したいのですが。検索を特定の構文領域に制限する簡単な方法はありますか?


1
答えはノーだと思います。特定の構文領域に検索を制限する簡単な方法はありません。
Karl YngveLervåg15年

2
このマッピングsynIDattr()、カーソルの下の文字の構文グループを取得するために使用します。検索を実行する(またはを実行する)関数を記述して、この場所に留まるか、前方に検索を続けるかを決定するためにnormal n使用synIDattr()できます。
joeytwiddle 2015

@joeytwiddleそのような関数で回答を投稿した直後にあなたのコメントを見ました。それはあなたが考えていたもののようですか?
jjaderberg、2015

@jjaderbergはい、そうです。よくやった!
joeytwiddle

完全を
期す

回答:


4

ここにあなたが試すことができる関数があります。少しだけテストしましたが、問題なく動作するようです。

function! JJSyntaxSearch(pattern, syntaxitem)
  while search(a:pattern, 'W') > 0
    for id in synstack(line("."),col("."))
      if synIDattr(id,"name") =~? a:syntaxitem
        return line(".")
      endif
    endfor
  endwhile
  return 0
endfunc

command! -nargs=* JJSyntaxSearch call JJSyntaxSearch(<f-args>)

この関数は、特定の構文項目に対する「修飾された」一致でもある「通常の」一致が見つかるまで、またはバッファの最後に到達するまで、ループでVimの検索関数を呼び出します。

2つの引数を取ります。1つ目は検索パターンで、変更せずにVimのsearch()関数に渡されます。:help search()その機能のしくみについては、を参照してください。2番目の引数は、これらの一致をフィルタリングする構文アイテムの名前です。これはパターンにすることもでき、大文字と小文字を区別しない正規表現として比較されます。

あなたができる数学ゾーンでパターン「アルファ」を見つけるために

:JJSyntaxSearch alpha texMathZone.

.最後には、任意の単一文字を参照するためのパターン原子です:help /.。これはtexMathZoneAtexMathZoneBなどと呼ばれる多くの数学ゾーン構文項目があるためです。

このsearch()関数は、カーソルを次の「通常の」一致に移動します。次に、関数はを使用して、その新しいカーソル位置のすべての構文アイテムIDを取得しますsynstack()。それらをループして、各項目の名前を順番に取得し、syntaxitem引数に対してテストします。:help synstack()およびを参照してください:help synIDattr()。「修飾された」一致がある場合は、行番号を返します。「修飾された」一致が見つからないままバッファの最後に到達すると、が返されます0。関数のポイントは、カーソルを次の「修飾された」一致に移動して、そこでいくつかの操作を実行できるようにすることですが、「行番号または0」を返し、関数を再度呼び出すことが意味があるかどうかを示すと便利です。別の関数またはマクロから関数を繰り返し呼び出したい場合のインスタンス。

Wフラグを使用することを選択したのsearch()は、バッファの終わりを「折り返す」のを防ぐためです。そうしないと、同じ「通常の」一致は検出されますが、「修飾された」一致は検出されないため、関数がスタックする場合があります。


ご協力いただきありがとうございます!私はまだこの機能を試していませんが、私が欲しかったように見えます。
Rob F.


1

「数学ゾーン」が何らかの構文パターン、たとえば「math」という文字列で修飾されている場合、少なくともパターンシーケンスを使用して、次のように一致するパターンを持つ行を見つけることができます。

:/math//your pattern/

(注:2つのパターンは異なる行にある場合があります!)

これは、一致をゾーンに限定しない場合があります-ゾーンの終了を識別する必要があるため-ただし、最初のパターン/ math /の後に一致のみを表示します。ex-mode履歴(: up-arrow enter)を使用して、次の出現の検索を繰り返すことができます。


注:ISTRは、以前のvim / viバージョン/math//your pattern/ではnN入力コマンドとand コマンドの使用が少ないという利点があるため、(ex-modeコマンドではなく)そのメソッドを検索コマンドとして直接使用することもできましたが、確認できません私の現在のvimバージョンのそれ。


1

またはfoo内で文字列を検索している$...$場合$$...$$、これは機能するはずです。

\$.*\zsfoo

これは一致を$文字に固定しますが、文字列のみを選択しますfoo

これは本当に簡単な解決策ではありませんが、:global+ :substituteを使用して「数学ゾーン」を見つけ、その内部を検索することができます。

:global /\v\\begin\{%(align|alignat|displaymath)\}/ +1,/\\end/-1 s/foo/&/gc

:substitute検索コマンドのふりをして、次の出現に移動してnで終了できますq。誤って差し替えを確認しても問題ありません。

あなたはリストの内部を設定する必要があります%(... )あなたが使用して数学の環境の名前に(完全なリストは少し多額のですalign|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat)。ここでは非常に魔法の(\v)パターンを使用していることに注意してください。

説明:

:globalExコマンドを実行する(:s)は、各ラインパターンマッチ(上:help :global
/\v非常にマジックパターン(開始:h /:h pattern:h magic
\\begin\{リテラル一致\begin{
%(align|alignat|displaymath)(任意のこれらの単語の一致を:h /\%(:h /bar
\}/リテラルと一致する}パターンを終了します。

+1,/\\end/-1次の行(によって検出さ:globalれた行から数えます)から、検索パターンによって検出された行の前の行までの範囲/\\end。その範囲内で

s/foo/&/gcfoo確認後、リテラルのすべての出現箇所をそれ自体で検索および置換します(:h :substitute


これは確かに始まりですが、私は方程式、整列、IEEEeqnarray環境を頻繁に使用しており、検索からそれらを除外したくありません。
ロブF.

@RobF .:さまざまな環境内で一致させることはかなり可能ですが、1つのスクリプトで記述しない限り、簡単ではありません。ただし、\mathit変数名の周りで一貫して使用すると、それらを見つけるのがはるかに簡単になります。
Peter Lewerin、2015

0

ファイル内で「morning」という文字列を検索している場合 /morningenter、押しnて前方に移動します


1
質問はI would like to search only in "math zones"あなたの方法が研究ゾーンを区切らないファイル全体を検索することを言いました。
スタトックス

0

これ専用の関数を書く以外に選択肢はありません。必要な文字列を検索し、次のいずれかの場合にのみ停止する関数を作成しました。

  1. マッチがなくなる
  2. 数学環境内にある一致があります(一致すると停止します)

検索する文字列を指定して呼び出すだけです。

function! Finmath(nextstr)
    while 1
        if search(a:nextstr)==0
            break
        endif
        if searchpairpos('\(', '','\)','n')!=[0,0]
            break
        endif
        if searchpairpos('\[', '','\]','n')!=[0,0]
            break
        endif
        let a = getcurpos() 
        if count(strpart(getline('.'),0,a[2]),'$')%2==1
            break
        endif 
    endwhile 
endfunction

数学以外の文法エラーでのみ停止する、GrammerousCheckの同様の関数を作成するつもりです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.