pub struct ActiveDocumentRenderState {Show 37 fields
pub buffer_kind: BufferKind,
pub document_buffer_id: BufferId,
pub active_pane_buffer_id: BufferId,
pub cursor: Position,
pub scroll: u32,
pub leftcol: u32,
pub viewport_height: u32,
pub modal: ModalState,
pub visual_anchor: Option<Position>,
pub snapshot: Arc<DocumentSnapshot>,
pub pending_count: u32,
pub op_count: u32,
pub macro_recording: bool,
pub completion_open: bool,
pub picker_open: bool,
pub chord_capture: bool,
pub snippet_active: bool,
pub popup_focused: bool,
pub command_line_active: bool,
pub search_line_active: bool,
pub terminal_insert_active: bool,
pub terminal_esc_exits: bool,
pub terminal_visual_active: bool,
pub terminal_app_cursor_keys: bool,
pub terminal_insert_exit_pending: bool,
pub terminal_program_name: Arc<str>,
pub terminal_nav_cursor: Option<(i32, u16)>,
pub terminal_visual: Option<TerminalVisualState>,
pub folds: Arc<[Fold]>,
pub all_matches: Arc<[Range]>,
pub current_match: Option<Range>,
pub visual_range: Option<Range>,
pub visual_block_extents: Option<BlockExtents>,
pub substitute_preview: Option<Arc<SubstitutePreview>>,
pub selections: Arc<SelectionSet>,
pub option_cache: OptionCache,
pub display_line_numbers: Option<Arc<[u32]>>,
}Expand description
Active buffer’s hot-path render-side projection.
Carries everything the renderer needs to draw the currently-
active buffer regardless of its kind (Document / Help /
Oil / FileTree). Per “everything is a buffer” (CLAUDE.md):
the same fields apply uniformly to every kind — the kind
itself is one of the carried fields.
Split out of BuffersRenderState (which is the registry
of all buffers) because read frequencies differ by orders of
magnitude:
- The active-buffer state churns on every motion / edit / scroll — per-frame critical.
- The registry churns only on
:b N/:e <path>/:bd.
Splitting lets Slice 3b republish them independently — a
motion republishes ActiveDocumentRenderState without forcing
BuffersRenderState to allocate a new Arc.
Phase 5.8.AF.5 / Slice 3c.1: populated. Renderers migrate
their direct editor.X reads to this sub-state in Slices
3c.2 (TUI) + 3c.3 (GPUI); the field set covers every paint-
time hot-path read.
Fields§
§buffer_kind: BufferKindBuffer kind (Document / Help / Oil / FileTree). The renderer’s paint switch dispatches on this for kind- specific overlays (oil row prefix, file-tree decorations, help anchors, …).
document_buffer_id: BufferIdBufferId of the currently-active document. For the
Document kind this equals active_pane_buffer_id; for
help / oil / file-tree the kinds may diverge (a help
popup sits over a document pane).
active_pane_buffer_id: BufferIdBufferId of the active pane’s surface (what the user sees in the focused pane). Used by per-pane reads.
cursor: PositionCursor position (line + byte). Per-frame critical.
scroll: u32First visible buffer line. Drives the viewport’s top.
leftcol: u32First visible display column (horizontal scroll). Drives the
body’s left clip when wrap is off; 0 under wrap.
viewport_height: u32Viewport height in screen-cell rows (active pane’s content area). Set by the renderer; read back here for motions, scroll math, and the gutter.
modal: ModalStateModal state (Normal / Insert / Visual / OpPending / Command / Search / Replace). Drives cursor shape, the modeline label, and gates per-mode paint behavior.
visual_anchor: Option<Position>Visual selection anchor; None when not in Visual.
snapshot: Arc<DocumentSnapshot>Active document’s snapshot pointer (cheap rope Arc
clone). Captured at publication time so the renderer
holds a per-frame consistent view. Wait-free read for
downstream consumers (line iteration, byte indexing).
pending_count: u32Pending motion-count accumulator (e.g. 3 in 3dw).
Slice 3c.atomic.J: mirrored here so the input translator
can build its TranslateContext from a published snapshot
instead of reaching through app.editor.X per keystroke.
op_count: u32Operator-pending count (e.g. 2 in d2w). Same
rationale as pending_count.
macro_recording: booltrue while a macro is being recorded (q<reg>).
Used by the translator to gate the q rebind and by the
modeline’s recording indicator.
completion_open: booltrue while the insert-completion popup is open.
Gates insert-mode keystroke translation (Tab cycle,
CR accept, Esc dismiss).
picker_open: booltrue while a picker overlay is open. Gates the
normal-mode keymap so picker-local keys take precedence.
chord_capture: booltrue while the : line sits on an ArgKind::Chord arg slot
(e.g. the armed :describe-key prompt) — the next keystroke is
CAPTURED as that chord, not dispatched. Published (computed via
[crate::dispatch::Editor::chord_capture_active]) so the actor-based
GPUI peer can read it the same way the TUI App computes it live;
drives TranslateContext::chord_capture.
snippet_active: booltrue while a snippet’s tab-stop chain is active.
Gates Tab / S-Tab to drive next_tabstop / prev_tabstop
instead of falling back to insert-completion / outdent.
popup_focused: boolPU refactor (2026-07-22): true when a Steal popup has
keyboard focus (State B). Replaces the architectural leak
where active_buffer == BufferKind::Help doubled as a
focus-state canary. Set/cleared in Editor’s popup-
mutation methods; published here so TUI and GPUI renderers
read popup_focused directly instead of re-deriving it
from buffer_kind.
command_line_active: boolMB.1 (rich minibuffer): true while the *command-line* buffer
is focused for editing (the : line is open). Swapping
self.document to that buffer would otherwise make the active
pane render the command-line text; renderers read this flag to
route the active pane to its own (registry-keyed) buffer instead —
the Help-popup pattern. See docs/dev/architecture/rich-minibuffer.md.
search_line_active: boolMB.5: true while the *search-line* buffer is focused for
editing (a / or ? search is being typed). Same semantics as
command_line_active — renderers read this flag to route the
active pane to its own (registry-keyed) buffer.
terminal_insert_active: boolTerminal-mode T2.a (2026-05-25): true when
terminal-insert-mode is active on the active Terminal
buffer. Drives the translate-layer branch that encodes
keystrokes to ANSI bytes (and emits
Action::TerminalInput) instead of running them through
the normal-in-terminal vim grammar.
terminal_esc_exits: boolTerminal-mode T2.b.0 (2026-05-25): resolved value of the
terminal.esc-exits typed option. Mirrored into the
render state so the input translator can build its
TranslateContext from the published snapshot rather
than reaching into editor.config per keystroke. When
true, <Esc> while terminal_insert_active emits
Action::ExitTerminalInsert instead of encoding to
\x1b for the PTY.
terminal_visual_active: boolTerminal-mode T3.b.2 (2026-05-25): true when the
active Terminal buffer has a linewise Visual selection
in flight (i.e. TerminalBuffer::visual.is_some()).
Drives the modeline label (TERMINAL-VISUAL) and the
translate-layer routing for j / k (extend head vs
scroll viewport) without renderers having to reach into
the buffer registry themselves.
terminal_app_cursor_keys: boolTerminal-mode T2.c (2026-05-25): DECCKM bit read from
the active terminal’s alacritty Term. When true,
the translate layer feeds it to
keymap_terminal::key_to_ansi_with_mode so arrow keys
encode as SS3 (ESC O A) rather than CSI
(ESC [ A). Programs like vim / less / htop / fzf
flip this with ESC [ ? 1 h.
terminal_insert_exit_pending: boolTerminal-mode T2.c (2026-05-25): true between the
<C-\> arming chord and the subsequent confirm key.
When set, the next translate call routes:
<C-n>→ExitTerminalInsert- any other chord → encode
\x1c+ the chord’s normal PTY bytes
Cleared by both paths so the next chord starts fresh.
terminal_program_name: Arc<str>2026-05-25: program basename (“zsh”, “bash”, “cargo”) of
the child process driving the active Terminal buffer.
Published from TerminalBuffer::program_name so the
modeline can surface “what’s running here” rather than
the generic TERMINAL label. Empty when the active
buffer is not a Terminal.
T-clean-1 Phase A.1 (2026-05-28): the active Terminal
pane’s cursor in alacritty grid coordinates
(absolute_line, col). Derived by the publisher from
self.cursor (doc-space) + synthetic.origin_top_line.
Renderers read this instead of reaching into
TerminalBuffer::nav_cursor so the bespoke mirror can
retire (Phase A.3). None when the active buffer is
not a Terminal or has no SyntheticDoc (Insert mode).
terminal_visual: Option<TerminalVisualState>T-clean-1 Phase A.1 (2026-05-28): published copy of
TerminalBuffer::visual for renderer consumption. Same
shape as on the buffer (grid coords). Renderers read
this so the buffer-side field can later move to a
doc-space source. None when not in terminal-Visual.
folds: Arc<[Fold]>Phase 5.8.AF.5 / Slice 3c.final.B (group 2): folds for
the active document. Renderers read
rs.active_document.load().folds instead of app.editor.folds.
Arc<[Fold]> so subsequent reader frames share the
allocation; typical fold count is <20 so cloning at
publish-time is sub-µs.
all_matches: Arc<[Range]>Hlsearch matches in the active document. Each entry is a
ProtoRange covering one occurrence; the renderer paints
every range with the softer match bg. Cap is bounded by
:set max_hits (default 1000) so the clone is bounded.
current_match: Option<Range>Primary search hit the cursor sits on (painted with the
strongest match colour). None outside Search mode.
visual_range: Option<Range>Resolved visual selection range (anchor → head, normalised).
None when not in Visual. Mirrors the host’s
Editor::visual_selection_range() helper so renderers don’t
need to reach for that method through &Editor.
visual_block_extents: Option<BlockExtents>Rectangular block extents when modal == Visual(Blockwise),
None otherwise. Renderers prefer this over visual_range
in Blockwise — visual_range only expresses a linear span
and can’t represent the per-line column band a block needs.
Mirrors [crate::visual::Editor::visual_block_extents].
substitute_preview: Option<Arc<SubstitutePreview>>:s/pat/repl/... preview overlay. None while no
substitute is being typed. The renderer paints the
match ranges (and replacement text, if any) with the
destructive-preview colour. Arc for cheap cloning.
selections: Arc<SelectionSet>Active document’s selection set (multi-cursor / linewise /
blockwise). Already an Arc on RopeDocumentHandle so this
is one Arc bump.
option_cache: OptionCacheHot-path option cache (typed-options resolved values).
Copy so the publish is a plain struct move. Used heavily
by per-row paint (whitespace glyphs, current-line highlight,
line-number style).
display_line_numbers: Option<Arc<[u32]>>K.4.6 follow-up (2026-06-02): per-composed-row source line
number lookup. None for regular Documents (the gutter
uses the composed row index, which IS the source line
number — identity mapping). Some(arr) for Multibuffer
views, where arr[composed_row] gives the source line
number in the originating source buffer.
The renderer’s render_gutter_for reads
arr[composed_row] when present and formats THAT as the
gutter label, so the user sees the actual source file’s
line numbers (e.g. 429, 430, 432 — skipping non-hit
lines) rather than the composed-buffer row indices
(0, 1, 2 — meaningless for navigation).
Substrate-published per Option (a) confirmed in the K.4.6 design discussion: the gutter has one job (“show this row’s display line number”), the mapping is data, no kind-special-casing in the renderer.
Trait Implementations§
Source§impl Clone for ActiveDocumentRenderState
impl Clone for ActiveDocumentRenderState
Source§fn clone(&self) -> ActiveDocumentRenderState
fn clone(&self) -> ActiveDocumentRenderState
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 ActiveDocumentRenderState
impl Debug for ActiveDocumentRenderState
Auto Trait Implementations§
impl Freeze for ActiveDocumentRenderState
impl RefUnwindSafe for ActiveDocumentRenderState
impl Send for ActiveDocumentRenderState
impl Sync for ActiveDocumentRenderState
impl Unpin for ActiveDocumentRenderState
impl UnsafeUnpin for ActiveDocumentRenderState
impl UnwindSafe for ActiveDocumentRenderState
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