Expand description
Tree-sitter-backed syntax highlighting for lattice (DESIGN.md §5.3).
§Status
- Languages bundled: Rust, Python, JavaScript, Markdown (block +
inline split), plus a
Plainno-op fallback. - Incremental reparse landed (Option B, slices B.1–B.5).
Syntax::parse_at_with_editsacceptsEditDeltas, appliestree.edit()to the cached tree, and runsParser::parse(_, Some(&old_tree))so unchanged subtrees are reused.SyntaxHandleruns the parse on aspawn_blockingworker;request_reparsetakesBuffer(O(1) Arc bump) so the input thread doesn’t allocate the source. App-side cache onApp.visible_highlights_keyshort-circuits the per-framehighlight_lineswalk when nothing changed. - Flicker-free updates landed (C-series, slices C.1–C.5).
The C-series turns the algorithmically-correct B-series into
a user-visibly-flicker-free experience. The two-stage parse
exposes
Syntax::try_apply_intermediate(fast: tree.edit + source/version update, no parse) andreparse_with_cached_tree(slow: Parser::parse with cached tree as seed) so theSyntaxHandleworker can publish a byte-aligned intermediate snapshot before the parse completes.Appsynchronously line-shifts and byte-shifts itsvisible_highlightscache on every edit so held spans stay aligned with current content; the renderer never sees an empty/wrong intermediate. Grammar- driven edits (operators) flow through the same chokepoint so the C.x logic applies uniformly. - Plugin extension API used by builtins, not yet by plugins.
Adding a new language:
- Add the
tree-sitter-<lang>crate as a dep. - Register it in
registry::LangRegistry::standard. - Add a variant to
Lang(and updateLang::detect_from_pathfor the canonical extension).
§Injections
The shared registry::LangRegistry holds every registered
grammar’s HighlightConfiguration; the per-document Syntax
borrows refs through it. The injection callback looks up
sibling configs by name – so a markdown \``rust … ````
block recurses into the rust config, and a markdown paragraph
injects the inline-markdown parser. New languages drop in to
the registry and become injection targets without further
wiring.
Capture-name -> Style mapping lives in style.rs. The mapping
is the v1 stand-in for the themable name-to-color tables
described in §5.6 style mappings.
Re-exports§
pub use crate::handle::SyntaxHandle;pub use crate::indent::BracketSyntax;pub use crate::indent::electric_columns;pub use crate::indent::indent_columns_for_new_line;pub use crate::indent::indent_for_new_line;pub use crate::indent::is_electric_trigger;pub use crate::indent::tree_levels_for_line;pub use crate::indent::tree_levels_for_new_line;pub use crate::lang::Lang;pub use crate::modes::JavascriptMode;pub use crate::modes::MarkdownMode;pub use crate::modes::PythonMode;pub use crate::modes::RustMode;pub use crate::modes::TREE_SITTER_COMPLETION_SOURCE_ID;pub use crate::modes::TreeSitterCompletionMode;pub use crate::modes::TreeSitterSymbolSource;pub use crate::modes::lang_for_mode_id;pub use crate::modes::major_mode_id_for_lang;pub use crate::modes::register_language_modes;pub use crate::motions::SyntaxMotionIds;pub use crate::motions::register_syntax_motions;pub use crate::oneshot::oneshot_highlight_lines;pub use crate::plugin_lang::LanguageName;pub use crate::plugin_lang::LanguageRegistration;pub use crate::plugin_lang::LanguageRegistrationError;pub use crate::plugin_lang::PluginLanguages;pub use crate::plugin_lang::PluginLanguagesHandle;pub use crate::registry::GrammarSpec;pub use crate::registry::LangRegistry;pub use crate::syntax::Syntax;pub use crate::syntax::SyntaxError;pub use crate::syntax::SyntaxSnapshot;pub use crate::text_objects::SyntaxTextObjectIds;pub use crate::text_objects::register_syntax_text_objects;pub use crate::theme_style::resolve_syntax_style;pub use crate::theme_style::syntax_element_id;
Modules§
- conceal
- Conceal rules — the per-language declaration of what to hide.
- handle
SyntaxHandle– the async wrapper around per-documentSyntaxthat runs reparses off the UI thread.- indent
- Where should this line start?
- lang
- Languages this crate knows how to parse.
- modes
- Per-language major modes.
- motions
- Tree-sitter structural motions —
]f/[f/]F/[F(function),]c/[c/]C/[C(class),]a/[a/]A/[A(parameter),]l/[l/]L/[L(loop). The motion counterpart to the structural text objects (text_objects.rs); both read the same textobjects.scm captures. See docs/dev/architecture/treesitter-motions.md. - oneshot
- D.3.b.2 (2026-05-29): one-shot synchronous highlight.
- plugin_
lang - Languages registered at runtime rather than compiled in.
- registry
- Process-wide registry of
HighlightConfigurations, keyed by language name. Owned viaArcso everySyntaxinstance holds a cheap clone and the injection callback inHighlighter::highlightcan look up sibling configs (markdown block → markdown_inline; markdown’s fenced code blocks → rust / python / javascript / etc.) without eachSyntaxcarrying its own copy. - style
- Style category emitted by the highlighter, plus the capture-name table.
- syntax
Syntax: per-document tree-sitter state.- text_
objects - N.1.4c: structural (tree-sitter) text objects – the universal
af/if(function),ac/ic(class),aa/ia(parameter),al/il(loop) grammar objects. They are first-class citizens of Lattice’s vim grammar (compose with every operator:daf,vic,yaa, and theznnarrow operator’sznaf), owned here inlattice-syntaxper the locked N.1 design. - theme_
style - Syntax → theme-element style bridge.
- wasm_
grammar - Loading grammars from WebAssembly, and the stores parsers need to run them.
Structs§
- Styled
Span - Byte-range span within one source line, carrying a semantic
Style.
Enums§
- Style
- Semantic style category emitted by the tree-sitter highlighter.