I have the following in my .vimrc which (I believe) makes :grep within Vim use rg:
if executable('rg')
set grepprg=rg\ --no-heading\ --vimgrep\ --hidden\ --case-sensitive\ --ignore-vcs\ --glob\ '!.git'\ --glob\ '!node_modules'
endif
I want to search for all definitions of functions named render.... If I do
rg -e \(const\|let\)\ render .
on the command line, I get what I'm looking for.
But
:grep -e \(const\|let\)\ render
in vim results in
zsh:1: command not found: let) render
regex parse error:
(const
^
error: unclosed group
I've tried some other combos of \, putting the whole query in /.../, can't quite get it working.
How do I use the alternation operator in ripgrep in vim?
There are three pieces of machinery involved, here, each with its own idiosyncrasies: Vim, your shell, and RipGrep.
Ideally, this is how your pattern should look with RipGrep's syntax:
If you try it as-is:
you should get a cascade of messages (irrelevant lines removed):
Vim
The first line:
tells you that the command executed under the hood is:
which is obviously incomplete. That is because Vim thinks that the
|is a command separator (:help :bar) so it tries to execute the broken:grep (let. If you want your|to pass through, you must escape it:OK, all the arguments are now passed to
rg:Your shell
You are not done yet, though:
Your pattern includes a capture group delimited with parentheses, which confuses the hell out of your shell because it looks like an attempt to execute the command
let|constin a subshell, which is bound to fail anyway, but in a context where it can't be done.You can try to solve those problems by escaping things with backslashes but you are entering an escaping arms race between the shell and Vim. That is the kind of race where there is no winner.
A better approach is to wrap your whole pattern with single quotes:
which tells your shell to treat what is between the quotes literally, without trying to be smart.
You can check what arguments are passed to
rgby forcing an error:which should show you this:
Well done!
RipGrep
Without the single quotes, RipGrep wouldn't know that
renderis part of the pattern so it treats it as a filename and you get errors because that filename doesn't exist.Wrapping the pattern in single quotes killed two birds with one stone: your shell expansion issue is solved and RipGrep knows where your pattern ends.
NOTE: While it is inconsequential, here, the
-eflag is not necessary because your pattern doesn't start with a-.