1

I wrote a vim-script function, which allows me to grep a keyword in my project.

function! CustomGrep(...)
    if a:0 == 0
        silent vimgrep <cword> **/*.h **/*.hpp **/*.c **/*.cpp
    else
        silent execute 'vimgrep' a:1 '**/*.h **/*.hpp **/*.c **/*.cpp'
    endif
    "cope
endfunction

Now I want to write another function, which can replace a keyword:

function! CustomReplace(target, newWord)
    call CustomGrep(a:target)
    " loop --- how to loop?
    execute 's/'.a:target.'/'.a:newWord.'/gc'
    cnext
    " end loop
endfunction

Obviously, I need a loop in the function, which looks like:

let cnt = CustomGrep(a:target)
for from 1 to cnt
execute 's/'.a:target.'/'.a:newWord.'/gc'
cnext
endfor

But I don't know how to get the number of the output of vimgrep.

BTW, I know there have been some plugins, such as EasyGrep, but I still want to make a new one.

  • What do you need the count for? Why not using :%s command? – Christian Brabandt Apr 3 at 6:14
  • :%s only replace words in one file. What I need is to replace all occurrence in a project (a directory), just like how vimgrep works, vimgrep can grep all occurrence in a project recusively. – Yves Apr 3 at 6:17
  • I guess you need to get the output of the quickfixlist, have a look at :h getqflist() or :h getloclist() for the lvimgrep commands. You can then work with each match – Christian Brabandt Apr 3 at 6:23
  • @ChristianBrabandt Thanks, let me try. – Yves Apr 3 at 6:29
  • hmmm, why not :cdo? – Maxim Kim Apr 3 at 8:52
2

Simpler is

function! CustomReplace(target, newWord)
  call CustomGrep(a:target)
  cdo execute 's/'.a:target.'/'.a:newWord.'/gc'
endfunction

Or with cfdo and %s,

function! CustomReplace(target, newWord)
  call CustomGrep(a:target)
  cfdo execute '%s/'.a:target.'/'.a:newWord.'/gc'
endfunction
| improve this answer | |
1

With the help of @ChristianBrabandt, I finished this function:

function! CustomReplace(target, newWord)
    call CustomGrep(a:target)
    let x = 0
    let cnt = len(getqflist())
    while x < cnt
        execute 's/'.a:target.'/'.a:newWord.'/gc'
        w
        if x != cnt - 1
            cnext
        endif
        let x = x + 1
    endwhile
endfunction

Using getqflist() to get the number to control the loop, that's it.

| improve this answer | |
  • cdo would be easier; I’ll post an answer in a bit – D. Ben Knoble Apr 3 at 13:44
  • @D.BenKnoble That would be great. – Yves Apr 6 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.