Sublime Forum

Sublime syntax pop multiple levels

#1

I was looking for some sublime-syntax help. I have the following code:

field:
  - match: "[a-zA-Z_]+\\d_]*\\s*:"
    push:
      - meta_scope: meta.message.field
      - include: string
      - include: constant
constant:
  - match: \b(?:true|false|null)\b
    scope: constant.language
    pop: true # Pops meta.message.field
string:
  - match: '"'
    captures:
      0: punctuation.definition.string.begin
    push:
      - meta_scope: string.quoted.double
      - match: '"'
        captures:
          0: punctuation.definition.string.end
        pop: true # I want to pop string.quoted.double and meta.message.field
  - match: '[a-zA-Z_]\w*'
    scope: string.unquoted
    pop: true # Pops meta.message.field

It matches

foo: bar
foo: true
foo: "bar"

The problem is that the double quote leaves the meta.message.field scope on the stack. Is there a way to have the closing double quote pop twice so meta.message.field gets popped off the stack as well?

1 Like

Syntax definition for Regular Expressions inside JSON strings (think keybindings)
#2

I don’t think there is a way to pop several context at once.

In your case you can come around by replacing the

- match: '"'
    captures:
      0: punctuation.definition.string.begin
    push: ...

By:

- match: '"'
    captures:
      0: punctuation.definition.string.begin
    set: ...

Indeed once you know your field is a string, the end of the string will be the end of the field.
You may need to add a meta.message.field inside the string, I’m not sure.

1 Like

#3

There’s two ways to pop multiple contexts. The first is, as gwenzek mentioned, to just use “set” instead of “push”, but it only works if you indeed want this behavior.
The other option is a lookahead/behind pattern in a few pop patterns that either do or do not consume actually characters. You can see an example of this in the default HTML.sublime-syntax where it includes PHP, irrc.

1 Like

#4

So clear_scopes: was added in 3116

1 Like