1

I'm trying to create a function that implements the functionality outlined here: Vim search replace all files in current (project) folder

My current attempt:

nnoremap <C-F> :call ReplaceAcrossAllFiles(
function! ReplaceAcrossAllFiles(search, replace)
  execute "vimgrep /" . a:search . "/gj | copen "
    \ . " | cfdo %s/" a:search . "/" . a:replace . "/gc"
    \ . " | cfdo update"
endfunction

If, for example, I execute ReplaceAcrossAllFiles("hi", "hello") I get E683: File name missing or invalid parameter

EDIT

Thank you @Garcys and @statox for your answers. I now get an error which I believe is related to the quickfix window: E553: No more items. I'm able to suppress this with: silent execute "vimgrep /" . a:search . "/gj **/* | copen". However, as soon as I jump to the first match in another file, the error comes up again, cancelling the rest of the substitution.

3 Answers 3

4

You are missing something. After looking up the vimgrep documentation (:h vimgrep) you need the file(s).

vimgrep /" . a:search . "/gj **/*

The new script could be like this:

function! ReplaceAcrossAllFiles(search, replace)
  execute "vimgrep /" . a:search . "/gj **/* | copen "
  execute "cfdo %s/" a:search . "/" . a:replace . "/g | cfdo update"
endfunction

Some options should be reviewed.

2
  • 1
    I think you forgot to add the **/* in the new script :)
    – statox
    Commented Mar 18, 2021 at 11:02
  • Thank @statox for the error !! Commented Mar 18, 2021 at 11:21
3

If you replace execute by echo in your function you'll see that the executed command is

vimgrep /hi/gj | copen  | cfdo %s/ hi/hello/gc | cfdo update

But :h :vimgrep says that the command must be called with a filename :

:vim[grep][!] /{pattern}/[g][j] {file}

That's why vimgrep /hi/gj triggers a missing file name error.

You need to could add **/* as a filename to match all files in your directory like this:

execute "vimgrep /" . a:search . "/gj **/* | copen "
0
nnoremap <S-F> :vimgrep //gj **/* <bar> copen<C-B><Right><Right><Right><Right><Right><Right><Right><Right><Right>
nnoremap <C-F> :call ReplaceAcrossAllFiles(
function! ReplaceAcrossAllFiles(search, replace)
  silent! execute "vimgrep /" . a:search . "/gj **/* | copen"
  silent! execute  "cfdo %s/" . a:search . "/" . a:replace . "/gc"
  silent! cfdo update
endfunction

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.