The grammar file needs to be declared in the contributes.grammars
section of package.json
, here for an example language foo
. Since VSCode doesn't already know any languages with that ID, we also need to register a new language ID here:
{
// ...
"contributes": {
"grammars": [
{
"language": "foo",
"scopeName": "source.foo",
"path": "grammar.json"
}
],
"languages": [
{
"id": "foo",
"extensions": ["foo"]
}
]
}
}
grammar.json
looks like this:
{
"scopeName": "source.foo",
"patterns": [
{
"match": "foo",
"name": "mylang.symbol.foo"
}
]
}
The Developer: Inspect TM Scopes
command confirms that this is working as expected:
For mylang.symbol.foo
to be colored a specific way, the extension also needs to contribute a theme in package.json
:
{
// ...
"contributes": {
// ...
"themes": [
{
"label": "foo",
"id": "foo",
"uiTheme": "vs-dark",
"path": "theme.json"
}
]
}
}
With theme.json
looking like this:
{
"$schema": "vscode://schemas/color-theme",
"name": "Foo Theme",
"tokenColors": [
{
"scope": "mylang.symbol.foo",
"settings": {
"foreground": "#FF0000"
}
}
]
}
After selecting the theme with the Preferences: Color Theme
command, the word foo
will be colored red (and bar
is not):
Pretty much all of this should also be covered by VSCode's official docs on Syntax Highlighting and Color Themes, but in more depth.
Btw, instead of JSON, VSCode also supports TmLanguage grammars in XML / plist format out of the box, but I find the former tends to be more readable. And actually, the most readable format to use for TmLanguage grammars in my opinion is YAML, since they largely consist of regexes and they don't need to be escaped there. This does however require a conversion step from YAML to JSON or XML for VSCode to understand it.