grid: cell-shifting operations split wide pairs #12

Closed
opened 2026-10-01 12:50:20 +09:00 by natsukium · 0 comments
Owner

ICH, DCH, SL/SR, the IRM insert in put_grapheme, DECSLRM-bounded shifts, alt-screen truncating resize and DECCRA move cells and then repair only the vacated span, never the shift boundaries. A wide pair crossing a boundary is split, for plain wide chars too.

Repros (_ = Spacer):

  • Orphan Spacer: DCH on a left half 字b\r\e[P → _|b; ICH on a right half 字b\r\e[C\e[@ → ·|·|_|b; IRM on a right half 字b\r\e[C\e[4hX → ·|X|_|b.
  • Wide char left in the last column with no Spacer (glyph overflows the edge or margin): ICH on a full line abcdef字\r\e[@; SR \e[1 A; IRM \r\e[4hX; DECSLRM + ICH \e[?69h\e[1;4sab字\e[1;1H\e[@; DECSLRM + DCH \e[?69habc字x\e[1;4s\e[1;1H\e[P → b|c|字|·.
  • Alt-screen resize 8 → 4 columns with 字 at cols 3–4 → a|b|c|字.
  • DECCRA copies a lone Spacer.
  • VS16 widening checks the screen width, not the right margin: \e[?69h\e[1;7s\e[1;7H❤️ puts the Spacer outside the margin.
  • A width-2 cluster whose widen was refused (last column, occupied neighbour) sits in one cell; rewrap_run (lib.rs ~2046) later synthesizes a Spacer on resize, shifting the line right.

Where: ich / dch (crates/felis-grid/src/editing.rs ~1631–1690), scroll_region_horizontal, IRM path in put_grapheme, resize truncation, DECCRA.

ICH, DCH, SL/SR, the IRM insert in `put_grapheme`, DECSLRM-bounded shifts, alt-screen truncating resize and DECCRA move cells and then repair only the vacated span, never the shift boundaries. A wide pair crossing a boundary is split, for plain wide chars too. **Repros** (`_` = Spacer): - Orphan Spacer: DCH on a left half `字b\r\e[P` → `_|b`; ICH on a right half `字b\r\e[C\e[@` → `·|·|_|b`; IRM on a right half `字b\r\e[C\e[4hX` → `·|X|_|b`. - Wide char left in the last column with no Spacer (glyph overflows the edge or margin): ICH on a full line `abcdef字\r\e[@`; SR `\e[1 A`; IRM `\r\e[4hX`; DECSLRM + ICH `\e[?69h\e[1;4sab字\e[1;1H\e[@`; DECSLRM + DCH `\e[?69habc字x\e[1;4s\e[1;1H\e[P` → `b|c|字|·`. - Alt-screen resize 8 → 4 columns with 字 at cols 3–4 → `a|b|c|字`. - DECCRA copies a lone Spacer. - VS16 widening checks the screen width, not the right margin: `\e[?69h\e[1;7s\e[1;7H❤️` puts the Spacer outside the margin. - A width-2 cluster whose widen was refused (last column, occupied neighbour) sits in one cell; `rewrap_run` (`lib.rs` ~2046) later synthesizes a Spacer on resize, shifting the line right. **Where:** `ich` / `dch` (`crates/felis-grid/src/editing.rs` ~1631–1690), `scroll_region_horizontal`, IRM path in `put_grapheme`, resize truncation, DECCRA.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis#12
No description provided.