^[control-codes live in libghostty-vt
View as Markdown

Move the cursor left n columns.

CSI Pn D
Defaults
Pn = 1
ECMA-48
§8.3.18 CUB – Cursor Left, p. 36
DEC STD 070
§5.4.4 Cursor Backward, p. 5-47
VT220
§4.7 Cursor Positioning
VT510
CUB—Cursor Backward

Move the cursor Pn columns to the left. A 0 is taken as 1. The cursor stops at the left margin if it started at or right of it, and at the first column otherwise. It never moves to another line.

If a wrap is pending, the wrap is cancelled, as DEC STD 070 asks (§D.6.1, p. D-13) and xterm’s CursorBack does, and the cursor moves from the last column, so CSI D after filling a line leaves the cursor on the second-last column. (With xterm’s reverse wraparound mode on, the pending wrap instead uses up one of the Pn columns; that mode is off by default.)

The other three directions are CUU (A, up), CUD (B, down) and CUF (C, right), and they work the same way.

Support

TerminalVersionSupportNotes
VT220manual, 2nd ed., 1984Yes§4.7 Cursor Positioning
VT510manual, 1st ed., 1993YesCUB
xtermpatch 412, xterm-411aYes
libghostty-vt919dca5Yes
kitty0.49.1, run in a VMPartlyfails CUB-3, CUB-4 of the 4 cases that show it working
foot1.28.0, run in a VMPartlyfails CUB-4 of the 4 cases that show it working
pyte0.8.2, run as a libraryPartlyfails CUB-4 of the 4 cases that show it working
xterm.js headless6.0.0, run as a libraryPartlyfails CUB-4 of the 4 cases that show it working
alacritty_terminal0.26.0, run as a libraryPartlyfails CUB-4 of the 4 cases that show it working
ConEmubuild 230724, its documentationYeslists ESC [ cols D: ANSI escape codes
rxvt-unicode9.31, run in a VMPartlyfails CUB-4 of the 4 cases that show it working
VTE0.84.1, run as a libraryYespasses the 4 cases that show it working

Validation

CUB-1: Left n columns

ABCD
\e[3D
X
|AXCD_|

CUB-2: Stops at the first column

ABC
\e[99D
X
|XBC__|

CUB-3: From a pending wrap

ABCDE     # fills the line; a wrap is pending
\e[D
X
|ABCXE|
|_____|

CUB-4: Stops at the left margin

\e[?69h   # allow left and right margins
\e[2;4s   # margins at columns 2 and 4
\e[1;4H
\e[9D
X
|_X___|

DEC STD 070 is explicit that the cursor “will not move beyond the Left Margin” when it starts at or inside it, xterm and libghostty-vt stop there, and esctest2’s test_CUB_StopsAtLeftMarginInScrollRegion checks for it.

Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.