VPA — Vertical line position absolute (CSI d)
Move the cursor to an absolute row, keeping the current column.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[<row>d\033[3d\e[3dESC [ row d1b 5b ... 64Description
Vertical Position Absolute. Move the cursor to row <row> (1-based) without changing the column — the row-only counterpart of CHA (\x1b[<col>G, cursor-column). Default row is 1 if omitted (\x1b[d). Out-of-range values clamp to the visible region (or the DECSTBM scrolling region when DECOM is active). VPA's column-preserving behaviour makes it the right primitive when redrawing a status bar or progress line at a known row while the user types in the column above — CUP (\x1b[r;cH) would reset the column to 1. Less commonly used than CUP / CUU / CUD because most TUIs prefer absolute (row, col) pairs, but it's part of every ECMA-48-conformant terminal.
Spec citation: ECMA-48 §8.3.158 (VPA) / xterm-ctlseqs
Examples
printf '\033[24dstatus: ok' # jump to row 24, keep columnimport sys; sys.stdout.write('\x1b[24dstatus: ok')fmt.Print("\x1b[24dstatus: ok")process.stdout.write('\x1b[24dstatus: ok')printf("\x1b[24dstatus: ok");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- vim / neovim status line redraw`:redrawstatus` and the per-window `&statusline` rebuild path use VPA to jump to the status row while preserving the column the cursor was sitting in — avoids a CUP `\x1b[<row>;<col>H` round-trip and the extra column-math when the buffer cursor is mid-line
- htop / btop / glances column-aligned rowsafter writing the leftmost column of header / footer text, htop emits VPA to step down to the next row at the same column instead of recomputing the column for every row — the column constancy is the whole reason htop's vertical bars render cleanly under SIGWINCH redraws
- ncurses `wmove(WIN, row, col)` when column unchangedncurses's diff renderer emits VPA `\x1b[<row>d` instead of CUP when its dirty-line tracker indicates the column matches the previous cursor column — a 1-2 byte saving per redraw that adds up on slow remote PTYs
- less status-line repaintless repaints its `:` prompt by VPA to the bottom row + EL `\x1b[K` (clear) + write — the column was 0 from the previous newline so VPA suffices without a CUP
- tmux pane-status-format updatestmux's per-pane status line update (`set -g pane-status-format`) emits VPA to land on the status row inside the pane viewport — `\x1b[<row>d` survives the per-pane translation cleanly even when panes are split horizontally and column origin differs
Frequently asked
Short answers to the questions developers actually search for this sequence.
- How does
\x1b[<n>d(VPA) differ from\x1b[<n>;<col>H(CUP)? - VPA (
\x1b[Pn d) sets the cursor to rowPn*while preserving the current column*. CUP (\x1b[Pn1;Pn2 H) sets both row and column. Use VPA when you're walking down a column to draw a vertical sidebar / scrollbar / column-aligned status indicator without recomputing the column each row. Both row indices are 1-based per ECMA-48;\x1b[1dlands at the top row. If you need to clamp at the screen edge, the terminal handles it for you (most clamp to row 1 / row LINES). - Is
\x1b[<n>d(VPA) 0-based or 1-based? - 1-based, same as CUP.
\x1b[1dis the top row;\x1b[0dis *not* the top row —Pn=0is treated asPn=1per ECMA-48 (most terminals silently clamp; some legacy parsers reject the clause). OmittingPnalso defaults to 1:\x1b[d≡\x1b[1d. See pitfallcup-1-based-not-0-basedfor the same trap on CUP / HVP / CHA.
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
| 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 | partial | yes | yes | yes | yes | yes | yes | yes | yes |
Related sequences
In the family cookbook
CSI cookbook · 2. Cursor movement — CUU / CUD / CUF / CUB + CUP + CHA / VPA