Search & replace using quickfix list in Vim

前端 未结 6 1801

So far I always used EasyGrep for replacing text in multiple files. Unfortunately it is quite slow when a project gets bigger. One thing that seems to be amazingly fast is G

相关标签:
6条回答
  • 2020-12-07 10:55

    Using quickfix-reflector.vim, you can edit your search results in the quickfix window. The write command will then save the changes to your files.

    :copen
    :%s/foo/bar/cg
    :write
    
    0 讨论(0)
  • 2020-12-07 11:00

    cdo command has now been added! After you grep, you can use cdo to execute the given command to each term in your quickfix list:

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

    (Take a look at this git commit and this vim developers google group discussion for more information on cdo and the motivations behind adding it.)

    0 讨论(0)
  • 2020-12-07 11:02

    There's a patch to add the cdo (Quickfix do) command to vim, but it has not been pulled yet (as of 2015-03-25):

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

    You may want to patch vim yourself to get this patch:

    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
    
    0 讨论(0)
  • 2020-12-07 11:04

    nelstrom's answer is quite comprehensive and reflects his brilliant contributions to vimdom. It also goes a bit beyond what is strictly needed here; the quickfix step can be omitted in favor of populating args with the result of a shell command:

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

    should be all you need.

    Edit: as Domon notes, :set hidden must be done first if it's not already set!

    0 讨论(0)
  • 2020-12-07 11:05

    Update: Vim now has cdo, see Sid's answer.

    Original Answer:

    Vim has bufdo, windo, tabdo and argdo, which let you perform the same command in all open buffers, windows or files in the argument list. What we really need is something like quickfixdo, which would invoke a command on every file in the quickfix list. Sadly, that functionality is lacking from Vim, but here's a solution by Al that provides a home-rolled solution. Using this, it would be possible to run:

    :QFDo %s/foo/bar/gc
    

    And that would run the foo/bar substitution on all files in the quickfix list.

    The bufdo, windo, tabdo and argdo commands have some common behaviour. For example, if the current file can't be abandoned, then all of these commands will fail. I'm not sure if the QFDo command referenced above follows the same conventions.

    I've adapted Al's solution to create a command called Qargs. Running this command populates the argument list with all of the files listed in the quickfix list:

    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
    

    Using this, you could follow these steps to do a project-wide search and replace:

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

    Edit: (with a hat tip to Peter Rincker)

    Or you could join the last 3 commands together in a single line:

    :Ggrep findme
    :Qargs | argdo %s/findme/replacement/gc | update
    
    0 讨论(0)
  • 2020-12-07 11:17

    External grep

    (uses grepprg, grepformat like in makeprg/errorformat; if grepprg=='internal' this is identical to internal grep)

    :grep fopen *.c
    :copen
    :cnext
    

    Internal grep

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

    etc.

    Location list internal grep

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

    etc.

    Bonus: doing external grep for the loaded buffers:

    :silent bufdo grepadd fstream %
    :copen
    :cnext
    

    etc.

    External for all arguments:

    :silent argdo grepadd fstream %
    :copen
    :cnext
    
    0 讨论(0)
提交回复
热议问题