CUP — Set cursor position
Move the cursor to absolute row/column (1-indexed).
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[row;colH\033[1;1H\e[1;1HESC [ row ; col H1b 5b ... 48Description
Cursor Position. \x1b[row;colH moves the active cursor to the absolute row / column given. Both final bytes H (CUP) and f (HVP, Horizontal and Vertical Position) are synonyms — same behavior, same parameter shape, byte-for-byte interchangeable on every terminal in the support matrix above. Row and column are 1-based (not 0-based — VT100 / ECMA-48 inheritance). Omitting both parameters defaults to (1,1), i.e. the top-left corner of the screen or — when DECOM (origin mode) is set — the top-left of the active DECSTBM scrolling region. Out-of-range values are clamped to the visible region: \x1b[9999;9999H lands on the bottom-right corner, not somewhere off-screen. ECMA-48 §8.3.21 specifies the parameter semantics; xterm-ctlseqs documents the DECOM / DECSTBM interaction.
The top portability trap is the default-parameter trap. CSI default parameters are NOT uniformly 0 — \x1b[H defaults to (1,1) (move home), \x1b[;5H defaults the row to 1 (column 5, row 1), \x1b[5H is row 5 / column 1 (only first param given). Programs that rely on 'CSI defaults are 0' will silently corrupt layout — emit parameters explicitly when the value matters (see csi-default-params for the per-command default table). The other live trap is the DECOM / DECSTBM coordinate-frame shift: if your TUI has previously set a scrolling region with DECSTBM (\x1b[t;b r) AND switched on origin mode with DECOM (\x1b[?6h), \x1b[1;1H now lands at the top of the *region*, not the absolute screen top — your debug log line that 'should appear at row 1' silently moves into the middle of the screen. Detect by tracking your own origin-mode state, or unconditionally reset origin mode with \x1b[?6l before absolute positioning. Modern terminal coverage is uniform: xterm, iTerm2, kitty, alacritty, wezterm, ghostty, Windows Terminal, conhost.exe / ConPTY (Win10 1709+), Linux console, macOS Terminal.app — all honour the full CUP / HVP surface without quirks.
CUP is an absolute move — there's no 'undo' parameter. To return to the prior cursor position after a transient move, save first with DECSC (\x1b7) and restore with DECRC (\x1b8) — see cursor-save-restore. For relative cursor motion (up / down / left / right by N cells), use CUU / CUD / CUF / CUB (see cursor-move). The HVP alias \x1b[r;cf is documented separately at csi-hvp and accepts the exact same parameters — pick one form for your codebase and stay consistent. After positioning, common follow-ups are EL \x1b[K to clear the destination line (see erase-line) and EL plus SGR to paint a labelled status line in a known position.
Spec citation: ECMA-48 §8.3.21 (CUP)
Examples
printf '\033[2;5HHello at (2,5)\n'print('\x1b[2;5HHello at (2,5)')fmt.Print("\x1b[2;5HHello at (2,5)\n")process.stdout.write('\x1b[2;5HHello at (2,5)\n')printf("\x1b[2;5HHello at (2,5)\n");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- htop, top, btoprepaints the per-row stats grid in place each tick
- vim, neovim status line redraw
- tmux pane redraws
- less — re-positioning on scroll
Frequently asked
Short answers to the questions developers actually search for this sequence.
- Are row and column 0-based or 1-based?
- 1-based.
\x1b[1;1His the top-left corner;\x1b[1;1His also what\x1b[H(no parameters) defaults to. Row 0 / column 0 do not exist in ECMA-48 / VT100 — the convention is inherited from typewriter 1-indexed paper positions.\x1b[0;0His undefined and most terminals clamp it to (1,1). - What happens if I move beyond the screen, like
\x1b[9999;9999H? - Every conformant terminal clamps to the visible region: the cursor lands on the bottom-right cell, not off-screen. This is a common 'go to the last row' shortcut — paired with
\x1b[Kit erases from the bottom-left to right edge for a status line. Inside a DECSTBM scrolling region, clamping is to the region bounds, not the absolute screen. - Is
\x1b[H(CUP) the same as\x1b[f(HVP)? - Effectively yes. CUP (Cursor Position, final byte
H) and HVP (Horizontal and Vertical Position, final bytef) accept identical parameters and behave byte-for-byte the same on every terminal in the matrix above. The split is historical — VT100 shipped both. Pick one for your codebase;His by far the more common spelling in the wild.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- yes
- macOS Terminal.app
- yes
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- yes
- kitty
- yes
- alacritty
- yes
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- yes
- Konsole
- yes
- tmux
- yes
- GNU screen
- yes
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes | yes |