@Wliu if you could just indulge me for this question, it would be very much appreciated. Given that I didn’t quite understand injections
when I first saw them, I just want to confirm I understand what everything listed below is for.
Properties of the grammar file observed by the Grammar
class:
-
name
: Aesthetic label for language selection menu -
fileTypes
: Array of file extensions used to help calculate the language score (for automatic selection) -
scopeName
: A root scope that gets applied to all text, regardless of further matches. -
foldingStopMarker
: A currently ignored property, potentially will be used for syntax based folding (instead of the current indentation folding).foldingStartMarker
is not even looked for. -
maxTokensPerLine
: The maximum number of rule/pattern matches before tokenization of a line is stopped. -
maxLineLength
: The maximum line length, with longer ones being truncated to fit. It’s value in the grammar class can beInfinity
, but this results in an error when set directly in the file. -
limitLineLength
: Boolean, set totrue
makes theGrammarRegistry
set the value ofmaxLineLength
toInfinity
before converting to a grammar object. -
injections
: Explained in my other question. Basically, a way for the active grammar to insert rules based on scope instead ofinclude
ing in other rules. -
injectionSelector
: Used to apply the grammar in file where it is not the active grammar. Based on the scope provided, which is converted into aScopeSelector
class. -
patterns
: Converted into an ‘initial’ rule, which is then used to begin tokenization. -
repository
: Storage for rules based on name, which can beinclude
d into other rules. -
firstLineMatch
: Used to help the score, likefileTypes
.
Properties of an object in the patterns
array observed by the Patterns
class:
-
name
: Scope applied to text matched by the pattern. -
contentName
: Scope applied to text between thebegin
andend
captures of a pattern. -
match
: A single line regex used to determine a match. I’m unsure of the implementation though, specifically the difference between@match
and@regexSource
because of backreferences and the existence of anend
rule? Especially because I didn’t thinkend
was supposed to be used withmatch
.
if match
if (end or @popRule) and @hasBackReferences ?= DigitRegex.test(match)
@match = match
else
@regexSource = match
-
begin
: Checked ifmatch
does not exist. If not, it is set up similarly to amatch
rule, but an end pattern is generated and turned into a rule with the other patterns. -
end
: Not required, but used to finish abegin
match. -
patterns
: An array of objects which are part of the argument passed to@grammar.createRule()
. This in turn makes a newRule
object, which passes each pattern to@.grammar.createPattern()
, which makes a newPattern
. This recursive combination effectively processes every rule and pattern, no matter how deeply nested. -
captures
: Used to apply scopes to the capturedmatch
text. Is alternatively used forbegin
ifbeginCaptures
does not exist. Anypatterns
arrays inside of the capture group objects are processed as described in the above point. -
beginCaptures
: Captures specifically meant for thebegin
match. -
endCaptures
: Captures specifically meant for theend
match. If it does not exist,captures
will be tried instead. -
applyEndPatternsLast
: Getting more unsure here. The name seems straightforward; I would assume that by default theend
regex of the currently ‘active’ rule is always looked for first, before any internal pattern matches. Setting this totrue
would cause the reverse, where any internal patterns would try to be matched first. -
include
: The code for this is nice and straightforward. If it starts with a#
, the rule is looked for in the current repository. If it’s index is further in, the left side is considered the scope name of another grammar, and the right side the rule name in that grammar’s repository.$self
and$base
get special handling. Otherwise, it is considered another grammar’s scope name, and it’s ‘initial’ rule is inserted.
I haven’t tested how it behaves ifmatch
,patterns
, etc. are also present, but that sounds like a bad thing to do. -
popRule
: Related to theruleStack
variable used intokenizeLine
, I think. Seems to be automatically applied toend
patterns, so I’m guessing it pops an entire rule, which is made from apatterns
array. Are there any use cases where using it directly can help? I tested it now, and an error is thrown if it’s used to pop theinitialRule
used intokenizeLine
. I don’t know why, but that amused me… -
hasBackReferences
: Automatically set if it doesn’t exist (tangent: the CoffeeScript?=
operator always confuses me). Used to determine if backreferences are present. If they are, they need to be replaced at some point.
Is there any reason to provide this property directly? Performance doesn’t seem like an issue, as it’s only done once when initialised.
Also, theAllDigitsRegex
it uses doesn’t seem able to detect oniguruma backreferences (of the\k<n>
form). Using these throws an error though, and I can’t determine where from. It seems the be in the construction of aScanner
. -
disabled
: A boolean only looked at by theRule
constructor, which does what it says.