highlight — syntax highlighting spans
A small, self-contained highlighter: given source text and an explicit language name, it returns the byte ranges of tokens worth coloring.
pub fn highlight(source: &str, lang: &str) -> Option<Vec<HighlightSpan>>
Unlike the rest of the module, highlight takes a language name (not a
path) and does not use the LRU cache — it is a one-shot parse for
rendering snippets (code blocks in markdown, terminal output).
Language names
lang is matched against a fixed set of names. Note the JS family
collapse: javascript, js, jsx, mjs, cjs, json,
typescript, ts, tsx, php, lua, and dart all use the JavaScript
grammar (with the JS query). Matching is exact — a leading/trailing
space (" rust", "rust ") returns None (this mirrors how a markdown
renderer passes code-fence languages and rejects stray whitespace).
| Language names | Grammar |
|---|---|
rust, rs |
Rust |
python, py |
Python |
javascript, js, jsx, mjs, cjs, json, typescript, ts, tsx, php, lua, dart |
JavaScript |
c#, csharp, cs, c, h, cpp, c++, cxx, hpp, objectivec, objc, m, mm |
C# |
go, golang |
Go |
java, scala, groovy |
Java |
haskell, hs, lhs |
Haskell |
swift |
Swift |
zig, zon |
Zig |
kotlin, kt, kts |
Kotlin |
Unknown names return None.
Categories and queries
The output is a sorted list of HighlightSpan { start, end, category }
(byte offsets into source):
pub enum HighlightCategory { Keyword, String, Comment, Type, Function, Number, Builtin }
Each language has a hand-written query:
- Rust, Python, JavaScript get full queries: keywords (literals and
structural words), strings, comments, types, numbers, function
definitions and call sites, and builtins (
true/false/null/this/self/…). - The remaining languages (C#, Go, Java, Scala, Haskell, Swift, Zig, Kotlin, C/C++, Objective-C, …) share a minimal fallback query covering just strings, comments, types, and numbers.
Spans are sorted by start; overlapping captures are possible (e.g. a
keyword inside a comment) — consumers decide how to resolve them.
Example
let spans = tree_sitter::highlight::highlight("fn main() { let x = 1; }", "rust");
for span in spans.unwrap() {
let text = &src[span.start..span.end];
println!("{:?}: {text:?}", span.category);
}
// Keyword: "fn", Keyword: "let", Number: "1", ...