Michael S.
Michael S.

Reputation: 305

Adding custom syntax to the Javascript language (VSCode)

I work with a custom environment, where the our build system uses specific macros to change outputted JS files. When I use VSCode, it doesn't seem to like that syntax, and that makes coding on it really annoying as in most cases it also breaks further syntax highlighting.

The custom syntax is {{custom}}. custom can be several things, at first I'd like vscode to just recognize the whole macro syntax as a string, so it won't mess with anything. Eventually I'd like to customize the indide of the macro, so I could highlight it.

I've tried searching the net for solutions, and making extensions to achive that, but with no success, currently the closest I came, is editing the javascript tmLanguange files directrly and adding the following to the statement:

"mystring-double": {
    "name": "string.template.js",
        "begin": "([_$[:alpha:]][_$[:alnum:]]*)?({{)",
            "beginCaptures": {
        "1": {
            "name": "entity.name.function.tagged-template.js"
        },
        "2": {
            "name": "punctuation.definition.string.template.begin.js"
        }
    },
    "end": "}}",
        "endCaptures": {
        "0": {
            "name": "punctuation.definition.string.template.end.js"
        }
    },
    "patterns": [
        {
            "include": "#string-character-escape"
        }
    ]
}

and also changing the string statement to the following:

"string": {
    "patterns": [
        {
            "include": "#qstring-single"
        },
        {
            "include": "#qstring-double"
        },
        {
            "include": "#mystring-double"
        }
    ]
},

This is very hacky, and still hardly achieves what I want to do. Currently the code looks like this with my changes:

vscode screenshot

From the screenshot it looks like it doesn't work at all, but in fact it does in some cases, in some other breaks the syntax highlighting and I always see errors on the macros.

Any help on how I can make an extension to do what I want would be really appreciated!

Upvotes: 1

Views: 1463

Answers (1)

Matt Bierner
Matt Bierner

Reputation: 65223

You should be able to use a grammar injection for this. For example, take a look at how the lit-html extension injects support for strings like:

const myHtml = html`<br>`

Writing an injection grammars requires two files: the grammar itself and the package.json contribution

I believe that you may want two injections, one for expressions like a === {{bla}} and another for expressions inside of strings like "{{bla}}". The first case is very similar to what lit-html does, while for the second, your injection selector would be something like "injectionSelector": "L:source.string"

Upvotes: 1

Related Questions