Sublime Forum

Restrict with_prototype to single context in sublime-syntax

#1

I was recently looking into the feasibility of working on a Razor templating syntax for C# when I eventually ran into a problem I don’t think I can work around without modifying the embedded syntaxes. Take this Razor snippet:

<p>This is a test</p>
@{
    string[] teamMembers = {"Matt", "Joanne", "Robert", "Nancy"};
    foreach (var name in teamMembers)
    {
        <p>@name</p>
    }
    Array.Reverse(teamMembers);
    foreach (var reversedItem in teamMembers)
    {
        <p>@reversedItem</p>
    }
}

The @{ identifier starts a C# code block. The last } terminates it. How am I supposed to differentiate the last brace with any of the ones in the middle?

When you include another syntax, the with_prototype tag lets you inject matches into EVERY context. Because of this, there is no way I can properly check that last brace. If there was a way to only inject it into the main context (or whatever context was the target to be injected), then I could easily detect it.

The only workaround I can think of would be convincing the author of the language syntax to include a special embedding context that would be as simple as:

  embed:
    - match: '(?=\})'
      pop: true
    - include: main

It would be nice not to have to do that, though.

0 Likes

#2

This may be a silly question, but do you need to use with_prototype?

%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
scope: source.razorcs
contexts:
  main:
    - include: scope:text.html.basic
    - match: '@\{'
      push:
        - match: '\{$'
          push:
            - match: '\}'
              pop: true
            - include: main
        - include: scope:source.cs
        - match: '\}'
          pop: true
    - match: '@\w+'
      scope: variable.other.razorcs

obviously my example isn’t likely to be foolproof, but it seems to work
(i.e. it should use lookaheads for the curly braces and let the C# syntax scope them etc.)

1 Like

#3

That ability to include scopes like that is not documented and may completely solve my problem. I’ll have to experiment more.

0 Likes

#4

you can also go one step further and include only a specific context from another syntax definition, in case it is useful:

- include: scope:source.cs#block
0 Likes

#5

The Default Packages repo is worth checking out to see how some constructs are handled by the syntaxes that ship with ST3.

0 Likes

#6

Yeah, I was able to figure that one out. Thanks to your help I was able to mostly finish my Razor syntax file. It wasn’t as clean as I would have liked, but it is working now.

0 Likes