TmLanguage and TmTheme playground

Quickly preview TextMate syntaxes and themes

This is a little project I cooked up quickly while working on making some changes to a TextMate language syntax for use with VSCode. See it in action here.

Screenshot of the playground

Overview

A TextMate language grammar (TmLanguage) describes a language's syntax for the purpose of syntax highlighting. It's not generally expected to produce a complete parse tree, but rather provide context locally so a syntax highlighter knows what kind of syntax is being used at a given location in the source. Patterns are defined with regular expressions and assigned nested scopes, which are used by the theme to apply colors to various parts of the source code.

A TextMate color scheme (TmTheme) assigns colors to source code tokens based on what kind of syntactic form they represent. It does so by applying settings for tokens matching a given set of scopes defined by the language grammar. Themes are generally language-agnostic because TmLanguage scopes generalize fairly well. For example, a string in any language is likely to have a scope beginning with string.*.

This application takes a TmLanguage and a TmTheme (optional; a default theme will be used if one isn't specified) and uses them to highlight a given section of code. There are several presets available for both languages and themes. The UI here is nothing special; it's quick and dirty and I'm no designer. It's really just for pasting themes, grammars, and source code into to see how they look.

Input

The UI has three primary inputs:

TmLanguage

The TmLanguage box accepts a TextMate Language Grammar in YAML, JSON, or XML plist format.

TmTheme

The TmTheme box accepts a TextMate color scheme or a VS Code theme in YAML, JSON, or XML plist format.

Example code

The Example code box accepts any text. Whatever you type here will parsed with TmLanguage and displayed in the Rendered box.

Variables

Inspired by the official TypeScript TextMate grammar, TmLanguages and TmThemes displayed using this tool may optionally have a top-level variables property containing a map of variable names to variable values. Before handing the grammar or theme off to the syntax highlighter, references to those variables wrapped in double curly braces will be replaced with that variable's value.

name: Simple Grammar
scopeName: source.simple

variables:
  ident: '(?:\b(?!\d)\w+\b)'

patterns:
  - include: '#expressions'

repository:
  expressions:
    patterns:
      - name: meta.function.call.simple
        begin: '({{ ident }}\s*)?\('
        end: '\)'
        beginCaptures:
          1: { name: entity.name.function.simple }
        patterns:
          - include: '#expressions'
          - match: ','

      - name: variable.other.simple
        match: '{{ ident }}'

  

The ident variable eliminates the need to state \b(?!\d)\w+\b in multiple patterns.

This is not a feature of TextMate language definitions; to use this in your projects you'll need some additional processing like this.

Output

Rendered code

The Rendered box displays the contents of Example code as parsed by the given TmLanguage and colored by the given TmTheme (or a default theme is the TmTheme box is empty).

Scopes

Select any token in the rendered code, and the scopes applied to that token by the TmLanguage will be displayed below. This allows you to quickly troubleshoot language structures being highlighted incorrectly.