^[control-codes live in libghostty-vt

Control sequences

SL Scroll Left

Move the contents of the scrolling region left or right by n columns.

CSI Pn SP @
Defaults
Pn = 1
ECMA-48
§8.3.121 SL – Scroll Left, p. 63
xterm
Functions using CSI

CSI Pn SP @ (SL) moves what is on the screen Pn columns to the left, and CSI Pn SP A (SR) moves it Pn columns to the right. They are SU and SD turned on their side. ECMA-48 defines SR at §8.3.135, p. 68. Neither is in DEC STD 070 or the VT510 manual: DEC’s terminals scroll sideways with DECIC and DECDC and DECBI and DECFI instead.

xterm implements both (CASE_SL, CASE_SR), and calls them “from ISO 6429, not found in any of DEC’s terminals” (xtermScrollLR). It does the same as DECDC or DECIC with the cursor at the left margin (xtermColScroll):

  • every line of the scrolling region moves, and only the part of it between the left and right margins;
  • SL loses the columns that pass the left margin and brings in blank ones at the right margin, SR the other way round;
  • a 0 is taken as 1, and a count larger than the region empties it;
  • the cursor does not move;
  • if the cursor is outside the margins, top, bottom, left or right, nothing happens.

libghostty-vt ignores SL and SR. Its CSI dispatch in stream.zig has no case for @ or A with a space intermediate, so the cases below that change the screen are marked as known differences.

The space matters: CSI Pn @ is ICH and CSI Pn A is CUU.

Validation

SL-1: Scroll left

ABCDE\r\n
FGHIJ
\e[1;3H
\e[\s@    # SL by one column
|BCDE____|
|GHIJ____|
cursor 1,3

SL-2: Scroll right

ABCDE\r\n
FGHIJ
\e[1;3H
\e[2\sA   # SR by two columns
|__ABCDE_|
|__FGHIJ_|
cursor 1,3

SL-3: Zero is one

ABCDE
\e[1;1H
\e[0\s@
|BCDE_|
cursor 1,1

SL-4: More than the width empties the region

ABCDE\r\n
FGHIJ
\e[2;2H
\e[9\sA
|_____|
|_____|
cursor 2,2

SL-5: Only the scrolling region moves

ABCDE\r\n
FGHIJ\r\n
KLMNO\r\n
PQRST
\e[2;3r   # scrolling region: lines 2 and 3
\e[2;1H
\e[\s@
|ABCDE|
|GHIJ_|
|LMNO_|
|PQRST|
cursor 2,1

SL-6: Between the left and right margins

ABCDEF\r\n
GHIJKL
\e[?69h   # allow left and right margins
\e[2;5s   # margins at columns 2 and 5
\e[1;3H
\e[\s@    # SL: in from the right margin
|ACDE_F|
|GIJK_L|
cursor 1,3

SL-7: SR between the margins

ABCDEF\r\n
GHIJKL
\e[?69h
\e[2;5s
\e[1;3H
\e[2\sA   # SR by two: lost past the right margin
|A__BCF|
|G__HIL|
cursor 1,3

SL-8: Nothing happens with the cursor outside the margins

ABCDEF\r\n
GHIJKL
\e[?69h
\e[3;5s
\e[1;1H   # left of the left margin
\e[\s@
\e[2\sA
|ABCDEF|
|GHIJKL|
cursor 1,1

SL-9: Nor above the scrolling region

ABCDE\r\n
FGHIJ\r\n
KLMNO
\e[2;3r
\e[1;3H   # above the top margin
\e[\s@
|ABCDE|
|FGHIJ|
|KLMNO|
cursor 1,3
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.