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.

6
  • What do you need the count for? Why not using :%s command? Commented Apr 3, 2020 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
    Commented Apr 3, 2020 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 Commented Apr 3, 2020 at 6:23
  • @ChristianBrabandt Thanks, let me try.
    – Yves
    Commented Apr 3, 2020 at 6:29
  • hmmm, why not :cdo?
    – Maxim Kim
    Commented Apr 3, 2020 at 8:52

2 Answers 2

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
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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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