Vertical Position Absolute (VPA)
Move the cursor to a specific row without changing the column.
- 0x1B
- ESC
- 0x5B
- [
- ____
- y
- 0x64
- d
The parameter y must be an integer greater than or equal to 1. If y is
less than or equal to 0, adjust y to be 1. If y is omitted, y
defaults to 1. The row value is one-based: the topmost row is row 1.
This sequence always unsets the pending wrap state.
VPA is functionally equivalent to Cursor Position (CUP)
with the column set to the current cursor column and the row set to y.
Because it takes the same absolute positioning path as CUP, the column is
re-resolved along with the row. With
origin mode off the column is
unchanged, but with origin mode on the current column is read as an
origin-relative column and the cursor can end up on a different column.
If origin mode is NOT set, the cursor is moved to row y
clamped to the bottom row of the screen.
If origin mode is set, y = 1 corresponds to the
top margin and the maximum value for y is the
bottom margin. When origin mode is set, it is impossible to
position the cursor outside the vertical scroll region with this sequence.
Origin mode shifts the column the same way. The current column is offset by
the left margin and clamped to the
right margin, so with a left margin at column 3,
origin mode set and the cursor on absolute column 2, a bare CSI 3 d
leaves the cursor on column 4.
Tip
VPA is the vertical counterpart to HPA. If you need to set both the row and the column at once, use CUP instead.
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[1;3H" # move to row 1, column 3
printf "A"
printf "\033[3d" # VPA to row 3 (column 4 retained)
printf "X"
|__A_______|
|__________|
|___Xc_____|
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[500d" # VPA past the bottom edge
printf "X"
|__________|
|__________|
|Xc________|
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[2;3r" # scroll region rows 2..3
printf "\033[?6h" # origin mode
printf "\033[1;1H" # origin-relative top-left
printf "\033[500d" # VPA past the bottom margin
printf "X"
|__________|
|__________|
|Xc________|
cols=$(tput cols)
printf "\033[${cols}G" # move to last column
printf "A" # set pending wrap state
printf "\033[1d" # VPA cancels pending wrap
printf "X"
|_________X|
Printing A in the last column leaves the cursor there with pending wrap
set. CSI 1 d resolves to the row and column the cursor is already on and
clears the flag, so the X overwrites the A.