One screen cell: glyph + its visual attributes. Cell equality is
byte-perfect — two cells are equal iff their serialised bytes
would be identical, which is the invariant the diff relies on.
Visual attributes that can vary per cell in our footer. Kept minimal
on purpose: footer uses fg color, bold, and reverse-video
(for the palette’s selected row). Extending this to bg / underline
/ italic is a future concern — adding fields is the mechanical part,
but every field widens the diff equality surface and the SGR state
machine’s emit path, so we don’t preemptively carry what we don’t use.
A single cell’s worth of change: “put this cell at absolute position
(row, col)”. Multiple adjacent patches with the same style serialise
into one cursor move + a run of characters, so small clusters stay
cheap. Rows/cols are 1-indexed to match ANSI (\x1b[row;col H).
Slice-based cell-diff for the retained-mode Screen buffer.
Both frames are [Vec<Cell>] indexed by screen row (0..H-1),
with each inner Vec<Cell> indexed by screen col (0..W-1).
Unlike diff_cells, this variant doesn’t allocate a hashmap per
frame — Screen always knows all its rows upfront, so a contiguous
slice is both faster and maps 1:1 onto the 2D cells[row][col]
access pattern.
Append each char of s as cells, all sharing style. Wide chars
(CJK, emoji, etc.) expand to one real cell carrying the glyph +
(display_width - 1) continuation cells so cell_index == terminal_column holds across the row — critical for the cell-diff
to produce correct patches.
Like push_str_cells but parses embedded SGR escape sequences
(\x1b[...m) inline, mutating a working CellStyle so subsequent
cells pick up the colour / bold / faint / reverse attributes the
terminal would otherwise paint via raw ANSI. Returns the style
state at end-of-input so a caller wrapping a single physical line
into multiple chunks can carry attributes across chunk boundaries
(e.g. \x1b[31m on one chunk and \x1b[39m on the next).
Serialise patches into ANSI bytes with an SGR state machine: emit
cursor-position only when we’re jumping, emit SGR only when the
outgoing cell’s style differs from the last one we set, and run-pack
adjacent same-style patches into contiguous character streams.
Serialise a single row of cells into ANSI bytes without any cursor
positioning. Used by the scrollback-push path (write row to stdout
at the current cursor, then let \n advance). Skips continuation
cells; closes with \x1b[0m iff any SGR was emitted so subsequent
writes start from a clean state.