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

Reply via email to