SUB Substitute
Display an error character in place of something that could not be received, abandoning any sequence in progress.
SUB
- ECMA-48
- §8.3.148 SUB – Substitute, p. 71
- DEC STD 070
- §5.9 Substitute, p. 5-132
- VT510
- 4.2 Control Characters
SUB stands in for a character that arrived damaged. ECMA-48 says it is “used in the place of a character that has been found to be invalid or in error”, and does not say what a terminal shows. DEC STD 070 does: SUB places “a reversed question mark” at the cursor, as an error character, which the VT100 and its relatives drew as a checkerboard “blotch” instead. Unicode encodes the reversed question mark as U+2426, SYMBOL FOR SUBSTITUTE FORM TWO, ␦.
Inside a sequence, SUB also abandons it, as CAN does. DEC STD 070 (§3.5.1.2.2, p. 3-19) says it ends any sequence in progress “without execution”, and that SUB and the characters after it are then “interpreted normally”: the error character is displayed. The VT510 manual says the same, and adds device control strings.
xterm, emulating a VT220 or later, displays U+2426 in CASE_SUB, and the checkerboard U+2592 when emulating a VT100.
Validation
SUB-1: Displays the error character
AB
\x1a # SUB
C
|AB␦C_|
cursor 1,5
libghostty-vt displays nothing for SUB, and the cursor does not move, so the C lands where the error character should be. Its parser does abandon a sequence on SUB, as on CAN, but stream.zig has no handling for the character itself: a comment there says “We don’t currently have any handling for 0x18 or 0x1A”, and its C0 dispatch logs SUB as an “invalid C0 character, ignoring”. DEC STD 070, the VT510 manual and xterm all display an error character.
SUB-2: Abandons a control sequence
A
\e[3 # CUF, unfinished
\x1a
C
|A␦C__|
libghostty-vt does abandon the sequence, so the C is printed rather than taken as the final byte of CUF. It fails only because, as in SUB-1, no error character is displayed.