3

CTRLホットキー (例: + g) を設定しVIMGREPて、現在のバッファ内の現在のビジュアル選択に対して操作を実行するにはどうすればよいですか? 私の意図は、一致するすべての検索結果の「クイックフィックス」ウィンドウに行番号付きのリストを表示することです。

現在、正規表現検索の結果のリストを取得したい場合は、次のようにコマンド モード クエリを実行できます。

:vimgrep /foo/ %

ただし、これには 2 つの問題があります。

  1. クエリ全体を入力する必要はありません。私は常に視覚的な選択を行い、CTRL+ rCTRL+を使用wして現在の視覚的な選択をコマンド バッファーに貼り付けることができますが、これよりも単純なものが必要です。
  2. 上記のアプローチでは、現在のバッファーが既にファイルに保存されている必要があります。これを行うたびにファイルバッファーを保存するのではなく、VIM に貼り付けた一時バッファーで作業できるようにしたいと考えています。

ありがとうございました。

4

3 に答える 3

6

低レベルのソリューション

試し[Iて、:ilistコマンド:

[I                 " lists every occurrence of the word under the cursor
                   " in the current buffer (and includes)

:ilist /foo<CR>    " lists every occurrence of foo in the current buffer 
                   " (and includes)

を押してから:行番号を<CR>入力し、その行にジャンプします。

簡単なマッピングで視覚的な選択でそれらを使用できます。

xnoremap <key> "vy:<C-u>ilist /<C-r>v<CR>:

ただし、挿入時にレジスタをサニタイズする必要があるでしょう。

を参照してください:help :ilist

別のさらに低レベルのソリューション

ここまで来たら、さらに深く掘り下げて、驚くほどシンプルでエレガントなものを見つけてみましょう。

:g/foo/#

上記と同じ方法で使用できます:ilist

xnoremap <key> "vy:<C-u>g/<C-r>v/#<CR>:

制限事項

上記のソリューションでは、明らかにクイックフィックス ウィンドウは使用されませんが、次のことが可能になります。

  • 結果をリストとして表示し、
  • 行番号を使用して、実際に目的の場所に移動します。

ただし、制限があります。

  • リストはキャッシュされないため、別のオカレンスを取得する場合は、再度検索を実行する必要があります。
  • リストはクイックフィックス リストのように一時的なものではないため、:cnextや などのナビゲーション コマンドを使用:clastして結果を移動することはできません。

より高度なソリューション

これらの制限がショーストッパーである場合、この /r/vim スレッドの justinmk の回答を基にした以下の関数は、ほぼ完全な解決策を提供します。

  • 通常モードで押す[Iと、バッファ全体でカーソルの下の単語が検索されます。
  • 通常モードで押す]Iと、現在の行の後のカーソルの下の単語が検索されます。
  • ビジュアルモードで を押す[Iと、選択したテキストがバッファ全体で検索されます。
  • ビジュアルモードで を押し]Iて、現在の行の後の選択したテキストを検索します。

[I以下の関数は、バッファーがファイルに関連付けられている場合にクイックフィックス リスト/ウィンドウを使用し、それ以外の場合は通常の動作に戻り]Iます。コマンドの一部として使用するために変更される可能性があります:Ilist

" Show ]I and [I results in the quickfix window.
" See :help include-search.
function! Ilist_qf(selection, start_at_cursor)

    " there's a file associated with this buffer
    if len(expand('%')) > 0

        " we are working with visually selected text
        if a:selection

            " we build a clean search pattern from the visual selection
            let old_reg = @v
            normal! gv"vy
            let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
            let @v = old_reg

            " and we redirect the output of our command for later use
            redir => output
                silent! execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern
            redir END

        " we are working with the word under the cursor
        else

            " we redirect the output of our command for later use
            redir => output
                silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
            redir END
        endif
        let lines = split(output, '\n')

        " better safe than sorry
        if lines[0] =~ '^Error detected'
            echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".'
            return
        endif

        " we retrieve the filename
        let [filename, line_info] = [lines[0], lines[1:-1]]

        " we turn the :ilist output into a quickfix dictionary
        let qf_entries = map(line_info, "{
                    \ 'filename': filename,
                    \ 'lnum': split(v:val)[1],
                    \ 'text': getline(split(v:val)[1])
                    \ }")
        call setqflist(qf_entries)

        " and we finally open the quickfix window if there's something to show
        cwindow

    " there's no file associated with this buffer
    else

        " we are working with visually selected text
        if a:selection

            " we build a clean search pattern from the visual selection
            let old_reg = @v
            normal! gv"vy
            let search_pattern = substitute(escape(@v, '\/.*$^~[]'), '\\n', '\\n', 'g')
            let @v = old_reg

            " and we try to perform the search
            try
                execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' .  search_pattern . '<CR>:'
            catch
                echomsg 'Could not find "' . search_pattern . '".'
                return
            endtry

        " we are working with the word under the cursor
        else

            " we try to perform the search
            try
                execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
            catch
                echomsg 'Could not find "' . expand("<cword>") . '".'
                return
            endtry
        endif
    endif
endfunction

nnoremap <silent> [I :call Ilist_qf(0, 0)<CR>
nnoremap <silent> ]I :call Ilist_qf(0, 1)<CR>
xnoremap <silent> [I :<C-u>call Ilist_qf(1, 0)<CR>
xnoremap <silent> ]I :<C-u>call Ilist_qf(1, 1)<CR>

注意:<C-r><C-w>残念ながらそのようなショートカットがない視覚的な選択ではなく、カーソルの下に単語を挿入します。ヤンクするしかありません。

于 2014-10-24T08:20:36.227 に答える