Skip to content

Latest commit

 

History

History
361 lines (308 loc) · 18.8 KB

File metadata and controls

361 lines (308 loc) · 18.8 KB

Rules

VSCode TextMate doesn't support all of the official TextMate rules.
Supported rules under VSCode TextMate: rawGrammar.ts
All unsupported rules are ignored.
MacroMates example_grammar
https://github.com/microsoft/vscode-textmate/blob/main/src/rule.ts#L389

Root

{ ... }
The JSON object containing your grammar.
It is required along with scopeName

Valid VSCode-TextMate rules:

Valid TextMate 2.0 rules:

Valid shiki rules:

Other rules: (ignored by VSCode/TextMate)

name_display

"name:" "..."
The display name of your language.
VSCode TextMate acknowledges name, but doesn't do anything with it.

scopeName

"scopeName:" "..."
The scopeName for your language.
It is the same value as "scopeName" under "grammars" in your package.json file.
It should be globally unique.
You should use the recommended format of source.languageId or text.languageId.
If you are extending another language, you should add your language on the end of their scopeName source.theirLanguageId.yourLanguageId.
For example HTML (Derivative) text.html.derivative extending HTML text.html.basic

patterns

"patterns": [ { ... } ]
An array of object pattern's to include.
If everything inside patterns fails with an error, then any begin rules will fail also.
If there are multiple conflicting rules, VSCode will pick the highest one from the list:

getCompiledRuleId

repository

"repository": { "...": { ... } }
A list of rules that can be later referenced with include.
contributing-a-basic-grammar.
VSCode Bug: If there is a match or begin, then the repository is ignored.
Although you can name repo-rules anything you like, you cannot reference a rule named $self or $base
If there are multiple conflicting rules, VSCode will pick the highest one from the list:

_compilePatterns

injections

"injections": { ... }
A dictionary of injections.
They do NOT work when the grammar is embedded into another language in VSCode.
injection-grammars

injectionSelector

"injectionSelector": "..."
Controls which scope-names to inject into and with what priority.
Default priority is 0, left L: is -1 (higher) and Right R: is 1 (Lower)
injectionSelector is used in conjunction with "injectTo" under "grammars" in your package.json file.
injection-grammars

fileTypes

"fileTypes": [ "..." ]
An array of file extensions your language supports.
VSCode TextMate acknowledges fileTypes, but doesn't do anything with it.
Use "extensions" under "languages" in your package.json file instead.

firstLineMatch

"firstLineMatch": "..."
A regex to detect if an open file should get assigned to your language.
VSCode TextMate acknowledges firstLineMatch, but doesn't do anything with it.
Use "firstLine" under "languages" in your package.json file instead.

include

"include": "..."
Reference an item in a repository.
"$self" includes the entire grammar file again.
"$base" includes the top level grammar file. (When embedded inside other grammars).
"#..." includes a repository rule in the same grammar file.
"source..." includes another grammar file with the scopeName.
"source...#..." includes a repository rule in the other grammar file.
include can reference rules in a repository that is at the same level as it or higher.
However it cannot reference a repository at the same level as it, if they are both inside a patterns array

name

"name": "..."
A list of space-separated scope-names to be assigned to the provided token.
VSCode will then colour that token using the scope names in the current theme.

TextMate 2.0 and Github do not separate scopes on spaces.
But instead attempt to match the entire text (including spaces) against the theme-scopes.
However they do separate theme scopes on spaces.
So string.regexp meta.group will only match on string.
Since regexp meta is not a valid scope-part.

naming_conventions, themes, theming
You should add your languageId as a suffix to all scope-names. example keyword.control.goto.cpp
comment, string and regex disables bracket matching while meta.embedded reenables it.
However, VSCode TextMate only checks for word boundaries \b(comment|string|regex|meta\.embedded)\b.
So keyword.string-double.comment will be recognized with string, disabling bracket matching.
Priority is to the first standardTokenType found.
_toStandardTokenType
The VSCode setting "editor.quickSuggestions" can be enabled/disabled based on the following standardTokenTypes: comment, strings and other.

contentName

"contentName": "..."
Same as name, but only applies to the region within begin/end or begin/while (includes the while).
Also applies to the captured text when paired with patterns inside a capture

match

"match": "..."
TextMate 2.0: If end or while does not exist, begin will be treated as match.
Regex used to tokenize and capture parts of a file.
name is used to apply a scope-name to the whole text being matched.
captures is used to apply scope-names to specific capture groups and/or retokenize the capture groups.
All other rules are effectively ignored. Including repository.
rule.ts

begin

"begin": "..."
begin starts a region that can span multiple lines.
An invisible 0-width anchor is placed directly after begin. The anchor can then be matched against using \\G.
TextMate 2.0: If end or while exists, match will overwrite and be treated as begin.
Regex just like match.
name is used to apply a scope-name to both the begin text and the entire region covered by begin/(end|while).
contentName is used to apply a scope-name to the inner region being covered (includes while).
end is used to end the region that was opened by begin. It is effectively placed at the beginning of the patterns array.
while is mutually exclusive and is prioritized over end.
patterns contains rules that are executed inside the inner region.
captures is used to apply scope-names to specific capture groups and/or retokenize the capture groups.
beginCaptures is just like captures, but specifically targets begin. It is prioritized over captures.
match is mutually exclusive and is prioritized over begin.
All other rules are effectively ignored. Including repository.
rule.ts

end

"end": "..."
Used to end the region started by begin.
end is checked before the patterns array. But it is not concrete.
Meaning items in patterns can consume the same text as end and effectively push the end rule along.
end can end directly after begin. Don't get caught out by it. Bad usage of 0-width begin and end rules.
If end is empty or missing. It will match against the character 0xFFFF .
If end is invalid it will either end immediately or carry on to the end of the document.
Regex just like match.
applyEndPatternLast controls if end should attempt to match before or after the patterns array.
name is used to apply a scope-name to the token matched by end.
captures is used to apply scope-names to specific capture groups and/or retokenize the capture groups.
endCaptures is just like captures, but specifically targets end. It is prioritized over captures.

while

"while": "..."
jeff-hykin textmate_while
while is checked once per line (starting on the line after the begin) capturing the matched text.
Items in the patterns array are then checked after the captured while text.
while places an invisible 0-width anchor after it. It can then be matched using \\G.
VSCode TextMate Bug: while is a lot more concrete than end. It cannot be pushed out by items in the patterns array.
TextMate 2.0 & Github: while is not concrete, and can be pushed out by items in the patterns array just like end.
Regex just like match.
name is used to apply a scope-name to the entire line matched by while.
contentName is used to apply a scope-name to the entire line matched by while.
captures is used to apply scope-names to specific capture groups and/or retokenize the capture groups.
whileCaptures is just like captures, but specifically targets while. It is prioritized over captures.

applyEndPatternLast

"applyEndPatternLast": 1
Controls if the end rule should attempt to match before or after the patterns array.
VSCode TextMate: true and numbers != 0 will enable it. 0, false and null will disable it.
TextMate 2.0: true (:true) and 1 will enable it. false (:false) and numbers != 1 will disable it.
applyEndPatternLast check

captures

"captures": { ... }
captures is used to apply scope-names to specific capture groups and/or retokenize the capture groups inside match, begin, end and while.
beginCaptures, endCaptures and whileCaptures are prioritized over captures.
Valid rules:

beginCaptures

"beginCaptures": { ... }
Same as captures.
Specifically targets begin.
Overrides captures for begin.
Valid rules:

endCaptures

"endCaptures": { ... }
Same as captures.
Specifically targets end.
Overrides captures for end.
Valid rules:

whileCaptures

"whileCaptures": { ... }
Same as captures.
Specifically targets while.
Overrides captures for while.
Valid rules:

capture

"0": { ... }
Target specific capture group number 0-999.
Group 0 is the entire string, excluding text before \\K regex.
Non-existent capture group numbers are ignored.
VSCode will ignore all characters after the numeric "123 this text is ignored, including 456": { }.
capture can only target capture groups (...) or named capture groups (?<name>...), not non-capture groups (?:...), atomic groups (?>...), 0-width lookarounds (?=...) (?<!...), absent groups (?~|...|...) or any other groups.
Capture groups inside lookaheads can be targeted, but there can be some side affects.
Capture groups inside negative-lookarounds will cause an error. Use non-capture group (?:...) instead.
A patterns array inside capture causes a performance hit in VSCode: issue 167
Valid rules:

  • name is used to apply a scope-name to the entire capture group
  • patterns allows sub-retokenizing of capture group, will clear scope-names from other captures. Use name to re-scope
  • repository list of rules that can be included from within patterns
  • comment
  • unknown

A patterns array (optionally empty) is required to be present for these rules to take effect.
It is not recommended to used them in this way. Rather buggy.
Nest them inside the patterns array instead.

comment

"comment": "..."
"//": ...
VSCode's TextMate does NOT acknowledge comment but instead just ignores it like all other unsupported keys.
C styled comments //... and /* ... */ are NOT allowed in JSON TextMate files.
VSCode's JSON validator ignores duplicate "//" keys.

schema

"$schema:" "..."
A link or relative file path to a json schema.
Schema used to validate VSCode JSON TextMate files.
Not supported by TextMate.

uuid

"uuid:" "..."
Technically this should be required in all json files.
A Universally Unique IDentifier (UUID) for each json file.
In the format [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}.
Not supported by TextMate.

disabled

"disabled:" 1
TextMate 2.0: Disables the current rule for easy testing.
Not currently supported by VSCode.

information_for_contributors

"information_for_contributors:" [ "..." ]
VSCode supplies it in their builtin syntax grammars.
Not supported by TextMate.

version

"version:" "..."
VSCode supplies it in their builtin syntax grammars.
Not supported by TextMate.

foldingStartMarker

"foldingStartMarker": "..."
A regex to define the start of a folding section.
Pair with foldingStopMarker.
Not currently supported by VSCode TextMate.
Use "folding" in your language-configuration.json file instead.

foldingStopMarker

"foldingStopMarker": "..."
A regex to define the end of the folding section that was started with foldingStartMarker.
Not currently supported by VSCode TextMate.
Use "folding" in your language-configuration.json file instead.

Unknown

"...": ...
All unknown/unsupported rules are ignored by VSCode TextMate.
This includes comment etc.
They do however need to be valid json.
With the exception of patterns. It must only contain objects {}. It cannot contain type "string", number, boolean or null. Arrays [] are ignored.