pub struct SyntaxRenderState {
pub syntax_handle: Option<Arc<SyntaxHandle>>,
pub scroll: u32,
pub viewport_height: u32,
pub end_line_override: Option<u32>,
pub fold_hash: u64,
pub text_version: u64,
pub inlay_hints: Arc<[InlayHintRow]>,
pub inlay_version: u64,
pub static_overlay_quads: Arc<ArcSwap<StaticOverlayQuads>>,
pub doc_highlights: Arc<[Range]>,
pub static_overlay_version: u64,
}Expand description
Tree-sitter syntax inputs + static-overlay bucket cache.
Phase 5.8.AF.5 / Slice X2: split into two halves.
Inputs (syntax_handle, scroll, viewport_height,
fold_hash, text_version, doc_highlights,
static_overlay_version) are written by dispatch’s
publish_render_state from current Editor state. The
background overlay worker reads them via the published
RenderState snapshot to decide whether to re-bucket.
Output (static_overlay_quads) is a nested
Arc<ArcSwap<...>> so the worker can publish a fresh
StaticOverlayQuads without going through
publish_render_state. The outer RenderState Arc stays
stable across a frame; the inner cell can be swapped at any
time. Renderers read with
render_state.syntax.static_overlay_quads.load() — wait-free.
display-line B4.2 (gut + rename): the dead visible_spans /
visible_rows prepaint output cells were deleted; syntax colour
now flows through the cells / DisplayMatrix substrate, and only
the static-overlay bucket remains as a worker output here.
Goal #1 (“no parsing on the UI thread”) is enforced by this split: the overlay bucketing runs on the worker, not in any renderer’s per-frame body.
Fields§
§syntax_handle: Option<Arc<SyntaxHandle>>Active document’s syntax handle. None when no language
is attached (scratch buffer, plain text). The worker calls
.snapshot() on this each tick to capture the current
tree state for the highlight walk.
scroll: u32First visible line (the worker passes this as start to
highlight_lines(start, end_line)).
viewport_height: u32Visible pane height in lines. The worker computes
end_line = scroll + viewport_height (clamped by the
snapshot’s line count) when Self::end_line_override
is None.
end_line_override: Option<u32>Fold-aware highlight-window upper bound. Some(n) makes
the worker walk [scroll, n) instead of the default
[scroll, scroll + viewport_height). Set by the peer
when closed folds collapse multiple buffer lines onto a
single visible row, so a n_row viewport may need to
highlight n_row + interior_fold_lines buffer lines for
the post-fold tail to render with syntax styling. Slice
X2.9 plumbing – before this the legacy
Editor::refresh_highlights_window accepted end_line
as an explicit argument; the X2 worker now reads it
through the same render-state cell as every other input.
fold_hash: u64Caller-tracked signature of closed folds in the visible range. Folds change which physical lines are visible, so the cache key must include this to avoid serving stale spans across fold toggles.
text_version: u64Current document text version. The stale-snapshot HOLD
(worker recompute path) compares the document’s version
against the snapshot’s text_version() to decide whether
the snapshot is still current or has fallen behind.
inlay_hints: Arc<[InlayHintRow]>Perf plan A.2 slice A.2b.1: active document’s flattened
inlay-hint list, pre-gated by the buffer’s
lsp-inlay-hint-mode enable-flag. Populated once per
publish from Editor::lsp_inlay_hints_cache for the active
document; empty when the mode is off, no LSP, or no hints
have arrived yet.
Why on SyntaxRenderState and not LspRenderState:
inlays are an INPUT to the cells / DisplayMatrix worker’s
row composition (A.2b.2). The cells worker walks this list to
splice inlay text into each composed row; downstream readers
(GPUI’s active-pane prepaint) consume the woven rows. The raw
per-buffer LSP cache stays on lsp.inlay_hints for the
inactive-pane fallback path that flattens its own list.
(display-line B4.2: the dead RowPrepaint cell that
previously consumed this is gone.)
Coordinates: byte is a utf-8 offset against the active
document’s line text; text already has padding_left
/ padding_right spaces baked in at the publish boundary.
inlay_version: u64Perf plan A.2 slice A.2b.2: content hash of inlay_hints.
Paired with VisibleHighlightsKey::inlay_version so the
worker invalidates its row cache when the inlay payload
changes (arrivals, mode-gate flip, label edits). Stable
across pure-scroll ticks (same payload → same hash → cache
hit). Built by the publisher in the same pass that builds
inlay_hints so the two stay aligned by construction.
static_overlay_quads: Arc<ArcSwap<StaticOverlayQuads>>Perf plan B.2: worker-published output cell for per-row
pre-bucketed STATIC overlay quads (doc_highlight,
all_matches, substitute). Same nested
Arc<ArcSwap<...>> shape as visible_rows so the worker
can swap a fresh bucket without rebuilding the outer
RenderState. Inner Arc identity is the per-cell handle
cloned from Editor::syntax_static_overlay_quads_cell at
every publish.
Active-pane only — inactive panes keep the legacy
per-frame bucket path in their renderer (the worker only
pre-paints the active pane’s window). Cursor-coupled
layers (visual_range, current_match) are merged in by
the renderer at prepaint time; they’re cheap per-row
(one range each) and would force a worker wake on every
cursor blink if pushed off-thread.
doc_highlights: Arc<[Range]>Perf plan B.2: active document’s LSP document-highlight
ranges, pre-converted from utf-16 columns to utf-8 byte
offsets at publish time. The worker consumes this list
directly when bucketing the DocHighlight layer instead
of forcing the renderer to repeat the per-frame
conversion against the snapshot text. Empty when the
active buffer has no highlights or the LSP isn’t attached
— matches the steady-state no-highlight path on a single
cheap branch. Parallels Self::inlay_hints (A.2b.1).
static_overlay_version: u64Perf plan B.2: content hash of the static-overlay payload
(doc_highlights + all_matches + substitute_matches).
Paired with
VisibleHighlightsKey::static_overlay_version so the
worker invalidates its overlay bucket when any layer
changes (search query bump, LSP response, substitute
input edit). Independent from inlay_version so search
churn doesn’t invalidate the row cache and vice versa.
Built by the publisher from the same payload in
static_overlay_state_version so the hash stays
byte-aligned with the published list.
Trait Implementations§
Source§impl Clone for SyntaxRenderState
impl Clone for SyntaxRenderState
Source§fn clone(&self) -> SyntaxRenderState
fn clone(&self) -> SyntaxRenderState
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SyntaxRenderState
impl Debug for SyntaxRenderState
Auto Trait Implementations§
impl Freeze for SyntaxRenderState
impl RefUnwindSafe for SyntaxRenderState
impl Send for SyntaxRenderState
impl Sync for SyntaxRenderState
impl Unpin for SyntaxRenderState
impl UnsafeUnpin for SyntaxRenderState
impl UnwindSafe for SyntaxRenderState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more