Thursday, September 29, 2016

Re: syntax match bug: 'keepend' not officially supported, but required in some cases

Brett Stahlman wrote:

> The syntax documentation suggests that the 'keepend' argument applies
> only to syntax regions, not syntax matches. But if I highlight a
> buffer containing only the following line...
>
> ABCDE
>
> ...with the following syntax definitions...
>
> syn match A /A/
> syn match Inside /[A-Z]\+/ transparent contained containedin=A
> hi A guifg=blue
>
> ...the match group "A" extends (apparently incorrectly) from A through
> E, though its pattern matches only the "A". Stranger still, one
> additional nested "Inside" group is recognized in each successive
> letter. I.e., "Inside" is contained within "Inside", in spite of the
> `containedin=A'. Thus, running synstack on successive characters, I
> see...
>
> -- cursor on A --
> A
> Inside
> -- cursor on B --
> A
> Inside
> Inside
> -- cursor on C --
> A
> Inside
> Inside
> Inside
>
>
> I can fix the problem by adding the 'keepend' argument to the
> definition for match group "A", but the "keepend" is highlighted as an
> error by the vim syntax, and the help on :syn-match gives me no reason
> to believe the argument should be supported.

Yes, the "keepend" actually works, although it's not documented. I'll
add a note in the documentation.

> Here are the results of synstack() with the following, "fixed" definition for A:
> syn match A /A/ keepend
>
> -- cursor on A --
> A
> Inside
> -- cursor on B --
> -- cursor on C --
>
> Is 'keepend' meant to be supported for syn-match? The purpose of
> 'keepend' is to prevent a nested group from obscuring a match with a
> containing group's "end pattern". Although a match group has no
> explicit end pattern, the principle of checking for the end of the
> match pattern certainly still applies, so I suppose it makes sense
> that 'keepend' would be accepted for both syn-match and syn-region. If
> that is the intent, then the documentation needs fixing.
>
> As for the infinitely nested "Inside" groups, I can't account for
> that, and suspect it's a bug, but perhaps I'm misunderstanding
> something about contained and containedin?

This is actually working as intended. When using a transparent item,
checking for contained items ignores that transparent item. So the
"containedin=A" applies every time.

This can be avoided by add "contains=NONE to the Inside item:

syn match Inside /[A-Z]\+/ transparent contained containedin=A contains=NONE

--
A mathematician is a device for turning coffee into theorems.
Paul Erdos
A computer programmer is a device for turning coffee into bugs.
Bram Moolenaar

/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment