Skip to main content

RenderState

Struct RenderState 

Source
pub struct RenderState {
Show 34 fields pub active_document: Arc<ArcSwap<ActiveDocumentRenderState>>, pub buffers: Arc<BuffersRenderState>, pub panes: Arc<PanesRenderState>, pub lsp: Arc<LspRenderState>, pub syntax: Arc<SyntaxRenderState>, pub picker: Arc<PickerRenderState>, pub completion: Arc<CompletionRenderState>, pub popup: Arc<PopupRenderState>, pub band: Arc<PopupRenderState>, pub messages: Arc<MessagesRenderState>, pub notifications: Arc<NotificationsRenderState>, pub modeline: Arc<ModelineRenderState>, pub modeline_elements: ModelineSnapshot, pub current_dir: Option<PathBuf>, pub options: Arc<OptionsRenderState>, pub resolved_opts: Arc<ResolvedOptionsRenderState>, pub modes: Arc<ModesRenderState>, pub buffer_locals: Arc<BufferLocalsRenderState>, pub diagnostics: Arc<DiagnosticsRenderState>, pub tabs: Arc<TabsRenderState>, pub translator: Arc<TranslatorRenderState>, pub lifecycle: Arc<LifecycleRenderState>, pub resolved_theme: Arc<ResolvedTheme>, pub theme_ids: BuiltinElementIds, pub signs: Arc<SignsRenderState>, pub cells: Arc<ArcSwap<CellsRenderState>>, pub diff: Arc<DiffRenderState>, pub virtual_rows: Arc<VirtualRowsRenderState>, pub paint_revision: u64, pub wasm_gutter_decorations: PerBufferCache<WasmGutterDecorationCache>, pub compilation_severity: Arc<HashMap<BufferId, Arc<Vec<(u32, GutterSeverityLevel)>>>>, pub compilation_location_lines: Arc<HashMap<BufferId, Arc<Vec<(u32, u32, u32)>>>>, pub code_block_lines: Arc<HashMap<BufferId, Arc<Vec<u32>>>>, pub compilation_theme_colors: Arc<(u32, u32)>,
}
Expand description

The renderer’s read contract with the host. Built fresh by [crate::dispatch::Editor::build_render_state] at the end of every dispatch tick and stored into the editor’s ArcSwap<RenderState>. Renderers load with editor.render_state.load_full() once per frame.

Fields§

§active_document: Arc<ArcSwap<ActiveDocumentRenderState>>

I.5.1 (2026-06-05): inner ArcSwap so a keystroke can republish the active-document substate WITHOUT reswapping the whole monolith RenderState (I.5.3 the keystroke-only publish). The outer monolith Arc stays the single shared cell threaded to every renderer + worker; this inner cell is what the hot path stores into. Readers go through .active_document.load().load(). Mirrors the established VirtualRowsRenderState.pane_matrices nested-ArcSwap shape.

§buffers: Arc<BuffersRenderState>§panes: Arc<PanesRenderState>§lsp: Arc<LspRenderState>§syntax: Arc<SyntaxRenderState>§picker: Arc<PickerRenderState>§completion: Arc<CompletionRenderState>§popup: Arc<PopupRenderState>§band: Arc<PopupRenderState>

WK.12: the minibuffer band, published beside the popup rather than instead of it — both can be open at once.

§messages: Arc<MessagesRenderState>§notifications: Arc<NotificationsRenderState>

NOTIF.1b: corner-anchored notifications.

§modeline: Arc<ModelineRenderState>§modeline_elements: ModelineSnapshot

ML.0b-2: published snapshot of the configurable-modeline element system (descriptors + content, both Arc-backed so this clone is cheap). The renderers lay out Left/Center/Right zones from this (ML.1/ML.2). Distinct from modeline above, which is the legacy cmdline/search sub-state — different surface, kept separate.

§current_dir: Option<PathBuf>

Editor’s working directory set by :cd. None means fall back to std::env::current_dir().

§options: Arc<OptionsRenderState>

Slice 3c.final.B.10: typed-options registry published as a wait-free Arc clone so the renderer’s picker_display_is_minibuffer (and any future per-frame typed-option read) doesn’t take an actor round-trip.

§resolved_opts: Arc<ResolvedOptionsRenderState>

PI.4: per-buffer mode-resolved options (renderer-agnostic option resolution). Read via Self::resolved_option_for.

§modes: Arc<ModesRenderState>

Slice 3c.final.B.11: active modes per buffer, published as Arc<HashMap<BufferId, Arc<ActiveModes>>> so per-buffer reads in the modeline + future hot paths are wait-free.

§buffer_locals: Arc<BufferLocalsRenderState>

Slice 3c.final.B.9: buffer-locals per buffer, published as Arc<HashMap<BufferId, Arc<BufferLocals>>> so the modeline / help-render / file-tree / oil paint paths read without an actor round-trip.

§diagnostics: Arc<DiagnosticsRenderState>§tabs: Arc<TabsRenderState>

Issue #29 (2026-05-22): tab pages snapshot. Per-tab labels + active idx + the resolved show-decision so both peers paint the tabline from the same source.

§translator: Arc<TranslatorRenderState>

Phase 5.8.AF.5 / Slice 3c.final.B (group 5): translator inputs — published so the renderer’s input loop can build a TranslateContext from owned snapshots instead of &'a borrows that tie it to Editor’s lifetime.

§lifecycle: Arc<LifecycleRenderState>

Phase 5.8.AF.5 / Slice 3c.final.B (group 6): renderer lifecycle flags (should_quit, pending_redraw, terminal_width). Carries the per-tick “renderer should notice this” signals that the main loop reads before composing the next frame.

§resolved_theme: Arc<ResolvedTheme>

T.4 (theme-system): the resolved theme read table, snapshotted from the ThemeRegistryHandle at publish. Renderers read resolved_theme.get(theme_ids.<elem>) — an O(1) array index (design §7). T.6.t deleted the flat host Theme field that used to ride alongside this; all style reads now go through the resolved table, and non-style chrome (glyphs, separator chars, dim/nerd-fonts flags) through the typed-options registry. The TUI rebuilds its ratatui cache from this only when ResolvedTheme::version() changes (no per-frame adaptation); GPUI adapts inline.

§theme_ids: BuiltinElementIds

T.4: builtin element ids (Copy), interned once at boot. Paired with Self::resolved_theme so a read is resolved_theme.get(theme_ids.x).

§signs: Arc<SignsRenderState>

SG.2b: sign definitions + their pre-resolved theme elements, so a GutterDecoration::Sign paints without a name lookup on the render path. See SignsRenderState.

§cells: Arc<ArcSwap<CellsRenderState>>

S2.1 (2026-05-26): cell-grid renderer substrate state. Carries the published CellMatrix cell + the inputs the cell-builder worker (S2.2+) reads to rebuild. See CellsRenderState and docs/dev/architecture/cell-grid-renderer.md.

I.5.2: inner ArcSwap so the keystroke fast path can republish the cells substate WITHOUT reswapping the whole monolith (I.5.3). Mirrors active_document. Readers go through .cells.load().

§diff: Arc<DiffRenderState>

D.3.d.1 (2026-05-29): inline-diff overlay render state. Carries the active document’s DiffSignMap for the gutter-sign column. Renderers read via rs.diff.sign_map.sign_at(line_idx). Snapshot is taken in build_render_state from editor.diff_signs_for_active(); absent ⇒ empty map.

§virtual_rows: Arc<VirtualRowsRenderState>

D.3.b.1 (2026-05-29): virtual-rows render state. Carries the published VirtualRowMatrix so the renderer can interleave deletion-block + multibuffer- header rows between document rows. Snapshot is taken in build_render_state from editor.virtual_rows_matrix_cell.load_full().

§paint_revision: u64

§12 async-result render-wake — the off-keystroke paint gate.

A content hash over every render-visible surface that is NOT owned by the cells / virtual-rows workers (those fire paint_request on their own content change). The actor’s off-keystroke arms (async_landed / inline-diag) compare this against the previously-published value and fire paint_request only when it moved, so an async arrival that changes the modeline badge, a diagnostics overlay, a popup, etc. reaches a frame without a keystroke — and a no-op publish does NOT (which also keeps the GPUI paint-bridge’s run_tick_pending → re-publish loop from spinning). Stamped by Editor::compute_paint_revision in build_render_state. The cells MatrixVersion axis is the dual: it gates cell rebuilds; this gates everything else (lattice-cells/src/version.rs enumerates the overlay set).

§wasm_gutter_decorations: PerBufferCache<WasmGutterDecorationCache>

PL8.E: per-buffer WASM gutter-decoration cache. A clone of Editor’s wasm_decorations.cache slot, so an off-render-path producer task’s writes are observed without republishing this snapshot. Renderers merge get_for(buffer_id).decorations into the same gutter partition they walk for Mode::gutter_decorations — the producer never runs at paint time (paramount #1). Empty when no decoration plugin is loaded.

§compilation_severity: Arc<HashMap<BufferId, Arc<Vec<(u32, GutterSeverityLevel)>>>>

CM.3c: per-buffer severity gutter index for the *compilation* buffer, keyed by [BufferId] (mirrors diff.sign_maps). Written by the AppEffect::CompilationGutterSet host arm from the off-thread compilation drain; each entry is the buffer’s full (line, level) list. Renderers look up compilation_severity .get(buffer_id) per pane and inject it into the mode’s gutter_decorations via lattice_mode::CompilationSeverityData — the renderer never depends on lattice-compilation. Empty when no compilation has produced marks. The value Arc makes both the publish clone and the render-path read O(1).

§compilation_location_lines: Arc<HashMap<BufferId, Arc<Vec<(u32, u32, u32)>>>>

CM.3c (2026-07-22): per-buffer compilation location-line index for theme-based highlighting of navigable lines in the *compilation* buffer. Written by the AppEffect::CompilationLocationLines host arm from the off-thread compilation drain; renderers check compilation_location_lines.get(buffer_id) when painting each line and apply the compilation.location theme element bg to any row whose index appears in the set. Empty when no compilation is active or no location lines have been produced. The value Arc makes both the publish clone and the render-path read O(1).

§code_block_lines: Arc<HashMap<BufferId, Arc<Vec<u32>>>>

MC.3: per-buffer set of source lines inside a fenced/indented code block. Snapshot of Editor::code_block_lines; renderers paint the full-width syntax.code_block background on any row whose index is in the set.

§compilation_theme_colors: Arc<(u32, u32)>

CM.3d (2026-07-22): snapshot of Editor::compilation_theme_colors.

Implementations§

Source§

impl RenderState

Source

pub fn content_left_pad_for(&self, buffer_id: BufferId) -> u32

Resolve the fold list + foldenable that a pane showing buffer_id must render with.

Folds are per-buffer (a buffer’s zf / za / computed + overlay folds are shared by every pane showing it — the user-confirmed model). The bug this fixes: both renderers previously sourced folds for every pane from active_document.folds, so an inactive pane showing a different buffer rendered with the active buffer’s folds — folding buffer A elided lines in buffer B’s pane (GPUI), and switching focus away made A’s inactive pane drop its folds (TUI). Both renderers now call this so the source is the pane’s own buffer, uniformly (TUI/GPUI parity).

The active buffer reads the live active_document.folds (freshest — updated synchronously on the fold keystroke); any other buffer reads its published per-pane entry in cells.panes (sourced from its DocumentFolds buffer-local). A buffer in no pane (no cells.panes entry) yields an empty list — nothing to elide. PI.0: the horizontal-centring pad for a pane rendering buffer_id. Resolved from THAT buffer’s CenterContentWidth local + the width of the pane showing it — never the active-buffer identity.

Previously the renderers gated centring on buffer_id == document_buffer_id, so a picker preview that swapped document_buffer_id to the previewed file collapsed the dashboard’s centring to 0 while the pane still showed the dashboard. Reading the rendered buffer’s own local keeps centring attached to the buffer that carries it. Shared by the TUI and GPUI peers.

Source

pub fn resolved_option_for<D: OptionDecl>( &self, buffer_id: BufferId, ) -> Arc<D::Value> ⓘ
where D::Value: Clone + Send + Sync + 'static,

PI.4: resolve option D for buffer_id from the published per-buffer resolved-options snapshot — the renderer-agnostic seam both peers use (mirror of Editor::resolved_option). Falls back to the global typed-option default when the buffer has no cached entry (transient publish gap / a buffer resolved lazily). O(1) TypeId lookup on the Arc-shared ResolvedOptions.

Source

pub fn current_line_highlight_for(&self, buffer_id: BufferId) -> bool

PI.4: whether a pane showing buffer_id paints its cursorline (:set cursorline / current-line-highlight-mode), resolved per-buffer. Both peers read this for the focused preview pane so the previewed buffer keeps its own cursorline (e.g. an LSP-reference / grep location preview keeps the target line highlighted).

Source

pub fn folds_for_buffer(&self, buffer_id: BufferId) -> (Arc<[Fold]>, bool)

Source

pub fn inlay_hints_for_buffer(&self, buffer_id: BufferId) -> Arc<[InlayHintRow]> ⓘ

Resolve the byte-baked inlay-hint rows a pane showing buffer_id must render.

Like Self::folds_for_buffer, this gives every pane its OWN buffer’s decoration so active and inactive panes render through ONE code path (inactive == active, modulo dimming). It replaces a duplicated seam where the active pane spliced the baked syntax.inlay_hints while inactive panes re-derived hints from the per-buffer LSP cache with their own utf-16→utf-8 conversion — two sources that could drift.

The active buffer reads the canonical baked list (syntax.inlay_hints); any other buffer reads its published cells.panes entry (built by build_inlay_hints_for_buffer, identical gating + byte-baking). A buffer in no pane yields empty.

Trait Implementations§

Source§

impl Clone for RenderState

Source§

fn clone(&self) -> RenderState

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RenderState

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for RenderState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> IntoMaybeUndefined<T> for T

§

fn into_maybe_undefined(self) -> MaybeUndefined<T>

Converts this value into a three-state builder argument.
§

impl<T> IntoOption<T> for T

§

fn into_option(self) -> Option<T>

Converts this value into an optional builder argument.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Pointee for T

§

type Pointer = u32

§

fn debug( pointer: <T as Pointee>::Pointer, f: &mut Formatter<'_>, ) -> Result<(), Error>

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more