While working on a syntax definition, I noticed some behavior that isn’t clearly defined by the documentation, so I thought I would make a note about it here, in case it helps someone else.
The documentation says:
meta_scope. This assigns the given scope to all text within this context, including the patterns that push the context onto the stack and pop it off.
But actually, we can see that it also applies to the patterns that set the context, not just those that push it.
Take the following sublime-syntax:
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
scope: source.example
contexts:
main:
- match: \(
push: inside_parens_start
inside_parens_start:
- meta_scope: meta.start
- match: 'hello'
scope: meta.start.content
set: inside_parens_body # we don't want to set this scope again if `hello` appears multiple times, so we switch to the body context
- match: \)
pop: true
- match: ''
set: inside_parens_body
inside_parens_body:
- meta_scope: meta.body
- match: 'foobar'
scope: meta.body.content
- match: \)
pop: true
Given the following test document:
(hello foobar)
One might expect:
-
(to have scopesource.example meta.start
-
helloto have scopesource.example meta.start meta.start.content
instead, it has source.example meta.start meta.body meta.start.content -
_(space) to have scopesource.example meta.body
-
foobarto have scopesource.example meta.body meta.body.content
-
)to have scopesource.example meta.body
-
to have scopesource.example
The fix is to change it to:
%YAML 1.2
---
# See http://www.sublimetext.com/docs/3/syntax.html
scope: source.example
contexts:
main:
- match: \(
push: inside_parens_start
inside_parens_start:
- meta_scope: meta.start
- match: 'hello'
scope: meta.start.content
set: inside_parens_body
- match: \)
pop: true
- match: ''
set: inside_parens_body
inside_parens_body:
- meta_content_scope: meta.body
- match: 'foobar'
scope: meta.body.content
- match: \)
scope: meta.body
pop: true
Notice that inside_parens_body now uses meta_content_scope, and all patterns that declare pop pattern scopes within it also set the same scope.
hopefully that will help other people struggling with what can seem to be quite confusing. 