Expand description
IM.1 — how much vertical space a source line’s display rows occupy, measured in line-heights.
§Why this exists
Scroll arithmetic counts display rows and assumes every row is one unit tall. That holds for the TUI forever — a terminal cell has one size — and it held for the GPUI peer until rows started differing in height (scaled markdown headings today, inline media blocks at IM.3).
The IM.0 audit found the damage is narrow but real: Editor::scroll is a
row index and survives untouched, but Editor::viewport_height is a row
count, computed as available_px / row_px against a uniform row_px.
Once rows differ, “how many rows fit” is not a constant — it depends on
which rows — so the seven functions that spend that number as a budget are
wrong. See docs/dev/architecture/inline-media.md §4.0.
§Why line-heights and not pixels
Pixels are a concept the TUI does not have, and this rides in shared host
state that both peers read. A line-height is a unit both peers have: the
TUI’s rows are all exactly 1.0, and GPUI’s are row_scale. Keeping the
core in line-heights is what stops a renderer concern leaking into
renderer-neutral types.
§Why keyed by source line
The scroll walks (bottom_anchored_scroll and friends) step by source
line and ask “how many display rows does this line cost”. Keying the
override the same way lets the weight replace that answer directly,
rather than forcing the walk to first resolve each line to a range of
display-row indices.
§The empty case is the important one
Almost every line is ordinary, so the map is sparse and
RowWeights::is_uniform is true in the overwhelming majority of
buffers — including every TUI buffer, always. When it is, cost returns
exactly default_rows as f32, so the converted arithmetic reduces to the
integer arithmetic it replaced. That property is the regression guard for
the whole slice: the TUI must behave identically before and after.
Structs§
- RowWeights
- Per-source-line vertical cost overrides, in line-heights.