Syntax highlighting
By default, case-sensitive visiting basenames select bundled Rust (.rs),
C (.c, .h), Go (.go), HTML (.html, .htm), CSS (.css), JavaScript
(.js, .mjs, .cjs), TypeScript (.ts, .tsx), JSON (.json) and TOML
(.toml, including Cargo.toml) grammars and queries.
.tsx selects the distinct TSX parser while retaining the typescript settings
identity. User associations and the selected language table can override recognition.
Canonical reuse retains the first visiting alias; display labels such as
main.rs<2> do not determine the language. No runtime grammar installation,
network access or external language service is required. Other identities default
to plain Text grammar presentation; native Org source
uses its own coloring. See the complete language rules.
The status line names the selected grammar only for a prepared syntax tree of
the current buffer revision. TypeScript and TSX have distinct mode labels. A failed or missing query uses Text; incomplete source
remains editable and can still have valid captures. Syntax failures cannot
reject a text edit or discard history. Renaming or saving to another extension
updates recognition using the actual associated path. A missing .rs destination
can use Rust presentation without creating a disk file.
Supplied syntax preferences
Library sessions use their admitted snapshot's syntax.enabled, max_bytes and
per-language grammar. Bundled rust, c, go, html, css, javascript,
typescript, tsx, json, toml and fallback plain choices are supported;
associations identify a language independently of its grammar. Disabling syntax
or exceeding a positive UTF-8 byte cutoff drops derived styling without
rejecting edits or changing history. Equality is admitted and zero means no
configured cutoff. Shrinking below the cutoff starts parsing from current text.
A canceled parse is not retried on every redraw of that same revision.
Renames and published write-file destinations re-resolve grammar from the same
snapshot; rejected operations retain their old policy.
Palette
Document syntax uses the semantic RGB palette, with these built-in Tokyo Night
night colors. The library's registry composition reads overrides from its
admitted configuration snapshot; a standalone Frame::project uses defaults
unless supplied a palette with Frame::with_palette.
| Captures | Palette role | RGB default |
|---|---|---|
| Keywords | palette.syntax.keyword |
#9d7cd8 |
| Strings and escapes | palette.syntax.string |
#9ece6a |
| Comments and documentation comments | palette.syntax.comment |
#565f89 |
| Types, constructors, tags, attributes and properties | palette.syntax.type |
#2ac3de |
| Functions, methods and macros | palette.syntax.function |
#7aa2f7 |
| Constants, booleans and numeric literals | palette.syntax.number |
#ff9e64 |
| Grammar-provided punctuation and operators | palette.syntax.punctuation |
#89ddff |
Each present RGB leaf replaces only its own role. Unknown query capture groups
retain the ordinary document foreground. The bundled query determines which tokens
receive captures; highlighting does not invent language coverage from character
matching. Selected cells use the selection text/background colors before
syntax; search matches use their own text/background colors and underlining.
Selections take precedence when the two overlap. Colors reset at row boundaries,
and composed status, tree, separator and prompt spans keep their own roles.
The standard NO_COLOR environment preference suppresses RGB sequences while
retaining reverse-video selection and search underlining. RGB fidelity depends
on the terminal's true-color support.
Executable startup applies the admitted user palette, grammar associations and syntax policy. Missing or rejected configuration uses complete built-ins. The terminal input reference describes cursor color capability fallback and restoration.
Source and display coordinates
Queries read borrowed rope chunks and return byte ranges qualified by the buffer's revision. Presentation maps captured bytes through complete graphemes to visible terminal cells. Tabs, wide clusters, control rendering and horizontal clipping retain the ordinary editor coordinate rules; clipped grapheme fragments remain blank. A styled row contains the same padded text as an unstyled row.
Incremental revisions
Every admitted mutation prepares exact Tree-sitter input edits alongside its rope candidate. Ranges use the base revision and publish in descending source order. Byte offsets and LF-based row/byte columns account for multibyte text, CRLF, replaced line breaks and each inserted fragment. Typing contributions, paste, rectangle rows, undo and redo all use the same publication boundary. Canceled or rejected preparation leaves the existing tree unchanged.
Publication adjusts the retained tree's coordinates and immediately invalidates its captures. Several accepted edits can accumulate before rendering. A later refresh reuses the tree only when its coordinates match the current revision; otherwise it starts from current source. Drawing refreshes at most once per rendered revision, outside atomic publication, from borrowed rope chunks. No complete document String is built for parsing.
An incomplete parse can still supply current captures. A canceled or failed parse discards the tree and parser continuation, keeps the accepted text/history and uses Text status. That revision is not retried on every redraw. A subsequent accepted revision can recover from current text and resume incremental reuse. The library's progress-aware refresh accepts Tree-sitter ParseOptions for a bounded parser attempt; cancellation cannot roll back an accepted edit.
Queries cover the visible source interval of each document row. Each request allows at most 4096 in-progress matches and 65536 returned styles; exceeding a bound discards that request's styles. Drawing and capture generation never change document bytes, dirty/save state, point, mark or undo history.
Native Org source
Admitted .org files and M-x org-mode use the native Org source recognizers,
independent of Rust grammars and external language services. text-mode drops
Org styles. syntax.enabled and the UTF-8 byte cutoff also apply to Org;
org.enabled controls mode availability. The status remains Org while source
observation is pending, incomplete or canceled, since mode and derived styling
have separate ownership.
palette.org supplies independent colors for headings, keywords, drawer
boundaries, properties, planning lines, block boundaries, literal code, comments,
list markers, table rows, formula directives, emphasis, links, targets, footnotes,
entities and malformed structural delimiters. The complete sample
and Org palette catalog list every active
Org leaf and RGB default.
Nested inline captures take precedence over their enclosing heading/table style.
Code/verbatim inline objects and source, example, export and comment blocks keep
literal context. Their text never becomes an outer heading or inline object.
Coloring does not evaluate formulas, expand entities or hide source delimiters.
One temporary session-owned worker observes visible Org buffers from shared rope snapshots. Split views reuse their buffer's result. Editing remains available while work is pending; old styles disappear immediately on revision change. Results must match the canonical buffer/revision before publication. C-g cancels owned work, and hiding its buffer or disabling its mode/policy retires it. Native input polls at 10ms only while a job is owned; idle sessions have no Org deadline. The canceled revision is not retried on each redraw; a new edit can recover.
The default observation profile admits 8 MiB, 200,000 source nodes/captures and
256 structural levels. It reports incomplete coverage when a bound stops work;
unsupported or unobserved source stays readable. Index suffixes retain their
unaffected prefix after edits. Structural/inline ownership is re-observed from
the full admitted snapshot so delimiter edits cannot inherit obsolete context.
This does not promise suffix-only semantic work. Native cancellation is checked
between bounded parser steps and around finite capture sorting; no permanent
parser thread or file scan runs while idle. Library users can explicitly prepare
and install a ColorScan result before standalone Frame::project.
Colors use the same grapheme/tab/wide-cell projection, selection/search precedence and NO_COLOR fallback as Rust. NO_COLOR keeps original source and delimiters, selection reverse video and search underlining without RGB output. Task-state, tag and timestamp text retain their enclosing heading and planning roles.
Library fold projection
Native Org View::set_folds accepts up to 4096 revision-qualified source ranges.
Nonempty ranges hide complete logical lines; an unterminated final line may end
at EOF. Empty ranges are ignored. Overlapping/adjacent ranges form one hidden
interval. Partial lines, foreign/stale source, inactive Org mode and hiding the
view's current point are rejected before replacing existing visibility. This
API changes neither canonical source nor history and works on read-only buffers.
Each view retains its own map. Splits copy the choice through shared immutable
offsets; revealing or clearing one view leaves its peers unchanged. View.top
remains a canonical logical row, source_row resolves a local displayed row and
screen_row returns no position for hidden or above-viewport source. Cursor,
gutter labels, syntax, selection, search and mouse hits use those same rows.
Hidden text stays part of canonical regions and copied/saved source. Complete
Unicode glyphs, tabs, horizontal clipping and blank EOF cells retain their
ordinary coordinate rules.
Vertical/page/wheel/autoscroll input advances visible rows. A targeted source navigation or search reveals its containing hidden interval before displaying the point. The native Org visibility controls retain hierarchy choices and reveal only the target entry and ancestor path. Canceled search restores the original view choice. Canonical text publication, undo and redo release obsolete fold offsets in all affected views. Standalone stale maps also fall back to visible source; stale view points remain invalid until the caller supplies a current canonical point. Tiny geometry preserves source scroll and does not create a row alias or idle deadline.
External grammar assets
Register a compatible precompiled native library and both UTF-8 queries in the
startup TOML. An external registration can replace a bundled source or admit an
unbundled language. Existing file associations choose the language identity;
for example, .py already selects python. The four leaves are required together:
[language.python.external]
parser = "python-0.25.0/parser.so"
symbol = "tree_sitter_python"
highlights = "python-0.25.0/highlights.scm"
completions = "python-0.25.0/completions.scm"
Relative paths resolve under the resolved XDG data root's rev/grammars
directory; absolute paths are also accepted. Relative parent escapes and symlinks
outside that root fail admission. Paths must name regular local files. The
symbol must begin tree_sitter_ with a nonempty ASCII letter/digit/underscore
suffix and fit 128 bytes. Register at most 32 languages; each nonempty query
must fit 1 MiB. Registrations are frozen at startup; no asset directory is scanned.
First use queues admission on one temporary worker. Library IO/loading and
query compilation run outside terminal input and drawing. The parser ABI and
both queries must validate before that generation becomes visible. While pending,
and after a failed admission, the bundled source remains available if present;
an unbundled language stays editable as Text. Successful external syntax uses
External status (Org Src External in a declared-language source draft).
A completed failure is cached, even if its files are subsequently corrected.
There is no asset polling timer after admission finishes.
Native libraries are user-trusted code, not a sandbox. Admission cannot contain arbitrary native-code faults. The upstream safe loader retains a successfully loaded mapping for the process lifetime, including when later query validation fails. Rev never unloads or replaces it in process. Install assets into a new versioned directory, update the registration, and restart to activate that version. Never overwrite a mapped library in place. Rev does not compile, download or install grammars; supply compiled assets before starting it.
External query profile
Highlight capture families are keyword, string, escape, comment, type,
constructor, tag, attribute, property, function, constant, number,
punctuation and operator. Dot-qualified names use their first component.
Unrecognized captures reject the complete registration.
Completion captures are exactly function, type, module, constant,
binding, parameter, field, scope, comment and string. At least one
of the seven declaration kinds is required. Declaration captures name actual
source nodes, not identifier occurrences or generated text. Their text becomes
the literal candidate; the existing label, symbol, snapshot and work limits apply.
The nearest explicitly captured ancestor scope bounds a declaration's visibility.
Capture a body/block when the function name itself should remain visible outside
that function. Unlike bundled adapters, the external profile does not infer
language-specific scope node names, structural keys or HTML/CSS catalogs.
The optional comment and string captures identify literal regions for the
existing automatic completion policy; ordinary Tree-sitter comment/string node
names are also recognized. Manual requests retain their existing explicit
invocation policy. For example, a Python completion query can use:
(function_definition name: (identifier) @function)
(assignment left: (identifier) @binding)
(block) @scope
(comment) @comment
(string) @string
Tree-sitter's built-in text predicates are supported. Unknown predicates, property tests/settings, invalid node names, unknown captures, malformed queries and incompatible parser ABIs reject the complete registration. These checks preserve the same bundled/plain fallback without changing canonical text/history.