Vertical Position Relative (VPR)
Move the cursor down `n` rows without changing the column.
- 0x1B
- ESC
- 0x5B
- [
- ____
- y
- 0x65
- e
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.
This sequence always unsets the pending wrap state.
VPR moves the cursor y rows down from its current position. VPR is
paired with VPA the same way CUD
is paired with VPA: VPA selects an absolute row, VPR selects a row
relative to where the cursor is now.
VPR is handled as an absolute move to the current column and the current
row plus y. With origin mode off, the result is clamped to the
final row of the screen, so VPR runs past a bottom margin instead
of stopping at it. With origin mode on, the clamp is the bottom margin.
This sequence never triggers scrolling and never modifies cell content.
Because the move is absolute, the column goes through the same resolution as the row. It is unchanged with origin mode off, but with origin mode on the current column is offset by the left margin and clamped to the right margin, so VPR can move the cursor across as well as down.
Note
VPR and CUD (Cursor Down,
CSI Pn B) agree as long as no scrolling region is set, and both unset pending wrap, but they are not the same handler. CUD always stops at the bottom margin; VPR only respects the bottom margin when origin mode is set, and otherwise carries the cursor to the final row of the screen.
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A"
printf "\033[2e" # VPR down 2 rows
printf "X"
|A_________|
|__________|
|_Xc_______|
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "A"
printf "\033[e" # VPR with default (1)
printf "X"
|A_________|
|_Xc_______|
printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[1;2r" # scroll region rows 1..2
printf "\033[1;1H"
printf "A"
printf "\033[500e" # VPR way past the bottom
printf "X"
|A_________|
|__________|
|_Xc_______|
Origin mode is off here, so the row is clamped to the screen height rather than to the bottom margin at row 2.
cols=$(tput cols)
printf "\033[${cols}G" # move to last column
printf "A" # set pending wrap state
printf "\033[1e" # VPR cancels pending wrap
printf "X"
|_________A|
|_________X|