Search code examples
regexvimrustvim-syntax-highlighting

Highlight matching angle-brackets in Rust syntax


Trying to fix a bug in Rust's vim plugin, I thought it might be worth getting some advice on this.

Rust has generics denoted using angle brackets (<...>) similar to C++ or Java. However, it is possible that an arrow (->) might occur inside. As an example consider the expression

Box<Fn(A) -> B>

When the cursor is over the opening bracket, vim highlights the arrow's > instead of the closing bracket.

Now I thought this happened because the syntax region matching did not special-case the possible existence of arrows. I tried to fix that by changing end=/>/ to end=/-\@<!>/ in its definition. But apparently that has no effect on parenthesis highlighting. Now I'm starting to think syntax regions have nothing to do with this.

In summary my question is: How can you change the way parentheses are matched for highlighting?


Solution

  • This is actually handled by the MatchParen plugin (comes with all vim installations).

    The MatchParen plugin uses a fixed list of syntax attributes to ignore when searching for the matching bracket (From around line 96 in $VIMRUNTIME/plugin/matchparen.vim)

      " When not in a string or comment ignore matches inside them.
      " We match "escape" for special items, such as lispEscapeSpecial.
      let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' .
        \ '=~?  "string\\|character\\|singlequote\\|escape\\|comment"'
      execute 'if' s_skip '| let s_skip = 0 | endif'
    

    s_skip is then passed to searchpairpos later on. It does not appear there is anyway to modify s_skip from outside the plugin.

    So if you change all instances of rustArrow to rustArrowCharacter the bracket highlighting will be correct. (There are three instances to change two in syntax/rust.vim and one ftplugin/rust.vim) The check just checks to see if string, character, singlequote, escape, or comment appear anywhere in the syntax attribute (case insensitive). If it does skip it when searching for matching brackets.

    I would recommend asking on vim-dev if matchparen can be patched so that custom syntax attributes can be added to the skip list.