Home > Mobile >  How to use alternation operator in Vim RipGrep?
How to use alternation operator in Vim RipGrep?

Time:01-26

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

  • Related