Skip to main content
ansicode

HPA / HPR / VPR — Position absolute & relative (CSI ` / CSI a / CSI e)

ECMA-48's row/col-preserving cursor moves — HPA (absolute column), HPR (relative column), VPR (relative row) — completing the trio anchored by VPA.

Byte forms

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

\\x1b[\x1b[<col>` (HPA) \x1b[<n>a (HPR) \x1b[<n>e (VPR)
\\033[\033[10` / \033[5a / \033[3e
\\e[\e[10` / \e[5a / \e[3e
ESC [ESC [ col ` / ESC [ n a / ESC [ n e
hex1b 5b ... 60 / 1b 5b ... 61 / 1b 5b ... 65

Description

Three ECMA-48 cursor-positioning primitives that preserve the orthogonal axis — same shape as VPA (\x1b[<row>d) and CHA (\x1b[<col>G, slug cursor-column) but covering the gaps. HPA (\x1b[<col> ) Horizontal Position Absolute — move to absolute column <col> (1-based), keep current row. Semantically identical to CHA (G); final byte differs only because ECMA-48 § 8.3.57 (HPA) predates / parallels § 8.3.9 (CHA). **HPR** (\x1b[<n>a) Horizontal Position Relative — move n columns right, keep row. Same effect as CUF (\x1b[<n>C) but the final byte a distinguishes the ECMA-48-canonical form. **VPR** (\x1b[<n>e) Vertical Position Relative — move n rows down, keep column. Same as CUD (\x1b[<n>B) by final byte e. All three default to n=1 / col=1 when omitted; out-of-range values clamp to the visible region (or DECSTBM/DECSLRM region when those are active). In practice most modern code emits CHA/CUF/CUD/CUB instead — but every ECMA-48-conformant terminal accepts the HPA/HPR/VPR aliases, and curses' default capability table contains them, so any parser must recognize the alternative final bytes. The HPA backtick final byte is also the easiest of any CSI final to mistype — note it's 0x60, not apostrophe 0x27 (which would be DECIC / DECDC's intermediate byte).

Spec citation: ECMA-48 §8.3.57 (HPA) / §8.3.59 (HPR) / §8.3.160 (VPR)

Parameters

col / nHPA: absolute column (1-based). HPR: columns to move right. VPR: rows to move down. Default 1 if omitted.

Examples

bash
printf '\033[40`status: ok'   # HPA: jump to col 40, keep row (note backtick, not single quote)
python
import sys; sys.stdout.write('\x1b[5a')   # HPR: move 5 cols right
go
fmt.Print("\x1b[3e")   // VPR: move 3 rows down
javascript
process.stdout.write('\x1b[1`')   // HPA: column 1 (== CR but doesn't move row)
c
printf("\x1b[10a");   /* HPR: 10 cols right — same effect as \x1b[10C */

Terminal support

xterm
yes
Linux console (fbcon)
yes
macOS Terminal.app
yes
iTerm2
yes
Windows Terminal
yes
cmd.exe / ConPTY
partial
kitty
yes
alacritty
yes
WezTerm
yes
Ghostty
yes
GNOME Terminal
yes
Konsole
yes
tmux
yes
GNU screen
yes

Related sequences