6

I'm using Silver Search with the ag.vim plugin. Does anyone know how to use regex with the :ag command to search?

wejrowski
  • 439
  • 5
  • 20
  • Can you give us an example regex and describe what you are trying to do? – Peter Rincker Nov 20 '14 at 23:21
  • Since ag.vim plugin has been deprecated in favour of [ack.vim](https://github.com/mileszs/ack.vim), you might want to check that one out. (ag.vim was a fork of ack.vim and there are really not a lot of differences). reference: https://github.com/rking/ag.vim/issues/124#issuecomment-227038003 – wiser Jul 17 '18 at 03:10

3 Answers3

6

Ag.vim needs some additional escaping (on top of what is needed for ag) because of vim, as stated in https://github.com/rking/ag.vim#gotchas.

For example, if you have the regexes, they need to be typed in Ag.vim as follows:

  • \. is in Ag.vim \\.
  • \( stays \( in Ag.vim
  • [ and ] are in Ag.vim \[ and \]
  • \s becomes \\\s in Ag.vim
  • | (options separator, e.g. in (a|b|c) is in Ag.vim \|
  • \.\s+async[^h] is in Ag.vim \\.\\\s\+async\[^h\]

So to search for \.\s+async[^h], you type :Ag \\.\\\s\+async\[^h\]. This is a little bloated with backslashes, but currently the only way I know to get the results.

I hope that gives you an idea of how to escape your regexes. For me, it took a little experimentation with the escaping.

eugenk
  • 472
  • 4
  • 11
1

ag uses the same syntax as grep:

$ ag .epart.    finds 'departure' and 'departed'
$ ag ^The       finds all lines starting with 'The'
$ ag s{2}       finds 'Odessa'

I'm not familiar with that ag.vim plugin but I guess that something like the following should find all lines ending with Oz:

:Ag Oz$

Refer to $man grep for the gory syntax details.

romainl
  • 186,200
  • 21
  • 280
  • 313
0

First off

According to the ag.vim GitHub page, ag.vim is now deprecated in favor of ack.vim configured to use ag. If you decide to go that route, just replace :ag with :Ack in the following and you're good to go.

And I Quote

ag.vim is automatically regex-enabled. However, to avoid backslash pollution, it's practically necessary to put your expression in 'single quotes', e.g. :ag '[hw]eight' to find height, weight but not eight. Otherwise, your Bourne-compatible shell will try to expand your pattern according to its own syntax before letting ag take it up.

Escapees

We're dealing with a Bourne-compatible shell here, so to escape single quotes see here. tl;dr with my opinion mixed in: '\'' is ugly but necessary.

(For the record, if the quote character comes at the beginning or end of your pattern, you can shave a couple singles off the end: :ag \''cuz' finds 'cuz; :ag 'runnin'\' finds runnin'.)

Since you're in Vim, you'll still have to escape a couple characters that Vim would otherwise expand: # -> \#; % -> \%. (As of Jan 2023, running ack.vim on Neovim on a Mac, the gotcha here doesn't apply.)

Pearly Writes

ag uses a PERL-family regex, which is rather different from Vim regex. (The good news is that it's pretty common nowadays, so you've probably encountered it before.) A couple gotchas:

In place of Vim's \< \> (word start and word end) use \b (word boundary).

Magic characters like ( ) + are always magic; escape to search for the literals:

:ag 'foo\(.*\)' " finds `foo()` and `foo(bar)` but not `foo`
:ag 'foo(.*)    " finds all three as well as `fool`

:ag '\b([A-Z]+_){2}[A-Z]+\b'   " finds every three-word name in CONSTANT_CASE
:ag '\b\([A-Z]\+_\){2}[A-Z]\+\b' " finds oddities like `(O+_))K+` (see why?)

Case Sensitivity

ag uses smart case-sensitivity, which can be overridden:

" Pattern has no uppercase: default to case-insensitive
:ag 'foo'            " matches `foo`, `Foo`, and `FOO`
" Force case sensitivity
:ag -s 'foo'         " matches `foo` but not `Foo` or `FOO`

" Pattern has any uppercase: default to case-sensitive
:ag 'Foo'            " matches `Foo` but not `foo` or `FOO`
" Force case insensitivity (equivalent to `:ag 'foo'`)
:ag -i 'Foo'         " matches `foo`, `Foo`, and `FOO`

Besides this, there are other options you can set while using ag, which you can read about by running man ag on the command line.

This ain't exhaustive

I probably missed something, just saying.

tl;dr

'single quote' your pattern,
escape your # %s with a backslash and make friends with the monster '\'' (take a guess what for).
Then you've uncovered the pristine PERL--
though ag might still get on your case from time to time.