web-dev-qa-db-ja.com

Vimのクイックフィックスリストを使用して検索と置換

これまで、複数のファイルのテキストを置き換えるために常にEasyGrepを使用していました。残念ながら、プロジェクトが大きくなると非常に遅くなります。驚くほど高速に思えるのは、バージョン管理されたファイルのみを検索するfugitive.vimのGgrepです。すべての結果はクイックフィックスリストにも保存されます。

Ggrepの結果を使用して、見つかったすべてのファイルを単純に置き換えるにはどうすればよいですか?クイックフィックスリストのすべてのファイルで%s/foo/bar/cgを使用することはどういうわけか可能ですか、それとももっと良い方法はありますか?

41
Zardoz

Update:Vimにcdoが追加されました。 Sidの回答 を参照してください。

元の回答:

Vimには bufdowindotabdo および argdo 。これにより、引数リスト内の開いているすべてのバッファー、ウィンドウ、またはファイルで同じコマンドを実行できます。本当に必要なのはquickfixdoのようなもので、クイックフィックスリスト内のすべてのファイルに対してコマンドを呼び出します。悲しいことに、その機能はVimに欠けていますが、 これが解決策です by Al これはホームロールソリューションを提供します。これを使用すると、次のコマンドを実行できます。

:QFDo %s/foo/bar/gc

そして、それはクイックフィックスリスト内のすべてのファイルでfoo/bar置換を実行します。

bufdowindotabdo、およびargdoコマンドには、いくつかの一般的な動作があります。たとえば、現在のファイルを破棄できない場合、これらのコマンドはすべて失敗します。上で参照したQFDoコマンドが同じ規則に従っているかどうかはわかりません。

Alのソリューション を適応させてQargsというコマンドを作成しました。このコマンドを実行すると、クイックフィックスリストにリストされているすべてのファイルが引数リストに入力されます。

command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
  " Building a hash ensures we get each buffer only once
  let buffer_numbers = {}
  for quickfix_item in getqflist()
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
  endfor
  return join(values(buffer_numbers))
endfunction

これを使用すると、次の手順に従って、プロジェクト全体の検索と置換を行うことができます。

:Ggrep findme
:Qargs
:argdo %s/findme/replacement/gc
:argdo update

編集:(Peter Rinckerへの帽子のヒント付き)

または、最後の3つのコマンドを1行にまとめることもできます。

:Ggrep findme
:Qargs | argdo %s/findme/replacement/gc | update
67
nelstrom

cdoコマンドが追加されました! grepを実行した後、cdoを使用して、クイックフィックスリストの各用語に対して指定されたコマンドを実行できます。

cdo %s/<search term>/<replace term>/cg

cdoとそれを追加する動機の詳細については、これ git commit およびこれ vim開発者のグーグルグループディスカッション をご覧ください。)

38
Sid

nelstromの答えは非常に包括的であり、vimdomへの彼の見事な貢献を反映しています。また、ここで厳密に必要なものを少し超えています。シェルコマンドの結果を引数に入力するために、クイックフィックスステップを省略できます。

:args `git grep -l findme`
:argdo %s/findme/replacement/gc
:argdo update

必要なのはそれだけです。

編集:Domonが指摘しているように、まだ設定されていない場合は、最初に:sethiddenを実行する必要があります。

14
rhowardiv

外部grep

(makeprg/errorformatのようにgrepprg、grepformatを使用します。grepprg== 'internal'の場合、これは内部grepと同じです)

:grep fopen *.c
:copen
:cnext

内部grep

:vimgrep /\<myVimregexp\>/ **/*.c
:copen
:cnext

等.

ロケーションリスト内部grep

:lvimgrep /\<myVimregexp\>/ **/*.c
:lopen
:lnext

等.

ボーナス:ロードされたバッファに対して外部grepを実行します:

:silent bufdo grepadd fstream %
:copen
:cnext

等.

すべての引数の外部:

:silent argdo grepadd fstream %
:copen
:cnext
3
sehe

quickfix-reflector.vim を使用すると、クイックフィックスウィンドウで検索結果を編集できます。 writeコマンドは、ファイルへの変更を保存します。

:copen
:%s/foo/bar/cg
:write
3
stefandtw

Cdo(Quickfix do)コマンドをvimに追加するパッチがありますが、まだプルされていません(2015-03-25現在):

https://groups.google.com/forum/#!topic/vim_dev/dfyt-G6SMec

このパッチを入手するには、vimに自分でパッチを適用することをお勧めします。

brew install hg # install Mercurial, e.g. with homebrew
hg clone https://vim.googlecode.com/hg/ vim
cd vim
# copy/download patch to . folder
patch -b -p1 < cdo.diff
./configure
make && make install