Thursday, March 1, 2012

Re: How to limit syntax rule match to the outside of a region?

On Feb 29, 10:12 am, Vadim Zeitlin <vz-...@zeitlins.org> 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 ';'.

> which more or less works for "var2" but "var1" is highlighted even if it
> occurs inside the block. I'd like to understand why does this happen and
> how to avoid it -- as well as implementing highlighting of the variables in
> the wrong places as errors. Does anybody know how could this be done?
>

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.

Note, var3 is not highlighted. Did you want a syn match instead of a
syn keyword, to allow multiple var names to match with one rule? If
you use :syn match instead, do be aware that :syn keyword always takes
precedence over :syn match or :syn region.

>  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.

--
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

No comments:

Post a Comment