Expand description
What one frame’s rows are as a change from the frame before’s.
A binding answers every gesture with a frame — the rows to paint, and where the caret is among them — and lifting a whole frame across a boundary (UniFFI records into Swift, serde into JS objects) costs the document, not the gesture: on a long document the lift is most of a keystroke and all of a click. Both renderers already keep the rows a frame did not change, so what is left to make cheap is the crossing, and the way to do that is to cross only the rows that changed.
A binding does not need to know why rows changed to know which did.
It keeps the rows it last handed out and takes the common prefix and
suffix against the ones it is about to: comparing a few hundred rows in
memory is microseconds, and what falls between is exactly the span a
renderer diffing whole frames would have found for itself. The one wrinkle
is that a row carries the source offset each of its runs came from, and a
keystroke moves every offset after it — so read by ==, every row below
an edit is a different row, and the “span” is half the document. A row
after the edit is the same row moved, and the suffix is matched on that
footing: equal in everything, with its offsets shifted by one constant,
which the frame then carries so the renderer moves its own copies the same
way. The shift is read off the rows and checked on every row it is claimed
for, never assumed from the edit, so a frame reproduces the rows exactly
or names the row as changed.
This module is the algorithm; each binding supplies what “the same row,
shifted” means for its own row type, and the fields the frame carries the
answer in are documented on the binding’s DocView.
Structs§
- RowDelta
- Where two frames’ rows differ: the span of the old rows a span of the new
ones replaces, and the offset the rows after it moved by. See
row_delta.
Functions§
- apply_
row_ delta - Apply
delta— with the rowsspanit stands for — torows, the frame before’s, so they become the frame’s: the reference for what a renderer does with the fields, and what the bindings’ tests apply a sequence of frames with.shift(row, by)moves every offset the row carries. - row_
delta - The change from
oldtonew, as the span outside their common prefix and suffix.