2011-12-30 5 views
2

このファイルの現在のファイル名を使用して検索したいと思います。私はすでに:call expand("%:p:h")を使って現在のファイル名を知っています。だから私は/call expand("%:p:h")のようないくつかのコマンドを使用して検索したいと思います。私はこれを試しましたが失敗しました。なぜなら、vimはこの関数呼び出しを文字通り解析するからです。現在のファイル名は、Vimのパターン構文に起因する をエスケープする必要があるシンボルが含まれていない場合は関数から返された値を使用して検索する方法

答えて

1

、いくつかの関数によって返される値は、コマンドライン(または単に挿入モードで)に挿入するには、次を使用する必要があります。

はCtrl + R= function_name()

ところで、expand("%:p:h")は現在のファイル名を返しますが、これは間違っています:実際には現在のファイルへのフルパスを返しますtファイル名。パスのないファイル名を取得するには、expand("%:t")を使用してください。詳細は:help expandをお読みください。

EDITED:これは安全な方法である:あなたのケースでは、あなたが示唆@ib@/を登録検索とソリューションを使用することができます。しかし、バッファにファイル名が見つかるだけで、ファイル名に特殊文字が含まれていない場合は、代わりにCtrl + R=を使用します。

だから、式全体が現在のファイル名を検索するには、次のとおりです。

/\VはCtrl + R=expand('%:t')

P.S.を入力してください

\Vは、「very nomagic」モードを意味します。 :help \V

+1

検索パターンを入力するときに式レジスタを使用するのが便利なオプションですが、結果は同じではありません。対話的にパス名を挿入するので、エスケープ(expand( '%')、 '\') 'でバックスラッシュシーケンスをエスケープしても(他の落とし穴は「非常にノーマジック」モードでキャンセルされます。検索を開始する文字( '/'または '?')をエスケープする必要があります。そして、ここにキャッチがあります:検索方向に関係なく、両方のシンボルの出現を保護することはできません! (前方検索で '? 'をエスケープすると疑問符が' \? 'アトムに変換されます。) –

+1

私はエクスプレッション("%:t ")'をエクスプレッションに使用しました。これはすでに結果が同じではないと言うのに十分です。この場合、 '\ V'で何かをエスケープする必要はほとんどありません。しかし、次の表現は絶対にあなたと同じです: '/ \ V =エスケープ(展開( '%:p:h')、 '\')'そして、 Vimは常に ''/''path delimeter(私のWindowsマシンとLinuxマシンの両方)を使うので、'' \ ''文字をエスケープするように提案しています。エスケープする必要があるなら、私は '' /? ''文字をエスケープします。 –

+0

実際には、あなたの最後のコメントからの検索式はすべての場合に同じ効果を持ちません*。見るのは簡単です: '/ tmp/test'ファイルを開きます。あなたが提案する検索コマンドは、空のパターンを探します(私の答えのコマンドとは対照的に)! –

1

その後、1だけで入力することができ、(:help patternを参照)

/Ctrlキー + R%

それ以外の場合は、現在のファイル名を準備し、最後に 検索レジストリに入れます。

:let @/ = '\V' . escape(expand('%:p:h'), '\') 

n/Nを使用して手動で検索コマンドを発行し、/または ?を入力してください。タイピングを減らすために、これらのステップを組み合わせたマッピングは に導入できます。

nnoremap <expr> <leader>f/ ExpandSearch('/') 
nnoremap <expr> <leader>f? ExpandSearch('?') 
function! ExpandSearch(dir) 
    let @/ = '\V' . escape(expand('%:p:h'), '\') 
    return a:dir . "\r" 
endfunction 

に類似のCtrl +R%が、より 一般的なコマンドラインの拡張機能、表現・レジスタもあります。検索パターンの編集中 + R=、式(:help expressionを参照) 入る一方が Ctrlキーを入力することができ、その評価の結果が 右位置のCtrl + =キーストロークに挿入されます が押されました。残念ながら、 の\Vアトムとescape()アトムで解決された通常のエスケープ問題のほかに、このように展開すると、新しい が作成されます。対話的にパス名が挿入されているので、検索コマンド(/または?)の実行に使用される文字を にエスケープする必要があります。悲しいことに、 の検索方向に関係なく、両方のシンボルの出現を保護することはできません。順方向検索で?をエスケープすると、 というマークがパターンをマングリングするアブソリュートの\?アトムに変換されます。

1

あなたのパターンにカーソルを移動しますsearch()と呼ばれるvimの中の関数があります:

:call search(expand("%:p:h")) 

あなたのパターンをハイライト表示されますmatchadd()と呼ばれる別の関数があります:ファイル名に特殊文字が含まれている場合

:call matchadd('Search', expand("%:p:h")) 

は、たとえば.*[]の場合は、escape()

:call search(escape(expand("%:p:h"), '.*[]')) 
一般
search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()* 
     Search for regexp pattern {pattern}. The search starts at the 
     cursor position (you can use |cursor()| to set it). 

matchadd({group}, {pattern}[, {priority}[, {id}]]) 
     Defines a pattern to be highlighted in the current window (a 
     "match"). It will be highlighted with {group}. Returns an 
     identification number (ID), which can be used to delete the 
     match using |matchdelete()|. 

escape({string}, {chars})    *escape()* 
     Escape the characters in {chars} that occur in {string} with a 
     backslash. Example: 
      :echo escape('c:\program files\vim', ' \') 
     results in: 
      c:\\program\ files\\vim 
     Also see |shellescape()|. 
+0

注意:現在のファイル名にVim検索パターンの構文を妨げる特殊文字が含まれていると、コマンドが正常に動作しません。 –

+0

'search()'関数を呼び出すことは、検索コマンドを使うことよりも劣ります。例えば、検索パターンは最後の検索レジスタに記憶されないので、デフォルトの「n」/「N」コマンドを使用してパターンの次/前のオカレンスにジャンプすることは不可能です。 ':match'コマンドや' matchadd() '関数を使ってカスタムの強調表示パターンを追加する場合も同様です。 –

+0

ファイル名が最後のコマンドで正しくエスケープされていないことに注意してください。たとえば、そのファイル名にバックスラッシュが含まれていると、パターンを大幅に変更することができます。 –

関連する問題