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?
CodePudding user response:
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:
(let|const) render
But it will actually trip up all three programs because:
- Vim will think that the
|
is a command separator (:help :bar
), - your shell will think that
(let|const)
is an attempt to execute the commandlet|const
in a subshell, - and RipGrep will believe that
render
is a path.
Vim
Vim thinks that the |
is a command separator (:help :bar
) so it tries to execute :grep (let
and then const) render
, which is not what you want. In order to prevent that, the |
must be escaped:
:grep (let\|const) render
Your shell
Your pattern includes a capture group delimited with parentheses, which your shell understands as an attempt to execute the command let|const
in a subshell, which is bound to fail.
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 pattern with single quotes:
:grep '(let\|const) render'
which tells your shell to treat what is between the quotes literally, without trying to be smart.
RipGrep
Without the single quotes, RipGrep doesn't know that render
is 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 kills 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 -e
flag is not necessary because your pattern doesn't start with a -
.