I'm trying to create a very basic .sublime-syntax
file to understand how the YAML-based definitions work and eventually create a full definition (the language is an old version of UnrealScript - definitions exist for this language already but I'm doing this as more of a learning exercise).
The first thing I'm trying to tackle is the declaration of variables, which can exist in a few different forms:
var int myInt;
var int myIntA, myIntB, myIntC;
var() int myInt;
var(foo) int myInt;
My syntax file currently looks like:
%YAML 1.2
---
name: UnrealScript
file_extensions:
- uc
scope: source.uscript
variables:
valid_variable_name: '[a-zA-Z_][a-zA-Z_0-9]{0,}'
valid_type_name: '{{valid_variable_name}}'
contexts:
main:
- match: ;
scope: punctuation.terminator.statement.empty.uscript
- match: '(?i)\bvar'
scope: storage.variable.var.uscript
push:
- meta_scope: meta.variable.assignment
- match: \(
scope: punctuation.variable.property.begin.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.parameter.uscript
- match: ''
pop: 1
- match: \)
scope: punctuation.variable.property.end.uscript
- match: '{{valid_type_name}}(?=\s+)'
scope: storage.type.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.other.readwrite.uscript
pop: 1
- match: ;
pop: 1
This seems to highlight things correctly, but let's say I start typing this and haven't yet added a semi-colon:
var int myInt, somethingElse
^^^^^^^^^^^^^
The variable name somethingElse
is assigned the storage.type.uscript
scope but I want it to be assigned variable.other.readwrite.uscript
- what am I missing?
Side note: I'm aware of named contexts but am using anonymous contexts for this example.
The reason why somethingElse
is scoped as storage.type.uscript
is because it is still in the context with the meta scope meta.variable.assignment
. (It would be much easier to discuss if the contexts were named btw...) So it sees {{valid_type_name}}(?=\s+)
as matching somethingElse
(assuming a newline after it and not typing exactly at EOF).
The simple solution here is to scope the variables after a comma correctly - so instead of popping after assigning scope variable.other.readwrite.uscript
, only pop at semi-colon for example.
%YAML 1.2
---
name: UnrealScript
file_extensions:
- uc
scope: source.uscript
variables:
valid_variable_name: '[a-zA-Z_][a-zA-Z_0-9]{0,}'
valid_type_name: '{{valid_variable_name}}'
contexts:
main:
- match: ;
scope: punctuation.terminator.statement.empty.uscript
- match: '(?i)\bvar'
scope: storage.variable.var.uscript
push:
- meta_scope: meta.variable.assignment
- match: \(
scope: punctuation.variable.property.begin.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.parameter.uscript
- match: ''
pop: 1
- match: \)
scope: punctuation.variable.property.end.uscript
- match: '{{valid_type_name}}(?=\s+)'
scope: storage.type.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.other.readwrite.uscript
- match: ','
scope: punctuation.separator.sequence.uscript
- match: (?=;)
pop: 1
- match: ;
scope: punctuation.terminator.uscript
pop: 1