Skip to main content

SO/SI

AI-Generated Content
This page was generated with the assistance of AI and may contain inaccuracies. It is intended as a placeholder for future human verification. If you spot issues ahead of its initial review, please report them on GitHub!
Standard

SO (Shift Out) and SI (Shift In) are C0 control characters used for character set switching. SO invokes the G1 character set into GL, while SI restores the G0 character set.

Syntax​

SO        0x0E      Shift Out — invoke G1 into GL
SI 0x0F Shift In — invoke G0 into GL
Formal syntax
SO = 0x0e ;
SI = 0x0f ;

Description​

Per ECMA-48 §8.3.126 and §8.3.119, SO and SI are used for code extension purposes, causing "the meanings of the bit combinations following it in the data stream to be changed." Their use is defined in ECMA-35.

In the VT100 character set architecture, four character sets (G0, G1, G2, G3) can be designated via escape sequences, and two of them can be active at once — one invoked into GL (the left half, 0x20-0x7F) and one into GR (the right half, 0xA0-0xFF).

  • SO (0x0E) invokes G1 into GL. Subsequent graphic characters in the 0x20-0x7F range are interpreted according to the G1 character set.
  • SI (0x0F) invokes G0 into GL, restoring the default mapping.

By default, G0 is ASCII and G1 is the DEC Special Graphics character set (line-drawing characters).

Common use​

The most common use of SO/SI is to enable line-drawing characters for drawing boxes and borders in TUI applications. A program sends SO to switch to the line-drawing set, outputs the box characters, then sends SI to return to ASCII.

note

In 8-bit environments, SO and SI are known as LS1 (Locking-Shift One) and LS0 (Locking-Shift Zero), respectively. They are functionally identical.

Examples​

# Draw a simple box using DEC line-drawing characters
printf '\e(B' # Designate ASCII into G0
printf '\e)0' # Designate DEC Special Graphics into G1
printf '\x0e' # SO — switch to G1 (line drawing)
printf 'lqqk\n' # ┌──┐
printf 'x x\n' # │ │
printf 'mqqj\n' # └──┘
printf '\x0f' # SI — switch back to G0 (ASCII)

Specifications​

SpecificationSection
ECMA-48§8.3.119, §8.3.126

Terminal support​

TerminalSupportVersionNotes
Terminal Emulators
Alacritty~YesCharset switching supported via configure_charset/set_active_charset, but only charsets B and 0 supported per escape_support.md
Bobcat✓0.9.0Character set handling in TerminalCtrl, UTF-8 mode configurable
contour✓v0.3.10SO (0x0E) and SI (0x0F) implemented as LS1/LS0; invokes G1/G0 charset into GL
foot✓YesImplemented in vt.c:241-255, selects G0/G1 character sets
Ghostty✓v1.0.0SO/SI handled in stream.zig:772-773, invoke G1/G0 charsets
iTerm2✓Yes
Kitty✓Yes
Konsole✓YesG1/G0 charset invocation
mintty✓YesSO (Shift Out/LS1) at src/termout.c:1715, SI (Shift In/LS0) at src/termout.c:1720
mlterm✓rel-0_2_1SO/SI handled natively; ISO-2022 encodings delegated to mef library
PuTTY✓0.45Implemented as LS1/LS0 for G1/G0 charset selection
Rio✓v0.0.28Shifts between G0 and G1 character sets
rxvt-unicode✓rxvt-unicode-1.2
st✓0.5Charset switching added in 0.5, control codes in 0.6
terminology✓v0.1.0
VT100✓Yes
VTE~YesImplemented as LS1/LS0. Only G1 character set mapping is functional
WezTerm✓YesHandled in performer.rs:466-470 via ControlCode::ShiftOut/ShiftIn, controls G0/G1 charset selection for DEC line drawing
Windows Terminal✓YesSI (0x0F) calls LockingShift(0), SO (0x0E) calls LockingShift(1) in OutputStateMachineEngine.cpp:74-78
xterm✓YesImplemented in charproc.c:3768-3780. SO/SI switch curgl between G0/G1
xterm.js✓2.3.0
Multiplexers
cy✗NoNot handled in Execute function
GNU Screen✓v.4.2.0SO/SI (Shift Out/In) implemented in Special() at src/ansi.c:697-702
tmux✓0.8Charset shift implementation for G0/G1 ACS
tuios✓v0.0.15
Zellij✓v0.7.0

See also​