^[control-codes live in libghostty-vt

Control sequences

DECSTBM Set Top and Bottom Margins

Set the lines of the scrolling region.

CSI Pt ; Pb r
Defaults
Pt = 1, Pb = the last line
DEC STD 070
§5.4.3 Set Top and Bottom Margins, p. 5-25
VT510
DECSTBM—Set Top and Bottom Margins

Set the top margin to line Pt and the bottom margin to line Pb. The lines between them, both included, are the scrolling region: a line feed on the bottom margin scrolls only those lines, as RI on the top margin does the other way, and IL, DL, SU and SD act only inside it. A parameter left out, or 0, takes its default, so CSI r puts the margins back at the first and last lines of the screen.

The top margin has to be above the bottom one. DEC STD 070 says that if Pt is equal to or greater than Pb, the control “will be ignored (not executed)”: nothing changes, and the cursor does not move. A region is at least two lines.

It also says a bottom margin past the last line is ignored the same way. xterm instead takes it as the last line (CASE_DECSTBM), and esctest2’s test_DECSTBM_MaxSizeOfRegionIsPageSize expects that. libghostty-vt does as xterm does.

Setting the margins moves the cursor to the home position: the first column of the first line, or with origin mode on, the top and left margins. The left and right margins are set by DECSLRM.

Validation

DECSTBM-1: Homes the cursor

\e[3;2H
\e[2;3r
|_____|
|_____|
|_____|
|_____|
cursor 1,1

DECSTBM-2: A one-line region is ignored

1\r\n2\r\n3\r\n4
\e[3;3r   # top equal to bottom: not executed
\n        # so the whole screen scrolls
|2____|
|3____|
|4____|
|_____|
cursor 4,2

DECSTBM-3: A bottom margin past the screen

\e[1;2H
x
\e[2;9r   # the bottom is taken as line 4
\e[4;1H
\n        # scrolls lines 2 to 4 only
|_x___|
|_____|
|_____|
|_____|
cursor 4,1

DECSTBM-4: Left out, the margins are the screen’s

1\r\n2\r\n3\r\n4
\e[2;3r
\e[r      # back to lines 1 to 4
\e[4;1H
\n
|2____|
|3____|
|4____|
|_____|

DECSTBM-5: Homes to the margin in origin mode

\e[?6h    # origin mode
\e[2;3r
|_____|
|_____|
|_____|
|_____|
cursor 2,1