Hello Ben and thanks for your very helpful reply -- and also sorry for the delay with my own one, I've unfortunately got sidetracked by other stuff and only could back to this now.
On Mar 1, 5:01pm Ben Fritz wrote: > On Feb 29, 10:12 am, Vadim Zeitlin <[email protected]> wrote: > > Hello, > > > > I'm trying to write a syntax file for a language that looks like this: > > > > var1 = foo; > > block name { > > var2 = bar; > > var3 = true; > > } > > > > The problem I have is that some variables can occur only at the global > > scope, i.e. outside of any block, while others can only occur inside a > > block. Ideally I'd like to highlight occurrences of the variables of the > > first kind inside a block and that of the second kind at global scope as > > errors but I'd also settle for not highlighting them at all. Unfortunately > > I don't see how to do it. Currently I have (simplified): > > > > syn keyword GlobalVar var1; > > syn keyword BlockVar var2 contained; > > syn region Block start="{" end="}" contains=ALLBUT,GlobalVar transparent > > > > This code works fine for me, if I remove the trailing ';' from the > keyword definitions. Vim commands just go to the end of the line, you > don't need to (and can't) terminate them with ';'. Yes, this was a mistake subconsciously (too many years of C/C++ programming taking its toll, I guess...) introduced when I was typing in the simplified version, sorry about this as well. The real file version (at https://github.com/vslavik/bakefile/blob/master/extras/vim/bkl.vim) doesn't have them. But the worst is not this but the fact that it now does work for me as well, even although I didn't really change anything. I don't understand what happened but my guess would be that I should have restarted my Vim after modifying the syntax file as perhaps some previously defined syntax matches hadn't been cleared. So this one was my mistake as well... > To highlight in the wrong places as errors, I adapted your script as > follows: > > syn keyword VarError var1 var2 > syn keyword GlobalVar var1 > syn keyword BlockVar var2 contained > syn region Block start="{" end="}" contains=ALLBUT,GlobalVar transparent > > hi GlobalVar guibg=blue > hi BlockVar guibg=yellow > hi VarError guibg=red > > Note that rules defined later take precedence over rules defined > earlier. Thus VarError always matches, but GlobarVar or BlockVar > overrides it if the variable is in the correct place. Another way to > do it would be to exactly define things with a Var1Error and Var2Error > which only match in the *wrong* spot, but the way I've done it lets > you be lazier. Thanks a lot, that's an excellent advice and I especially like it because it's so simple. The need to list all the names twice is a bit annoying but using Var1Error and Var2Error wouldn't really help that much as each variable would still appear twice in the file and now you'd have to think where to put it, too. Instead, I'm thinking about automatically generating (part) of the syntax file using the list of variable names which can be output by the program using these files itself. Anyhow, thanks again for the idea! > > Also, on a similar topic, what is the best way to highlight the values of > > the variables? I.e. for some of them only a limited set of values is valid, > > for example there are boolean variables which can only be "true" or "false". > > Currently I do > > > > syn keyword BoolValue false true contained > > syn match BlockVar "var3 *=.*$"he=s+4 contains BoolValue > > > > but this is quite inconvenient because I need to compute the highlighting > > index (4 above) for each variable and just doesn't look right. I'm sure > > there must be a better way of doing what I want but what could it be? > > Do you want to highlight var3 only if it is being assigned a true/ > false value? Use a zero-width look-ahead, or end the match explicitly > with \ze. See :help /\ze and :help /\@= and :help /zero-width. > > Do you want to highlight the "true" or "false"? If this is what you > want, you probably want to use a "nextgroup" definition. > > You can probably use both of these methods together. I actually wanted to do the latter but your pointer to \ze was still very helpful too as I could get rid of the "he=s+N" construction thanks to it, i.e. now I simply match "var3\ze *=" instead which is much simpler, thanks! But the most useful hint you gave me was about "nextgroup", I've somehow managed to completely overlook it while reading the syntax chapter of Vim manual. This is exactly what I needed, i.e. a way to "chain" 2 syntax items together. So to achieve my main goal, i.e. to highlight "true" or "false" as possible correct values for this variable I now simply do this: syn keyword BoolValue false true contained syn region BoolValueRgn matchgroup=Normal start="= *" end=";" \ contains=BoolValue contained syn match BoolVar "var3\ze *=" nextgroup=BoolValueRgn skipwhite which seems to work well (but please let me know if you notice any problems with it). Thanks again for your help! VZ -- You received this message from the "vim_use" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php
