vimregex-lookaroundsvimgrep

Can vimgrep be used with lookaround assertions?


I'm trying automate some text operations on a large JavaScript project, and wish to jump to the matches using vimgrep, which I'll follow with various macro invocations.

My target lines look like this:

getText("foo", 1)

But, not like this:

getText("foo")
getText("foo", [1])

I only want to match usages of getText that have more than one parameter, which is not enclosed in an array.

This search query (/), which uses a negative look-ahead, seems to work:

getText(.*",\(.*[\)\@!

But, running this regular expression with vimgrep:

:vimgrep /getText(.*",\(.*[\)\@!/ project/src/**/*.js

...fails with this message:

E682: Invalid search pattern or delimiter

I suspect that the look-ahead part of my regex is the cause, as the error goes away when I remove it.

Is there a way to utilize lookaround assertions with vimgrep?


Solution

  • :vimgrep loads each searched file into a Vim buffer and then applies Vim's regular expression search to it. So, unlike external tools as 'grepprg' / :grep, you can use the full Vim regular expression syntax here.

    As @Matt already commented, the E682 is caused by failing to escape the [. When you use the expression in a regular / search, Vim just treats the [ as a literal character, as the collection isn't properly closed - your search works as expected.

    In :vimgrep, the {pattern} has to be enclosed by /.../ delimiters, however. Apparently the parser continues to look for the ending /, but cannot find it as the not-yet closed [ collection keeps consuming characters, and this causes the error. This inconsistency isn't nice, and it obviously made you stumble, but it's not necessarily wrong. Now you know :-)

    Just properly escape the [ character as \[, and it'll work:

    :vimgrep /getText(.*",\(.*\[\)\@!/ project/src/**/*.js
    

    There are special regexp atoms (\v and \V) that change the amount of escaping; some people like to use them (to avoid excessive escaping, or for better readability) - I mostly find the necessary shift in interpretation distracting.