LS2 Locking Shift Two
Switch the characters printed to the G2 or G3 set.
ESC n
- ECMA-48
- §8.3.78 LS2 – Locking-Shift Two, p. 49
- DEC STD 070
- §3.8.3.1 Locking Shift Two, p. 3-75
- VT510
- Table 4–8
LS2 invokes the G2 set into GL, and LS3 (ESC o) the G3 set: everything printed after it comes from that set, until another shift. They do for G2 and G3 what SO does for G1, and SI undoes them by invoking G0 again. G2 and G3 are filled with ESC * F and ESC + F.
LS3 is ECMA-48 §8.3.80, p. 50 and DEC STD 070 §3.8.3.1, p. 3-76. DEC STD 070 says both are there “for interchange compatibility with ISO and ANSI standards”, and that they are “not to be used by conforming software”.
LS1R, LS2R and LS3R (ESC ~, ESC } and ESC |) invoke G1, G2 and G3 into GR instead, the right half of the code table, A1 to FE. That half exists only where the input is 8-bit codes. libghostty-vt decodes its input as UTF-8, where A1 to FE are not bytes of their own but parts of multi-byte characters. It accepts the three sequences and records the choice, but print in Terminal.zig never consults GR, so they have no effect.
Validation
LS2-1: G2 into GL, then back
\e*0 # G2 is DEC Special Graphics
\en # LS2
qx
\x0f # SI: G0 again
q
|─│q_______|
LS2-2: G3 into GL, then back
\e+0 # G3 is DEC Special Graphics
\eo # LS3
qx
\x0f # SI: G0 again
q
|─│q_______|
LS2-3: The shift lasts across lines
\e*0 # G2 is DEC Special Graphics
\en # LS2
q\r\nq
\x0f # SI
q
|─_________|
|─q________|