microsoft / vscode-textmate

A library that helps tokenize text using Text Mate grammars.
MIT License
562 stars 108 forks source link

How to create language dialects #225

Closed dragon-archer closed 5 months ago

dragon-archer commented 5 months ago

Hi everyone! I'm writing an vscode extension to support several Domain Specific Languages, which share a common base structure and each has a few additional rules.

As to avoid duplicating the common base rule, I created a base.tmLanguage.json under scope source.base. Then, I created a.tmLanguage.json and b.tmLanguage.json for DSL a and b respectively, with scope source.base.a, source.base.b, and inject them using injectSelector into specific scopes defined in source.base.

In the package.json I wrote as following:

"grammars": [
    {
        "language": "a",
        "scopeName": "source.base",
        "path": "./syntaxes/base.tmLanguage.json"
    },
    {
        "language": "b",
        "scopeName": "source.base",
        "path": "./syntaxes/base.tmLanguage.json"
    },
    {
        "scopeName": "source.base.a",
        "injectTo": [
            "source.base"
        ],
        "path": "./syntaxes/a.tmLanguage.json"
    },
    {
        "scopeName": "source.base.b",
        "injectTo": [
            "source.base"
        ],
        "path": "./syntaxes/b.tmLanguage.json"
    },
    {
        "language": "base",
        "scopeName": "source.base",
        "path": "./syntaxes/base.tmLanguage.json"
    }
]

My problem is:

So, I'd like to know if there is something I can do to correctly derive a and b from base, or perhaps I have to duplicate base.tmLanguage.json to a and b?

RedCMD commented 5 months ago

assigning the same scopeName to two different languages will not go well each language should have its own globally unique scopeName

instead of injecting it's prob way easier to just "include": "source.base" from within a.tmLanguage.json as long as you have the base scopeName under grammars

{
  "scopeName": "source.base",
  "path": "./syntaxes/base.tmLanguage.json"
}
dragon-archer commented 5 months ago

assigning the same scopeName to two different languages will not go well each language should have its own globally unique scopeName

instead of injecting it's prob way easier to just "include": "source.base" from within a.tmLanguage.json as long as you have the base scopeName under grammars

@RedCMD Thank you very much, I succesfully did this with an overall "include": "source.base" and several "injections" to add dialect specifics

P.S. I've searched the Internet for the scheme of tmLanguage.json files for several times, but all I could find is just a few duplicates of the official VS Code Docs, and there is nothing about the useful injection section. Actually the only reference I found about it is the syntax file from your extension. Perhaps you'd like to make an issue about it to the VS Code Docs so that newcomers can be less frustrating about similar tricky problems? Finally, I'd like to say that your extension really helps me a lot.

RedCMD commented 5 months ago

here's my schema for VSCode json TextMate https://github.com/RedCMD/TmLanguage-Syntax-Highlighter/blob/main/vscode.tmLanguage.schema.json I still need to finalize a bunch of things and I'm waiting for vscode to support unofficial json files

and some wip docs https://github.com/RedCMD/TmLanguage-Syntax-Highlighter/tree/main/documentation