Monday, December 19, 2011

Re: sh (bash) syntax for here-document strings: embedding other languages

Pe 12/18/2011 11:04 AM, Andy Spencer a scris:
[...]
> Yikes, start with something even simpler than that until you get it
> working and then build it up from there. I wouldn't even try to script
> it yet. I have the following (and only the following) in my
> ~/.vim/after/sh.vim
>
> unlet b:current_syntax
> syn include @phpSyntax syntax/php.vim
> syn region shPhp matchgroup=shRedir contains=@phpSyntax
> \ start=+<<\z(.*\)\ze\n.*vim: ft=php+ end=+\z1+
>
> And it highlights the following sh/php fragment correctly.
>
> php<<EOF
> <?php # vim: ft=php ?>
> <?php echo "hi there"; ?>
> EOF
>
>
>> Is it possible vim has a bug with regular expressions ?
>
> From :help \@<=
>
> The part of the pattern after "\@<=" and "\@<!" are checked for a
> match first, thus things like "\1" don't work to reference \(\) inside
> the preceding atom. It does work the other way around:

Oh, yes, indeed, you are correct.

Unfortunately I kind of need the match-within-previous-string feature, \@<=

The sh syntax allows for different forms of the here-document delimiter,
and the syntax/sh.vim file distributed with vim provides for the following:
- delimiter may be prefixed with the '-' character, as a flag to
trim leading tabs from the here-document lines and the
following delimiter line
- delimiter may be quoted, with single or double quotes, to
prevent backslash-escapes, parameter expansion, command
substitution and arithmetic expansion in the here-document.
- delimiter my be preceded or followed by \ followed by a
newline

To express all these forms, the author wrote 13 different regular
expressions, all matching some possible form for introducing the
here-document delimiter on a command line.

If I want to include some language or languages in the here-document,
than I would need to repeat the 13 region definitions for each and every
language. And I would like to include quite a few languages in my syntax
file (sh, awk, sed, bc, vim, php, python, perl, ..) ...

For this reason I tried to define a *contained* syn region, within the
predefined shHereDoc group (that happens to extend onto the entire
containing shHereDoc), so that I do not have to write (n * 13) regions
and regular expressions ...

Even with a simple :syn region (which, by the way, was the first thing I
tried), like this:

:syntax list sh_php_heredoc
--- Syntax items ---
sh_php_heredoc xxx start=/<<-"\z(\S\+\)"\n/ end=/^\z1$/ contained
keepend excludenl contains=@PHP containedin=shHereDoc

I still do not get any match. I do not know why but I guess it is
because the search starts within the containing region (shHereDoc),
after the <<-"delimiter" line. So I guess I need to search "before"
(within-previous-string), which does find the region start ...

However the \z( ... \) notation in vim regular expressions for syntax
does not work even with regions, for which the start and end regular
expressions are different, and as the documentation says the end one is
not even required ...

Even with re search-backwards feature \@<= that I used, I still think
the external reference strings in REs, \z(...) and \z1, should work:

:syntax list @PHP sh_php_heredoc
--- Syntax items ---
PHP
cluster=htmlError,htmlSpecialChar,htmlEndTag,htmlCssDefinition,htmlTag,htmlComment,htmlPreProc,htmlLink,javaScript,htmlBold,htmlUnderline,html
Italic,htmlH1,htmlH2,htmlH3,htmlH4,htmlH5,htmlH6,htmlTitle,cssStyle,htmlHead,phpRegion,phpRegionSc,phpSpecialFunction,phpClasses,phpInterfaces,phpAssignByRef
,phpRegionSync
sh_php_heredoc xxx start=/\%(<<-"\z(\S\+\)\n\)\@<=/ end=/^\z1$/
contained keepend excludenl contains=@PHP containedin=shHereDoc
Press ENTER or type command to continue

However the above does not find the end match even if the RE is quite
simple ...

I find this everything-everyore-must-be-a-simple-RE design (for vim
syntax highlighting) insufficient to describe the syntax of a language.

More high-level features like followed-by, containing and contained
regions should be present, but with the ability to add alternatives for
the following and previous regions, to search only in a region as one
would search in a file, to add names to any regions in order to search
or extract data from it later or in other places, or to be used in some
kind of group_exists('name') macro, and some other high-level
conditionals, using defines or flags declared when matching regions of
text like defining them from within the REs used for a match.

Thank you,
Timothy Madden

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