Skip to main content
ansicode

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[\x1b[row;colH
\\033[\033[1;1H
\\e[\e[1;1H
ESC [ESC [ row ; col H
hex1b 5b ... 48

Description

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

bash
printf '\033[2;5HHello at (2,5)\n'
python
print('\x1b[2;5HHello at (2,5)')
go
fmt.Print("\x1b[2;5HHello at (2,5)\n")
javascript
process.stdout.write('\x1b[2;5HHello at (2,5)\n')
c
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;1H is the top-left corner; \x1b[1;1H is 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;0H is 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[K it 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 byte f) 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; H is 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

Related sequences

In the family cookbook

CSI cookbook · 1. The envelope — `\x1b[` … `<final-byte>`