Skip to main content
ansicode

HVP — Horizontal and vertical position (CSI f, alias of CUP)

Move the cursor to absolute (row, col) — semantically identical to CUP but uses final byte f instead of H.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[<row>;<col>f
\\033[\033[1;1f
\\e[\e[1;1f
ESC [ESC [ row ; col f
hex1b 5b ... 66

Description

Horizontal and Vertical Position. ECMA-48 §8.3.61 defines HVP with the SAME semantics as CUP (\x1b[r;cH, §8.3.21) — move the cursor to the absolute 1-based row/col, default (1,1), values clamped to the visible region. The difference is purely the final byte: H (0x48) for CUP, f (0x66) for HVP. Both are widely emitted in the wild — some applications still use the older f form, notably parts of curses' default capability table and certain DEC VT-clone test vectors. Treat HVP exactly like CUP when decoding; emit CUP (H) when writing new code unless you need to match a legacy stream. Note: in ECMA-48 HVP was historically the canonical primitive and CUP the synonym; xterm-ctlseqs reverses the relationship and treats CUP as primary, reflecting modern usage.

Spec citation: ECMA-48 §8.3.61 (HVP) / xterm-ctlseqs

Examples

bash
printf '\033[2;5fHello at (2,5)\n'   # same as \033[2;5H
python
print('\x1b[2;5fHello at (2,5)')
go
fmt.Print("\x1b[2;5fHello at (2,5)\n")
javascript
process.stdout.write('\x1b[2;5fHello at (2,5)\n')
c
printf("\x1b[2;5fHello at (2,5)\n");

Used in

Real-world tools that emit this sequence — anchors the bytes to commands you've already used.

  • DEC VT510 RM applications (historical)DEC's VT510 Reference Manual presents HVP as the canonical positioning sequence — pre-1990 VAX / VMS apps written against the VT100-family manuals emit `\x1b[<r>;<c>f` everywhere even though they could have used CUP. Reading these legacy listings is the main place modern engineers encounter HVP
  • WordPerfect for DOS cursor positioningWordPerfect 5.x emitted HVP for cell positioning on DEC and IBM-3151 terminals — the product's Windows port dropped HVP support but DOS executables still in archival use produce the byte sequence when shelled out from DOSBox over a real serial line
  • ncurses fallback when `cup` cap is missingif a terminfo entry lacks the `cup` (cursor address) capability but defines `hpa` + `vpa`, ncurses falls back to HVP-style composed addressing — rare in practice (every modern entry has `cup`), but `tic` / `infocmp` will compile a `cup=\E[%i%p1%d;%p2%df` cap if the entry author wrote it
  • mosh state-replay enginemosh's terminal-state diff replay treats CUP and HVP as fully equivalent during the SSP frame-rebuild pass — its parser maps `H` and `f` final bytes to the same `move_cursor(row, col)` state mutation, so a legacy stream emitting HVP replays correctly across reconnects
  • `tic` / `infocmp` terminfo round-tripround-tripping an old `vt100` or `vt220` terminfo through `infocmp -L` → `tic` will preserve the `cup=\E[%i%p1%d;%p2%df` HVP-form if it was authored that way — useful when porting a 1990s mainframe terminfo entry to a modern Linux box and you want to keep the byte-for-byte identical sequence stream

Frequently asked

Short answers to the questions developers actually search for this sequence.

Is \x1b[<r>;<c>f (HVP) the same as \x1b[<r>;<c>H (CUP)?
Effectively yes on every terminal in the support matrix. ECMA-48 specifies HVP as having identical positioning semantics to CUP — both are 1-based, both default Pn1/Pn2 to 1 when omitted, both move the cursor without scrolling. The historic distinction was that HVP belonged to a different ECMA category (presentation control vs editor control) and could be inhibited independently by SCS — irrelevant on modern terminals. The de-facto convention is to emit CUP \x1b[H since it's the byte everyone implements first; reserve \x1b[f for code that already used it.
When should I use HVP \x1b[f instead of CUP \x1b[H?
Almost never — pick CUP \x1b[H for new code. The only practical reason to emit HVP is reading legacy code or working with a parser that the source already wrote against f. ECMA-48 keeps both around for spec compliance, but every emulator in the support matrix treats them identically. If you're emitting through a stack that strips one of them (rare — typically only DEC VT510 RM-strict parsers), the other still gets through; otherwise the choice is purely stylistic.

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 · 2. Cursor movement — CUU / CUD / CUF / CUB + CUP + CHA / VPA