3

Take this short XML snippet for defining strings in gtksourceview:

<context id="string" style-ref="string" end-at-line-end="true">
    <start>"</start>
    <end>"</end>
    <include>
        <context id="special-string" style-ref="special">
            <match>(foo|bar)</match>
        </context>
        <context ref="def:line-continue"/>
    </include>
</context>

This highlights any instances of "foo" or "bar" inside a string. Suppose I want to highlight these two when they are the entire string, so that "foo" has the middle three characters highlighted but "foobar" is not highlighted at all. Is this possible in gtksourceview?

I tried using anchors ^...$ and lookahead/lookbehind (?<=") / (?=") but the former didn't work and the latter broke the syntax highlighter entirely.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
Charles
  • 11,269
  • 13
  • 67
  • 105
  • Is a negative lookahead what you are looking for? `foo(?!bar)` ? See this regex example: https://regex101.com/r/eL9tK2/1 – Jan Dec 12 '15 at 07:44
  • @Jan: No, positive lookahead/lookbehind, not negative. I want to match "foo" and "bar" but not "xxfooxx" and the like. But even though gtksourceview claims to use PCRE it seems to choke on those expressions. (The quotes are part of the string here: the three letters foo would not be highlighted, only when surrounded by quote marks.) – Charles Dec 12 '15 at 07:48
  • I would think of word boundaries then: https://regex101.com/r/eL9tK2/2 (see the updated example). – Jan Dec 12 '15 at 07:50
  • @Jan: No, because "X foo" should not be highlighted. Foo is only highlighted when preceded and followed by a quote mark. (In my actual application there are a large number of alternatives, not just foo and bar, but that shouldn't matter too much.) – Charles Dec 12 '15 at 07:54
  • This one is pretty simple: https://regex101.com/r/eL9tK2/3 – Jan Dec 12 '15 at 08:34
  • Not sure why you would need the grouping `(foo|bar)`. But, maybe it needs a group around the whole thing. If its PCRE, otherwise, this should work `((?<=")(?:foo|bar)(?="))` or possibly `((?<="(?:foo|bar)(?="))` –  Dec 13 '15 at 02:54
  • @sln: It says it's PCRE but neither the lookahead nor its entity equivalent work -- in fact they cause gtksourceview to error out. – Charles Dec 13 '15 at 06:22

1 Answers1

3

It seems like there is no way to match the beginning (or end) of the parent context in a subcontext. However, if you define special-string as a top-level context and include it before string in the main language context it will work:

<context id="special-string" style-ref="string">
    <match>"(foo|bar)"</match>
    <include>
        <context sub-pattern="1" style-ref="special"/>
    </include>
</context>

<context id="string" style-ref="string" end-at-line-end="true">
    <start>"</start>
    <end>"</end>
</context>
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60