# Horizontal and Vertical Position (HVP)

> Move the cursor to a given line and column, as CUP does.

- **Sequence:** `CSI Pl ; Pc f`
- **Defaults:** Pl = 1, Pc = 1
- **ECMA-48:** [§8.3.63 HVP – Character and Line Position, p. 46](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n59/mode/1up)
- **DEC STD 070:** [§5.4.4 Horizontal/Vertical Position, p. 5-51](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n305/mode/1up)
- **VT510:** [HVP—Horizontal and Vertical Position](https://vt100.net/docs/vt510-rm/HVP.html)

Move the cursor to line `Pl`, column `Pc`, exactly as [CUP](https://control-codes.page/csi/cup/index.html.md) does:
both count from 1, either can be left out, a `0` is taken as `1`, a position
past the edge is clamped to it, and with origin mode on the position counts
from the margins.

The two exist side by side for a historical reason. In ECMA-48, HVP moves
the *data* position while CUP moves the *presentation* position, a
distinction that matters to a device where the two can differ. A terminal
has only one cursor. DEC STD 070 defines HVP by calling CUP's own algorithm,
and keeps it only for compatibility with printing terminals, telling software
to use CUP instead. The VT510 manual says the same.

## Validation

### HVP-1: To a position

Input, one step per line:

```text
\e[2;3f
X
```

Expected screen:

```text
|_____|
|__X__|
|_____|
```

### HVP-2: Defaults

Input, one step per line:

```text
\e[3;3f
\e[f      # both left out
A
\e[2f     # column left out
B
\e[;4f    # line left out
C
\e[0;0f   # zero is one
D
```

Expected screen:

```text
|D__C_|
|B____|
|_____|
```

### HVP-3: Clamped to the screen

Input, one step per line:

```text
\e[999;999f
X
```

Expected screen:

```text
|_____|
|_____|
|____X|
```

### HVP-4: With origin mode

Input, one step per line:

```text
\e[2;3r   # region is lines 2 and 3
\e[?6h    # origin mode
\e[1;1f   # the top of the region
A
\e[9;1f   # clamped to the bottom of the region
B
```

Expected screen:

```text
|_____|
|A____|
|B____|
|_____|
```

---

This is the Markdown version of <https://control-codes.page/csi/hvp/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
