Skip to main content
Tree-sitter includes a powerful syntax highlighting system via the tree-sitter-highlight library, which is used on GitHub.com for highlighting code in multiple languages.

Overview

The syntax highlighting system requires three types of files:
  1. Per-user configuration - ~/.config/tree-sitter/config.json
  2. Language configuration - tree-sitter.json in grammar repositories
  3. Query files - Located in the queries/ folder
All configuration files use the .scm extension, which stands for Scheme, reflecting the Lisp-like syntax used in Tree-sitter queries.

Language Configuration

The tree-sitter.json file contains metadata about the parser and language:

Basic Information

  • scope (required) - Language identifier like "source.js" matching TextMate grammar conventions
  • path (optional) - Relative path to the parser’s src/ directory (default: ".")
  • external-files (optional) - Files to check for modifications during recompilation

Language Detection

  • file-types - Array of filename suffixes (e.g., [".js", ".jsx"])
  • first-line-regex - Regex tested against the first line of a file
  • content-regex - Regex tested against file contents for disambiguation
  • injection-regex - Regex for matching language injection sites

Query Paths

  • highlights - Path to highlight query (default: queries/highlights.scm)
  • locals - Path to local variable query (default: queries/locals.scm)
  • injections - Path to injection query (default: queries/injections.scm)

Highlight Queries

Highlight queries assign highlight names to syntax nodes using captures:

Standard Highlight Names

Common highlight names include:
  • keyword - Language keywords
  • function / function.builtin - Function names
  • type / type.builtin - Type identifiers
  • property / property.builtin - Object properties
  • string / string.escape - String literals
  • number - Numeric literals
  • comment / comment.documentation - Comments
  • variable / variable.parameter - Variables
  • operator - Operators
  • punctuation.bracket / punctuation.delimiter - Punctuation
Highlight names can be dot-separated for specificity. For example, function.builtin is more specific than function.

Theme Configuration

Map highlight names to colors in your config:

Local Variables

The local variables query tracks scopes and variables to ensure consistent coloring:

Special Capture Names

  • @local.scope - Indicates a node that introduces a new local scope
  • @local.definition - Marks the name of a definition in the current scope
  • @local.reference - Marks a name that may refer to an earlier definition

Excluding Local Variables

Use the (#is-not? local) predicate to disable highlighting for local variables:

Ignoring Nodes

Use @ignore to exclude specific nodes from tagging:

Language Injection

Language injection allows parsing code in multiple languages within a single file.

Injection Captures

  • @injection.content - Node whose contents should be re-parsed in another language
  • @injection.language - Node containing the language name to use

Injection Properties

  • injection.language - Hard-code a specific language name
  • injection.combined - Parse all matching nodes as one nested document
  • injection.include-children - Include child nodes’ text in the injection
  • injection.self - Parse using the same language as the node
  • injection.parent - Parse using the parent language

Example: Ruby Heredoc

Implementation Details

The tree-sitter-highlight crate provides the core functionality:

Key Types

  • HighlightConfiguration - Immutable, thread-safe language configuration
  • Highlighter - Reusable highlighter instance with parser and query cursors
  • HighlightEvent - Represents a highlighting step:
    • Source { start, end } - Plain source code range
    • HighlightStart(Highlight) - Begin highlighted region
    • HighlightEnd - End highlighted region

Performance Optimizations

Cancellation Support

Highlighting can be cancelled using an atomic flag:
The highlighter checks the flag every 100 iterations (defined by CANCELLATION_CHECK_INTERVAL).

Unit Testing

Tree-sitter provides a built-in testing system for highlight queries:

Test Syntax

  • Caret (^) - Tests the column at the caret position on the previous non-test line
  • Arrow (<-) - Tests at the same column as the comment character
  • Negation (!) - Asserts the scope does NOT match (e.g., !keyword)
Run tests with:

HTML Rendering

The HtmlRenderer converts highlight events to HTML:
The HTML buffer pre-allocates 10KB (BUFFER_HTML_RESERVE_CAPACITY) and the lines buffer pre-allocates space for 1000 lines (BUFFER_LINES_RESERVE_CAPACITY) to minimize reallocations.

Command-Line Usage

Code Navigation

Learn about tagging and code navigation

Query Syntax

Deep dive into Tree-sitter query language