4

I'm writting a syntax file for Direct3D and I have a problem with the attributes:

[unroll]
for(int i = 0...)

Here, "unroll" is an attribute. I'm using a regex to find some keywords inside square brackets to identify them as attributes. The regex I'm using works, except when there are no spaces before the opening square bracket:

[unroll] // does not work
 [unroll] // works

It doesn't matter the number of whitespaces (or tabs) before the opening square bracket as far as there is at least one.

This is the regex (simplified to match only unroll) I'm using:

syn match hlslAttribute /^\s*\[unroll\]/

The same problems if using:

syn match hlslAttribute /.*\[unroll\]/

EDIT: As stated in a comment: It works while searching on the file, but not when matching the pattern for syntax highlighting.

The current syntax highlighting file can be found at: http://pastebin.com/zr1bGLt0

To enable the syntax hilighting for .fx or .hlsl files you must copy the hlsl.vim file (the one at pastebin) to the location of the syntax files in any Vim installation (/syntax: /usr/share/vim/vim73/syntax/) and add this line to your .vimrc:

autocmd BufNewFile,BufRead *.fx,*.fxc,*.fxh,*.hlsl set ft=hlsl

Then create a file with one of the previous extensions and write:

[unroll]
 [unroll]

The second line will be all the same color, while the first won't. Both of them should be like the second one.

Marc Costa
  • 95
  • 6
  • `/\s*\[unroll]` works with or without whitespace, here. – romainl Dec 27 '12 at 17:03
  • It works while searching on the file for me too, but not when matching the pattern for syntax highlighting. :S I don't know why. – Marc Costa Dec 27 '12 at 17:11
  • If you hexdump the file, before such an attribute and after a newline, are there other characters? Both of your regexes _should_ work, that is strange. – fge Dec 27 '12 at 17:11
  • @fge No, as it is syntax it is not strange. @John There is a big bunch of reasons why when using syntax highlighting this regex won’t work. Very big. You should provide enough information to reproduce this on another’s machine with `vim -u NONE`. As the part of it you definitely need to post the syntax script. And for future, “It works while searching on the file for me too, but not when matching the pattern for syntax highlighting” is what is supposed to be in the question, not in the comment. – ZyX Dec 27 '12 at 17:54
  • @ZyX I don't believe there is a syntax problem here, I believe the beginning `/` character to be part of the "command" and that it should be removed from the regex itself. Just a thought. – fge Dec 27 '12 at 17:56
  • @fge In order to be the problem author must’ve written something like `syn match group '/^\s*\[unroll]/'`. I don’t believe he did this and think that more likely `[` at the beginning of the line is matched by some other syntax group (but that is not the only possible explanation). In any case @John’d’ve posted the exact command that fails because what he posted does not fail. – ZyX Dec 27 '12 at 18:03
  • @ZyX Post edited and code posted in pastebin. Hope that helps. – Marc Costa Dec 27 '12 at 18:15
  • You don’t need to bother with the whole stuff with copying, adding, creating. To test all you need is `hlsl.vim` in `~/.vim/syntax/hlsl.vim`, empty buffer (that is launched when vim starts) and `set ft=hlsl`. Though you may do even less to test. // I can’t reproduce your problem. On the example two lines it gives `hlslAttribute` for `[` and `]` and `hlslAttribute hlslAttributes` for `unroll` (I mean the synstack), both of the same color which is as I see expected. Can you narrow everything down so that it is reproducible starting with `vim -u NONE`? – ZyX Dec 27 '12 at 18:26
  • I don't know how to reproduce it with `vim -u NONE` since my syntax is a plugin. And when I do that I see both lines in white, when with my syntax colors should be green. By the way, how can I know which lines match with the syntax pattern? – Marc Costa Dec 27 '12 at 18:45
  • @John `echo join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'))`. And there is no magic in something being a plugin. The fact that vim can source plugins automatically cannot prevent you from sourcing them manually. Though I supposed you to do something like `vim -u NONE -c 'set rtp=$VIMRUNTIME,~/.vim' -c 'syntax on' -c 'set ft=hlsl'`. Better if instead of `~/.vim` you set it to directory that contains only `syntax/hlsl.vim` and no other files. – ZyX Dec 27 '12 at 18:52
  • @ZyX I didn't know that! When I execute this command on the line with a space in front it returns the expected result, but with the line with no spaces it returns: level16 (on unroll) and level16c (on []). – Marc Costa Dec 27 '12 at 18:55
  • @John I have no idea WTF is `level16`/`level16c` meaning that it is some other syntax files that you have not posted and that is not present in vim distribution. – ZyX Dec 27 '12 at 20:14
  • @ZyX After some searching I found out that they come from another plugin: rainbow-parenthesis. I'll figure out something. Thank you for your help! Now, at least, I know what's going on! :) – Marc Costa Dec 27 '12 at 21:18
  • @John Tell authors of this plugin that they ought to be using `matchadd()` :) This way it won’t possibly interfere with syntax, but coloring nested parenthesis properly and with normal performance will be *very* tricky. (This is why the smiley.) – ZyX Dec 27 '12 at 21:28
  • @ZyX I'm rather thinking on removing the rainbow parenthesis plugin. ;) I was doing just fine without it. – Marc Costa Dec 28 '12 at 08:59

1 Answers1

2

As you've figured out in the comments, often the cause is interference of another syntax group (in your case, by a different plugin, Rainbow Parenthesis). If this is part of the same syntax, you can often fix things by changing the nesting hierarchy, but with an external plugin, you're probably out of luck.

The problem is that Vim only provides two mechanisms for highlightings, :syntax (which is bound to the buffer) and :match / matchadd(), which is bound to the window. So if you want custom highlightings for a buffer, you have to either use :syntax and risk interference with the filetype's syntax, or use matchadd() and have to use complex autocmds to make them apply only to the current buffer.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324