visual-studio-codegrammarvscode-extensionstextmate2tmlanguage

How do I add a bare-bones syntax to VSCode?


I'd like to add the simplest possible (mvp) language grammar and syntax highlighting to vscode.

It's (imo) a mess of TextMate docs (two different versions apply) and random internet advice. I can't make a basic example work, or find one.

How would I add a language grammar with only one rule (eg: treat "foo" as mylang.symbol.foo), and a single coloring rule that affects this symbol?


Solution

  • 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.