pub struct DocView {Show 29 fields
pub rows: Vec<Row>,
pub frame: u32,
pub basis: u32,
pub row_start: u32,
pub replaced: u32,
pub row_count: u32,
pub src_shift: i32,
pub tables: Vec<TableView>,
pub directives: Vec<DirectiveView>,
pub media: Vec<MediaView>,
pub math: Vec<MathView>,
pub caret_row: u32,
pub caret_col: u32,
pub caret_ch: u32,
pub caret_src: u32,
pub has_selection: bool,
pub anchor_row: u32,
pub anchor_ch: u32,
pub dirty: bool,
pub can_undo: bool,
pub can_redo: bool,
pub view: String,
pub heading: Option<u32>,
pub code_block: bool,
pub blockquote: bool,
pub task: Option<bool>,
pub active: Vec<String>,
pub link: Option<String>,
pub mark_color: Option<MarkColor>,
}Expand description
A rendered frame: the rows to paint, where the caret sits, and the toolbar state — everything the Swift side needs for one repaint, in one value. Returned by every view-producing method.
§Whole or a change
By default every frame is whole: rows is every row of the document, and
the frame before it is forgotten. After LeafDoc::set_incremental_frames
the same methods answer with a frame whose rows are only the rows that
changed since the frame before — a caret move lifts none, a keystroke lifts
the row it landed on — and the five fields after rows say where they go.
Which kind a frame is, it says itself: basis is 0 on a whole frame and
the frame before’s number on a change. A caller applies a change to the
frame it holds (see rows), and one that holds a frame other than basis
has lost step and asks LeafDoc::view for a whole one, which every
change after that is against. The rest of the frame — the caret, the
selection, the toolbar state, tables, directives, media and math —
is complete on every frame of either kind.
Fields§
§rows: Vec<Row>The rows to paint: every row of the document on a whole frame, and on
a change (basis != 0) the rows that replace replaced of the frame
before’s from row_start, after which the rows that follow are the
frame before’s with src_shift added to every Run::src they carry.
So a frame is applied as: splice rows over row_start..row_start + replaced, then move the offsets of the rows after the splice. An
empty rows with replaced == 0 is a frame that changed no row.
frame: u32This frame’s number: one more than the frame before’s, from 1 at
the first. What a change names as its basis.
basis: u32The number of the frame these rows are a change against, or 0 when
they are the whole document. A change is applied only to a copy of
exactly that frame; see the type’s docs.
row_start: u32Where rows begin, as an index into the document’s rows — the
frame before’s and, since a change never moves the rows above it, this
one’s. 0 on a whole frame.
replaced: u32How many of the frame before’s rows, from row_start, rows replace.
0 on a whole frame.
row_count: u32How many rows the document has once this frame is applied — what
rows.len() is on a whole frame, so a caller sizing a scroll view
reads this on either kind.
src_shift: i32The byte offset every Run::src in a row after the replaced span
moved by — an edit shifts the source of everything below it, and
those rows are otherwise the frame before’s, so they are kept and
moved rather than lifted. 0 on a whole frame, and on a change that
moved nothing.
tables: Vec<TableView>Tables described structurally, for a frontend that draws its own grid
instead of painting the box-glyph rows. Empty in the source view. Each
names the span of the document’s rows its picture occupies, to be
skipped — an index into a whole frame’s rows, and into the rows a
change has been applied to. These lists are small and ride every
frame complete, so no frame has to say whether they changed.
directives: Vec<DirectiveView>Leaf directives (::name{…}) described structurally, for a frontend that
paints what the host app’s vocabulary makes of them instead of the ⧉
placeholder row. Empty in the source view, where the directive is the
literal text the caret is editing.
media: Vec<MediaView>Block-level images, videos, and audio described structurally, for a
frontend that lays real views over the rows core reserved instead of
painting the placeholder glyphs. Empty in the source view, where the
 or <video> markup is the literal text being edited.
math: Vec<MathView>Formulas standing as pictures — each inline atom and each display
block — for a frontend that typesets and draws them in place of the
math run or the placeholder rows. Empty in the source view, and
empty of any formula on the caret’s line, which is its TeX there.
caret_row: u32The caret’s row: an index into Self::rows.
caret_col: u32The caret’s display column within its row — core’s grid position. Kept
for callers reasoning in columns; a proportional renderer wants
Self::caret_ch instead.
caret_ch: u32The caret’s offset within its row’s text in UTF-16 code units — what
NSAttributedString/NSTextView count to. This is caret_col mapped
through the row’s grapheme widths, so it lands the caret correctly past
wide glyphs (CJK, emoji) where a column and a character index diverge.
caret_src: u32The caret’s source byte offset — the coordinate a table cell is keyed
by (TableCellView::start/end), so a frontend drawing its own grid can
find which cell the caret sits in without the picture-row indices.
has_selection: boolWhether a (non-empty) selection is active.
anchor_row: u32The selection’s fixed end (the caret is the moving end), as a row and a
UTF-16 offset — so the renderer can restore a native selection with the
same direction the model has. Equal to the caret when has_selection is
false.
anchor_ch: u32§dirty: boolWhether the buffer differs from the last saved bytes — for a “● modified” affordance.
can_undo: boolWhether there is a step to undo, and one to redo — what a native Edit
menu or an undo manager enables its items by. Both false on a read-only
document. Exact, not a bound: can_undo is true precisely when
LeafDoc::undo would move the document, so a host composing several
histories into one can ask before it dispatches.
can_redo: bool§view: String"wysiwyg" or "source", for a view-toggle affordance.
heading: Option<u32>The heading level at the caret, if any — a toolbar lights H1…H6 from it.
code_block: boolWhether the caret stands in a code block — the toolbar lights its Code
Block button from it. Rides the frame for heading’s reason: walking
the caret into a fence changes no mark, and a button asking for itself
would never be told.
blockquote: boolWhether the caret stands inside a block quote, at any depth — the
toolbar lights and ticks its Block Quote control from it. A quote wraps
blocks rather than being one, so this is true alongside heading or
code_block, not instead of them. Rides the frame for heading’s
reason.
task: Option<bool>Whether the list item at the caret carries a checkbox, and which way it
faces — Some(true) ticked, Some(false) empty, None for a plain
item or no item at all. A toolbar lights its Checklist button from the
first question and ticks its Checked item from the second. Rides the
frame for heading’s reason: stepping the caret from a bullet into a
task item changes no mark, and a button asking for itself would never
be told.
active: Vec<String>The inline marks active at the caret (bold, italic, code, …) — the
toolbar lights the matching buttons.
link: Option<String>The destination of the link the caret stands in, or None — the toolbar
lights its Link button from it and seeds an edit of that link with it.
It rides the frame rather than being a query a toolbar makes for itself
because a toolbar only redraws when the state changes: walking the caret
out of a link changes no mark, no heading, and no dirty flag, so a Link
button reading this by a call of its own would keep a stale light on. Same
reason heading is here and not asked for.
Only a parsed link answers (LeafDoc::link_destination_at_caret);
a wikilink is literal text with no node behind it, and has nothing to
repoint — see LinkTarget.swift.
mark_color: Option<MarkColor>The colour of the highlight the caret stands in — which swatch a colour
palette draws as the current one, and None both outside a highlight and
inside an uncoloured one.
It rides the frame for link’s reason, and more sharply: walking from a
red highlight into a blue one changes no mark, no heading, no dirty flag
and no link, so a palette asking for itself would never be told to move
its checkmark.
An enum rather than the name string Run::mark_color carries, because
the two are different questions. A run’s colour is a rendering hint that
has to survive a name this build has never heard of (a newer twig’s
eighth colour draws as a plain highlight rather than not at all); this is
the closed palette a control offers, and a name outside it is not a
swatch anyone can press.