LS2, LS3 Locking Shift Two and Three
Switch the characters printed to the G2 or G3 set.
LS2 Locking Shift Two
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
- VT220
- §4.4.3 Invoking Character Sets with Locking Shifts
- 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.
Support
| Terminal | Version | Support | Notes |
|---|---|---|---|
| VT220 | manual, 2nd ed., 1984 | Yes | §4.4.3 Invoking Character Sets with Locking Shifts, VT200 mode only |
| VT510 | manual, 1st ed., 1993 | Yes | LS, Level 4 mode only |
| xterm | patch 412, xterm-411a | Yes | |
| libghostty-vt | 0f171f6 | Yes | LS1R, LS2R and LS3R are accepted but have no effect |
| kitty | 0.49.1, run in a VM | No | fails the 3 cases that show it working |
| foot | 1.28.0, run in a VM | Yes | passes the 3 cases that show it working |
| pyte | 0.8.2, run as a library | No | fails the 3 cases that show it working |
| xterm.js headless | 6.0.0, run as a library | Yes | passes the 3 cases that show it working |
| alacritty_terminal | 0.26.0, run as a library | No | fails the 3 cases that show it working |
| ConEmu | build 230724, its documentation | No | not in ConEmu’s ANSI escape codes |
| rxvt-unicode | 9.31, run in a VM | Yes | passes the 3 cases that show it working |
| VTE | 0.84.1, run as a library | No | fails the 3 cases that show it working |
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________|