Skip to main content

syntax/
lib.rs

1//! Tree-sitter syntax classification.
2//!
3//! Spans come back in document order, and anything they do not cover is
4//! unhighlighted text. No color and no rendering here — kinds map to colors
5//! through [`SyntaxPalette::color`](theme::SyntaxPalette::color).
6//!
7//! [`grammars::LANGS`] is one row per cargo feature, fixed at build time;
8//! [`grammars::install`] puts it into [`registry`], which also holds the
9//! languages this build can name and not paint, and which
10//! [`registry::register`] adds to at runtime.
11//!
12//! A language may carry an injections query marking regions written in another
13//! language — `<script>` and `<style>` in html. The injected name is resolved
14//! through [`registry`], so it must be one this build can paint.
15//!
16//! Every language is configured with [`lang::NAMES`]. A `Highlight` index means
17//! whatever the layer that produced it was configured with, and an injected
18//! parse returns indices of its own.
19//!
20//! No locals support: that query is passed empty in
21//! [`Lang::compile`](lang::Lang).
22//!
23//! Does not build for `wasm32-unknown-unknown`.
24
25use std::ops::Range;
26use theme::HighlightKind;
27
28pub mod document;
29pub mod grammars;
30pub mod lang;
31pub mod registry;
32pub mod session;
33
34/// The exact tree-sitter these grammars were built against. Reach for a
35/// `LanguageFn` through here rather than declaring your own tree-sitter, or
36/// [`Lang::new`](lang::Lang::new) will not accept it — two versions in the
37/// graph are two unrelated types with one name.
38pub use tree_sitter;
39pub use tree_sitter_language;
40
41/// The wasm engine, which this crate borrows and never builds.
42///
43/// `tree_sitter::wasmtime` is the only handle that works: wasmtime arrives
44/// through tree-sitter, and a second one in the graph is a second `Engine` type.
45#[cfg(feature = "wasm")]
46pub use tree_sitter::wasmtime;
47
48#[cfg(feature = "wasm")]
49static ENGINE: std::sync::OnceLock<wasmtime::Engine> = std::sync::OnceLock::new();
50
51/// Hand this crate the engine wasm grammars are instantiated in. `false` if one
52/// was already set, which leaves the first in place.
53///
54/// The app owns the engine; this keeps a handle so other consumers share it.
55/// Until one is set, a [`Grammar::Wasm`](lang::Grammar::Wasm) cannot load.
56#[cfg(feature = "wasm")]
57pub fn set_engine(engine: wasmtime::Engine) -> bool {
58    ENGINE.set(engine).is_ok()
59}
60
61#[cfg(feature = "wasm")]
62pub(crate) fn engine() -> Option<&'static wasmtime::Engine> {
63    ENGINE.get()
64}
65
66/// Highlight `source` as `language` (a fence tag — `rs`, `py`, `tsx`, …).
67/// `None` when the tag names no language with a grammar in [`registry`], which
68/// holds none until [`grammars::install`] or [`registry::register`] adds one.
69pub fn highlight(source: &str, language: &str) -> Option<Vec<(Range<usize>, HighlightKind)>> {
70    lang::resolve(language)?.highlight(source)
71}