Skip to content

CSI scrolling and margins

Status: Standard (SU/SD), DEC (margins), xterm (scrollback controls).

Scrolling moves rows within the scrolling region, which defaults to the whole screen. Only text scrolled off the top of the primary screen's region enters scrollback, and only when the region is the full screen in most emulators.

Scroll commands

Name Sequence Default Effect
SU CSI Ps S 1 Scroll region up Ps rows; blank rows enter at the bottom
SD CSI Ps T 1 Scroll region down Ps rows; blank rows enter at the top
IND ESC D Cursor down; scrolls at the bottom margin
RI ESC M Cursor up; scrolls at the top margin
NEL ESC E Like CR LF
LF, VT, FF 0x0a, 0x0b, 0x0c Cursor down; scroll at the bottom margin; CR too if LNM (CSI 20 h)

CSI Ps T with five parameters is xterm's mouse highlight-tracking initiator (XTHIMOUSE), and CSI > Ps T resets title-mode features. Parsers must dispatch on the parameter count and private marker.

Vertical margins: DECSTBM

CSI Pt ; Pb r      set top and bottom margins (1-based, inclusive)
CSI r              reset to the full screen

Setting margins moves the cursor to the home position (respecting origin mode). A region of fewer than two rows is rejected. Applications use DECSTBM to keep a status line fixed while output scrolls above it; DECRQSS with r reads it back.

Horizontal margins: DECSLRM

Status: DEC (VT420), opt-in.

CSI ? 69 h         DECLRMM: enable left/right margin mode
CSI Pl ; Pr s      DECSLRM: set left and right margins
CSI ? 69 l         disable; `CSI s` reverts to SCOSC

Support exists in xterm, WezTerm, Ghostty, foot, Contour, and Windows Terminal; VTE, Alacritty, and xterm.js do not implement it (xterm.js documents it as unsupported). Because CSI s changes meaning, applications must check ?69 support with DECRQM before enabling it.

Scrollback

Scrollback is outside every standard. Emulator conventions:

Control Meaning Status
CSI 3 J Clear scrollback xterm
?1049 Alternate screen, which has no scrollback xterm
?1007 Alternate scroll: wheel sends arrow keys on the alternate screen xterm
?1010 Scroll to bottom on output xterm
?1011 Scroll to bottom on key press xterm
CSI ? Ps ; … t, Ps = 14 Reserved by xterm for scrollback size reports; not implemented
CSI Ps + T Unscroll: move Ps rows from scrollback back onto the screen, pushing the region down; the inverse of SU into scrollback (kitty 0.20.2+, mintty 3.5.2+); CSI Ps T without the intermediate stays SD Extension

When the scrolling region is smaller than the screen, rows scrolled off its top are discarded, not archived. Terminals differ when the region starts at row 1 but ends above the bottom; xterm archives, several others do not. Applications that want output preserved should leave the region at the full screen.

Reverse wraparound

?45 (xterm reverseWrap) lets BS at column 1 move to the end of the previous row. Off by default; used by shells that redraw long prompts.

Probe

printf '\033[5;10r'; seq 1 30; printf '\033[r'      # only rows 5-10 scroll
tools/query decrqss r                      # DECRQSS: expect ^[P1$r5;10r^[\ before the reset
tools/query mode 69                        # DECRQM: 1/2 supported, 0 unknown

Sources

Compatibility

Feature support by terminal. Imported claims have not been reverified; unknown is not unsupported.
Feature / stable ID Alacritty Apple Terminal ConPTY (conhost) Contour DomTerm foot Ghostty iTerm2 kitty Konsole mintty mlterm PuTTY Revenant RLogin st tmux rxvt-unicode VTE wayst WezTerm Windows Terminal xterm xterm.js
SU/SD
csi-su-sd-scroll
SupportedImported · unverified SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified Unknown Unknown SupportedImported · unverified Unknown Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified
DECSTBM
csi-decstbm
SupportedImported · unverified SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified Unknown Unknown SupportedImported · unverified Unknown Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified
DECSLRM / ?69
csi-decslrm
Unknown Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified UnsupportedImported · unverified
1007 alternate scroll
dec-mode-1007-alternate-scroll
SupportedImported · unverified Unknown Unknown Unknown Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified
?45 reverse wrap
dec-mode-45-reverse-wrap
Unknown Unknown Unknown SupportedImported · unverified Unknown Unknown SupportedImported · unverified Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified
SL shift left
csi-sl
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown
SR shift right
csi-sr
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown
SU scroll up
csi-su
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown
SD scroll down
csi-sd
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown
Unscroll (CSI + T)
csi-plus-t-unscroll
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Supported Unknown Supported Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown