^[control-codes
live in libghostty-vt

Escape sequences

LS2, LS3 Locking Shift Two and Three

View as Markdown

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

TerminalVersionSupportNotes
VT220manual, 2nd ed., 1984Yes§4.4.3 Invoking Character Sets with Locking Shifts, VT200 mode only
VT510manual, 1st ed., 1993YesLS, Level 4 mode only
xtermpatch 412, xterm-411aYes
libghostty-vt0f171f6YesLS1R, LS2R and LS3R are accepted but have no effect
kitty0.49.1, run in a VMNofails the 3 cases that show it working
foot1.28.0, run in a VMYespasses the 3 cases that show it working
pyte0.8.2, run as a libraryNofails the 3 cases that show it working
xterm.js headless6.0.0, run as a libraryYespasses the 3 cases that show it working
alacritty_terminal0.26.0, run as a libraryNofails the 3 cases that show it working
ConEmubuild 230724, its documentationNonot in ConEmu’s ANSI escape codes
rxvt-unicode9.31, run in a VMYespasses the 3 cases that show it working
VTE0.84.1, run as a libraryNofails 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________|
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.