@carlwr/textmate-validate
    Preparing search index...

    @carlwr/textmate-validate

    🔍  textmate-validate

    Validation of VSCode TextMate grammars.

    ci docs npm release node license


    Links:

    The following examples use an example grammar grammar.json that can be created with this shell command:

    cat >grammar.json <<EOF
    { "patterns": [
    { "match": ".*" }, `# <- a valid regex`
    { "match": ".)" } `# <- INVALID REGEX!`
    ]
    }
    EOF

    Prerequisites: none; npx will fetch the package from npm on-the-fly

    Example:

    npx @carlwr/textmate-validate grammar.json || echo "failed!"
    # failed!

    npx @carlwr/textmate-validate --verbose --verbose grammar.json
    # [INFO] number of regexes:
    # total: 2
    # valid: 1
    # invalid: 1
    #
    # [INFO] valid regex:
    # regex: .*
    # path: patterns[0].match
    #
    # [ERROR] invalid regex:
    # error: unmatched close parenthesis
    # regex: .)
    # path: patterns[1].match
    #
    # [ERROR] validation failed

    npx @carlwr/textmate-validate --help # show help

    To use a specific onig.wasm instead of letting auto-detection pick one (see Oniguruma engine):

    npx @carlwr/textmate-validate --onig-wasm=./path/to/onig.wasm grammar.json
    

    Prerequisites: npm install @carlwr/textmate-validate

    Example:

    import { validateGrammar, passed, failed, printResult } from '@carlwr/textmate-validate'

    const result = await validateGrammar('grammar.json')

    passed(result) // false
    failed(result) // true

    const verbosity = 2
    printResult(result, verbosity) // same as the CLI output above

    JSON.stringify(result, null, 2)
    // [
    // {
    // "rgx": ".*",
    // "loc": "patterns[0].match",
    // "valid": true
    // },
    // {
    // "rgx": ".)",
    // "loc": "patterns[1].match",
    // "valid": false,
    // "err": "unmatched close parenthesis"
    // }
    // ]

    For a given TextMate grammar, the regexes in it are extracted and then validated.

    Validation is done by exercising each regex with the Oniguruma regex engine, which is what VS Code uses.

    Extracting the regexes:

    • a simple but robust custom parser is used
    • parsing errors are not reported (since it is beyond the scope of this package to reliably detect them)
    • ...the parsing strategy can be summarized as parse what we can, ignore anything else

    Validating the extracted regexes:

    • each regex is exercised with the Oniguruma engine
    • if Oniguruma doesn't complain, the regex is considered valid
    • if Oniguruma complains, the regex is considered invalid
    • the error strings this package reports are those produced by Oniguruma

    The package uses the Oniguruma WASM binary of vscode-oniguruma.

    This is a design decision and comes with benefits and drawbacks:

    • benefit: validation accuracy:
      • validation is done with the same library (e.g. compiled with the same compilation flags) that will be used by VS Code when the grammar is used at later points
    • drawback: fragility:
      • this package must use heuristics to dynamically locate the path of the onig.wasm file that vscode-oniguruma includes
      • the heuristics used are well tested (CI runs tests on Ubuntu, macOS and Windows; each on all supported Node versions) - but could likely fail for less common setups

    The auto-detection can be bypassed by specifying the path directly; when specified, only that file is used:

    • CLI: --onig-wasm=<path-to-onig.wasm>
    • library: setOnigWasmPath(<path-to-onig.wasm>)

    The package is intended to be used as a validation check for generated or hand-written TextMate grammars for VSCode, typically as part of a build script, CI pipeline, prepublish package.json lifecycle hook, etc. It complements the following that are also useful in a similar context:

    • schema validation
      • using e.g. the tmlanguage.json schema - which VS Code does not officially conform to, but is likely yet useful
      • note that schema validation serves the purpose of checking the structure of the grammar, something this package does not do
    • testing

    General:

    From Macromates:

    TextMate grammar data model and structure:

    • apeths blog
    • rawGrammar.ts of microsoft/vscode-textmate
      • i.e. from the actual VS Code textMate grammar parsing source code
      • the interface IRawGrammar is the entry-point/top-level type
    • documentation/rules.md of RedCMD/TmLanguage-Syntax-Highlighter

    Scope selectors:

    Scope naming conventions:

    References:

    • More Links section of documentation/README.md of RedCMD/TmLanguage-Syntax-Highlighter