Skip to content

fix(emu): measure text in grid columns, group SGR 58, honour ?7h - #609

Merged
vyncint merged 2 commits into
mainfrom
fix/emulator-front
Oct 27, 2026
Merged

vyncint merged 2 commits into
mainfrom
fix/emulator-front

Conversation

@vyncint

@vyncint vyncint commented Oct 27, 2026

Copy link
Copy Markdown
Owner

Four emulator-front issues, on top of vt100 0.18.1 (#608).

#580 — text measured in the grid's columns. A new width::columns lays text out exactly as vt100 0.18 does: each character its own width, a zero-width one joining the cell before it, and the presentation selector widening an emoji. Neither unicode-width measure is that — a ZWJ family is one 2-column cluster to UnicodeWidthStr but two wide cells on the grid; ⚠️ is 1 column to a per-character sum but 2 on the grid. A test holds the model against vt100 itself for ten samples (CJK, combining, lam-alef, ZWJ, VS16, keycap, skin tone, flags). Used by:

  • insert mode's reservation (the ZWJ family overwrote AB, lam-alef A);
  • Screen::locate (reported history column 3 for text at column 5);
  • the termlens diff frame padding;
  • the text reader, so a saved ⚠️ reads back with the columns it was written at. Releases before this one gave it one column and the text does not say which wrote it: a row that only fits at one column per such cell reads the earlier way, so no file an earlier release wrote stops parsing.

An inserted run that wraps at the margin still overwrites the next row: doing it right needs the scroll region and origin mode, which termlens does not track. Documented in LIMITATIONS.md.

#579 — SGR 58. The grid's normalizer turns 58;5;n / 58;2;r;g;b into one colon parameter, which vt100 skips whole instead of reading 5 as blink and n as an attribute (58;5;0 reset the cell, 58;5;1 made it bold). Still recorded by unsupported(), as ^[[58:5:1m; the allocation-free fast path for plain SGRs is kept.

#581 — CSI ? 7 h is no longer recorded: it asks for autowrap, the emulator's only behaviour. ?7l is still recorded; LIMITATIONS.md says autowrap cannot be turned off.

#585 — documented, as the issue allows: vt100 records a wrap only where the last column held something, and a real fix needs per-row wrap state that survives scrolling, which vt100 has no API for. Screen::row_wrapped and LIMITATIONS.md now say so, with the issue's example.

Verification. Each fix has a test, and reverting it fails that test (insert mode, locate, the pad and the reader each to the string measure; the 58 grouping disabled). Full workspace suite, clippy, rustdoc -D warnings, DCO and attribution gates pass locally. No new PTY-spawning tests.

Closes #579
Closes #580
Closes #581
Closes #585

- A new width module lays text out as vt100 0.18 does: each character
  its own width, a zero-width one joining the cell before it, and the
  presentation selector widening an emoji. Insert mode, Screen::locate,
  the diff frame and the text reader use it; each measured a run as a
  string, which a ZWJ family, lam-alef and a skin-toned emoji are not
  (#580). The reader falls back to one column per selector cell when a
  row only fits that way, which is how earlier releases wrote it.
- The grid's colour normalizer turns a semicolon-form underline colour
  (58;5;n, 58;2;r;g;b) into one colon parameter, so vt100 skips it whole
  instead of taking its arguments for attributes (#579).
- CSI ? 7 h asks for the only behaviour the emulator has and is no longer
  recorded as unsupported; CSI ? 7 l still is (#581).

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
LIMITATIONS.md names the insert run that wraps at the margin, autowrap
off, and the wide character that wraps unrecorded over an empty last
column (#585); DESIGN.md section 3 gives the reader's width rule.

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
@vyncint
vyncint merged commit 35fdf9b into main Oct 27, 2026
16 checks passed
@vyncint
vyncint deleted the fix/emulator-front branch October 27, 2026 09:02
vyncint added a commit that referenced this pull request Oct 27, 2026
Resolves the CHANGELOG conflict with #609: both sets of entries kept.

Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant