Skip to content

DiscreteTom/tmlb

Repository files navigation

tmlb

npm coverage build license

TmLanguage builder.

Generate TmLanguage JSON files from TypeScript. Type hint. Avoid escape hell.

Try it online in the playground.

Install

yarn add tmlb

Basic Usage

const language = new TmBuilder({ scopeName: "source.test" })
  .repo("comments", { name: "comment.line.test", match: /\/\//.source })
  .append({ include: "#comments" })
  .build({ validate: true });

will yield:

{
  "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
  "scopeName": "source.test",
  "patterns": [
    {
      "include": "#comments"
    }
  ],
  "repository": {
    "comments": {
      "name": "comment.line.test",
      "match": "\\/\\/"
    }
  }
}

See: examples/hello-world.

Advanced

With r-compose, construct readable and maintainable RegExp.

Click to Expand
const language = new TmBuilder({ scopeName: "source.test" })
  .append({
    name: "comment.line.double-slash.test",
    match: compose(({ concat, escape, select }) =>
      concat(
        escape("//"),
        /.*/, // in non-multiline mode, the /./ doesn't match the /\n/
        select(/\n/, /$/),
      ),
    ).source,
  })
  .append({
    name: "comment.block.test",
    begin: compose(({ escape }) => escape("/*")).source,
    end: compose(({ escape, select }) => select(escape("*/"), /$/)).source,
  })
  .append({
    name: "keyword.other.test",
    match: compose(({ concat, select }) =>
      concat(/\b/, select("if", "else", "while"), /\b/),
    ).source,
  })
  .append({
    name: "string.quoted.double.test",
    match: compose(({ concat, any, select, not }) =>
      concat(
        /"/,
        any(
          select(
            /\\./, // any escaped character
            not(concat(/\\/, /"/)), // any char except a backslash or the close quote
          ),
        ),
        select(/"/, /$/),
      ),
    ).source,
  })
  .build({ validate: true });

See examples/r-compose.