Dave Yarwood
Dave Yarwood

Reputation: 3010

How do I include a literal @ (at symbol) in Vim regex?

I'm trying to write a syntax rule for a Vim plugin I'm writing, and I'm having trouble writing a Vim regex that will match an @ symbol followed by an identifier, which is defined as two letters followed by any number of accepted characters. Here's what I have so far:

syntax match aldaAtMarker "\v@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"

I know that everything after the @ works (at least, as far as I can tell) because I copy-pasted it from an aldaIdentifier rule that appears to work correctly. But, I'm having trouble inserting prepending the literal @ symbol because the Vim regex system evidently ascribes a special meaning to @ (see :help syntax and grep for @).

With my syntax rule as written above, trying to load the plugin results in the following errors:

Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E866: (NFA regexp) Misplaced @
Press ENTER or type command to continue
Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E64: @ follows nothing
Press ENTER or type command to continue
Error detected while processing /home/dave/.vim/bundle/vim-alda/syntax/alda.vim:
line   21:
E475: Invalid argument: aldaAtMarker "\v@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"
Press ENTER or type command to continue

If I replace @ with \@, there are no errors, but the wrong things are highlighted, which makes me think that the \@ in my regex is being interpreted in a special way instead of being taken for a literal @ character.

I'm clearly missing something and My Google-fu is failing me. How do I include a literal @ symbol in a Vim regex in "very magic" (\v) mode?

Upvotes: 6

Views: 1763

Answers (2)

Dave Yarwood
Dave Yarwood

Reputation: 3010

It turns out that I had another syntax rule that was highlighting some additional things in the same color and throwing me off.

In very magic mode, \@ does appear to correctly escape the @ symbol:

syntax match aldaAtMarker "\v\@[a-zA-Z]{2,}[\w[:digit:]\-+'()]*"

Upvotes: 2

Nahuel Fouilleul
Nahuel Fouilleul

Reputation: 19335

from here :

The recommended is \m magic which is the default setting.

Otherwise, literal @ can be matched always with character set [@].

3. Magic                            */magic*

Some characters in the pattern are taken literally.  They match with the same
character in the text.  When preceded with a backslash however, these
characters get a special meaning.

Other characters have a special meaning without a backslash.  They need to be
preceded with a backslash to match literally.

If a character is taken literally or not depends on the 'magic' option and the
items mentioned next.

                            */\m* */\M*
Use of "\m" makes the pattern after it be interpreted as if 'magic' is set,
ignoring the actual value of the 'magic' option.
Use of "\M" makes the pattern after it be interpreted as if 'nomagic' is used.

                            */\v* */\V*
Use of "\v" means that in the pattern after it all ASCII characters except
'0'-'9', 'a'-'z', 'A'-'Z' and '_' have a special meaning.  "very magic"

Use of "\V" means that in the pattern after it only the backslash has a
special meaning.  "very nomagic"

Examples:
    after:    \v       \m       \M       \V     matches 
        'magic' 'nomagic'
      $    $        $        \$     matches end-of-line
      .    .        \.       \.     matches any character
      *    *        \*       \*     any number of the previous atom
      ()       \(\)     \(\)     \(\)   grouping into an atom
      |    \|       \|       \|     separating alternatives
      \a       \a       \a       \a     alphabetic character
      \\       \\       \\       \\     literal backslash
      \.       \.       .        .      literal dot
      \{       {        {        {      literal '{'
      a    a        a        a      literal 'a'

{only Vim supports \m, \M, \v and \V}

It is recommended to always keep the 'magic' option at the default setting,
which is 'magic'.  This avoids portability problems.  To make a pattern immune
to the 'magic' option being set or not, put "\m" or "\M" at the start of the
pattern.

Upvotes: 4

Related Questions