^[control-codes live in libghostty-vt

C0 control characters

SO Shift Out

Switch the characters printed to the G1 set, and back to G0.

SO
ECMA-48
§8.3.126 SO – Shift-Out, p. 65
DEC STD 070
§3.8.3.1 Shift Out, p. 3-74
VT510
4.2 Control Characters

A terminal holds four graphic character sets at once, G0 to G3, and prints from whichever of them is invoked into GL, the left half of the code table (21 to 7E). SO invokes G1 into GL, and SI (0F) invokes G0 back. Both are locking shifts: everything printed after SO comes from G1, across any number of lines, until SI.

SI is ECMA-48 §8.3.119, p. 63 and DEC STD 070 §3.8.3.1, p. 3-73. ECMA-48 gives the two bytes other names in an 8-bit environment, LS1 and LS0, and leaves what they do to ECMA-35.

A set is designated into G0 to G3 with an escape sequence: ESC ( F, ESC ) F, ESC * F and ESC + F put the 94-character set with final byte F into G0, G1, G2 and G3 respectively. This is SCS, in DEC STD 070 §5.8.2, p. 5-117 and the VT510 manual’s SCS page. B is ASCII, and 0 is DEC Special Graphics, the set of line-drawing characters that full-screen programs draw boxes with: q becomes ─, x becomes │, and l, k, j and m become the corners ┌, ┐, ┘ and └. Those are the Unicode characters xterm maps them to (map_DEC_Spec_Graphic).

Designating a set into the slot already invoked changes what is printed from then on, with no shift needed; DEC STD 070 says so in its notes on SCS.

The shifts change only what is printed next. Characters already on the screen stay as they are.

Validation

SO-1: Out to G1, and back

\e)0      # G1 is DEC Special Graphics
\x0e      # SO
qxlkjm
\x0f      # SI
q
|─│┌┐┘└q___|

SO-2: The shift lasts across lines

\e)0      # G1 is DEC Special Graphics
\x0e      # SO
q\r\nq
\x0f      # SI
q
|─_________|
|─q________|

SO-3: Designating the set in use

\e(0      # G0, which is in use, is DEC Special Graphics
qx
\e(B      # and back to ASCII
qx
|─│qx______|