External match in a lookbehind assertion

7 views
Skip to first unread message

James Vega

unread,
Jan 3, 2008, 11:12:25 AM1/3/08
to vim...@vim.org
The current syntax highlighting of Perl heredocs[0] (and similar
constructs in other languages) has a known limitation of highlighting
anything after the heredoc start (e.g., "<<EOF") and on the same line as
a string instead of using normal highlighting.

[0] - syn region perlHereDoc matchgroup=perlStringStartEnd start=+<<\z(\I\i*\)+ end=+^\z1$+ contains=@perlInterpDQ

After some fiddling around with the syntax highlighting[1], I've been
able to get that text to be highlighted normally instead.

[1] - syn region perlHereDoc matchgroup=perlStringStartEnd start=+\%(<<\z(\I\i*\).*\n\)\@<=+ end=+^\z1$+ contains=@perlInterpDQ
syn match perlStringStartEnd +<<\I\i*+ nextgroup=perlHereDoc

The only problem with this is that the perlHereDoc region is trying to
match +^$+ (a blank line) as its end pattern instead of a line
containing simply the heredoc token. It seems that since the \z(\) is
inside the lookbehind, the external match isn't being saved.

Could Vim's regex handling be changed to save the external match even
though it's being matched in a zero-width atom?

This snippet of Perl code can be used to check the syntax highlighting.

print <<END and print "bar\n";
foo
END
$foo = "bar\n";

Currently, everything between "<<END" and "END" is highlighted as a string.
With the above changes "<<END" and all the lines after the print
statement are highlighted as a string. Adding a blank line after the
"END" line will cause the final line to be properly highlighted.

James
--
GPG Key: 1024D/61326D40 2003-09-02 James Vega <jame...@jamessan.com>

signature.asc

Bram Moolenaar

unread,
Jan 3, 2008, 12:10:36 PM1/3/08
to James Vega, vim...@vim.org

James Vega wrote:

I don't think this can be changed without causing trouble.

Why don't you use the "\zs" item to change where the region actually
starts? That's a lot more efficient too. Something like this:

syn region perlHereDoc matchgroup=perlStringStartEnd start=+<<\z(\I\i*\).*\zs+ end=+^\z1$+ contains=@perlInterpDQ

Disclaimer: Didn't try if this actually works...
You probably need to move the matchgroup to a separate item.

--
Computers are not intelligent. They only think they are.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

James Vega

unread,
Jan 3, 2008, 2:04:36 PM1/3/08
to Bram Moolenaar, Nick Hibma, vim...@vim.org
On Thu, Jan 03, 2008 at 06:10:36PM +0100, Bram Moolenaar wrote:
>
> James Vega wrote:
>
> > The current syntax highlighting of Perl heredocs[0] (and similar
> > constructs in other languages) has a known limitation of highlighting
> > anything after the heredoc start (e.g., "<<EOF") and on the same line as
> > a string instead of using normal highlighting.
> >
> > [0] - syn region perlHereDoc matchgroup=perlStringStartEnd start=+<<\z(\I\i*\)+ end=+^\z1$+ contains=@perlInterpDQ
> >
> > After some fiddling around with the syntax highlighting[1], I've been
> > able to get that text to be highlighted normally instead.
> >
> > [1] - syn region perlHereDoc matchgroup=perlStringStartEnd start=+\%(<<\z(\I\i*\).*\n\)\@<=+ end=+^\z1$+ contains=@perlInterpDQ
> > syn match perlStringStartEnd +<<\I\i*+ nextgroup=perlHereDoc
> >
> > The only problem with this is that the perlHereDoc region is trying to
> > match +^$+ (a blank line) as its end pattern instead of a line
> > containing simply the heredoc token. It seems that since the \z(\) is
> > inside the lookbehind, the external match isn't being saved.
> [snip]

> I don't think this can be changed without causing trouble.

I was a little wary at first too but external matches are only used for
syntax regions so it seems to be a pretty limited (and potentially
useful) change.

> Why don't you use the "\zs" item to change where the region actually
> starts? That's a lot more efficient too. Something like this:
>
> syn region perlHereDoc matchgroup=perlStringStartEnd start=+<<\z(\I\i*\).*\zs+ end=+^\z1$+ contains=@perlInterpDQ

I initially tried to use \zs but I couldn't get it to work. I'm
definitely no syntax highlighting guru though. I've added Nick to the
CC list in the hopes the discussion might inspire him to a better
solution.

I'll try to dig around in Vim's source this weekend to see if I can get
a working patch for remembering \z(\) and to test if/how it affects
things.

signature.asc
Reply all
Reply to author
Forward
0 new messages