mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

The `CUB` V2 test script has a trailing echo which pushes the cursor down one line, making the expected output incorrect. Remove the `echo` command so the cursor position is as shown.
183 lines
4.9 KiB
Plaintext
183 lines
4.9 KiB
Plaintext
import VTSequence from "@/components/VTSequence";
|
|
|
|
# Cursor Backward (CUB)
|
|
|
|
<VTSequence sequence={["CSI", "Pn", "D"]} />
|
|
|
|
Move the cursor `n` cells left.
|
|
|
|
The parameter `n` must be an integer greater than or equal to 1. If `n` is less than
|
|
or equal to 0, adjust `n` to be 1. If `n` is omitted, `n` defaults to 1.
|
|
|
|
This sequence always unsets the pending wrap state.
|
|
|
|
The leftmost boundary the cursor can move to is determined by the current
|
|
cursor column and the [left margin](#TODO). If the cursor begins to the left of the left margin, modify the left margin to be the leftmost column
|
|
for the duration of the sequence. The leftmost column the cursor can be on
|
|
is the left margin.
|
|
|
|
With the above in place, there are three different cursor backward behaviors
|
|
depending on the mode state of the terminal. The possible behaviors are listed
|
|
below. In the case of a conflict, the top-most behavior takes priority.
|
|
|
|
- **Extended reverse wrap**: [wraparound (mode 7)](#TODO) and [extended reverse wrap (mode 1045)](#TODO)
|
|
are **BOTH** enabled
|
|
- **Reverse wrap**: [wraparound (mode 7)](#TODO) and [reverse wrap (mode 45)](#TODO)
|
|
are **BOTH** enabled
|
|
- **No wrap**: The default behavior if the above wrapping behaviors
|
|
do not have their conditions met.
|
|
|
|
For the **no wrap** behavior, move the cursor to the left `n` cells while
|
|
respecting the aforementioned leftmost boundary. Upon reaching the leftmost
|
|
boundary, stop moving the cursor left regardless of the remaining value of `n`.
|
|
The cursor row remains unchanged.
|
|
|
|
For the **extended reverse wrap** behavior, move the cursor to the left `n`
|
|
cells while respecting the aforementioned leftmost boundary. Upon reaching the
|
|
leftmost boundary, if `n > 0` then move the cursor to the [right margin](#TODO)
|
|
of the line above the cursor. If the cursor is already on the
|
|
[top margin](#TODO), move the cursor to the right margin of the
|
|
[bottom margin](#TODO). Both the cursor column and row can change in this
|
|
mode. Compared to non-extended reverse wrap, the two critical differences are
|
|
that extended reverse wrap doesn't require the previous line to be wrapped
|
|
and extended reverse wrap will wrap around to the bottom margin.
|
|
|
|
For the **reverse wrap** (non-extended) behavior, move the cursor to the left `n`
|
|
cells while respecting the aforementioned leftmost boundary. Upon reaching the
|
|
leftmost boundary, if `n > 0` and the previous line was wrapped, then move the
|
|
cursor to the [right margin](#TODO) of the line above the cursor. If the previous
|
|
line was not wrapped, the cursor left operation is complete even if there
|
|
is a remaining value of `n`. If the cursor
|
|
is already on the [top margin](#TODO), do not move the cursor up.
|
|
This wrapping mode does not wrap the cursor row back to the bottom margin.
|
|
|
|
For **extended reverse wrap** or **reverse wrap** modes, if the pending
|
|
wrap state is set, decrease `n` by 1. In these modes, the initial cursor
|
|
backward count is consumed by the pending wrap state, as if you pressed
|
|
"backspace" on an empty newline and the cursor moved back to the previous line.
|
|
|
|
## Validation
|
|
|
|
### CUB V-1: Pending Wrap is Unset
|
|
|
|
```bash
|
|
cols=$(tput cols)
|
|
printf "\033[${cols}G" # move to last column
|
|
printf "A" # set pending wrap state
|
|
printf "\033[D" # move back one
|
|
printf "XYZ"
|
|
```
|
|
|
|
```
|
|
|________XY|
|
|
|Zc________|
|
|
```
|
|
|
|
### CUB V-2: Leftmost Boundary with Reverse Wrap Disabled
|
|
|
|
```bash
|
|
printf "\033[?45l" # disable reverse wrap
|
|
echo "A"
|
|
printf "\033[10D" # back
|
|
printf "B"
|
|
```
|
|
|
|
```
|
|
|A_________|
|
|
|Bc________|
|
|
```
|
|
|
|
### CUB V-3: Reverse Wrap
|
|
|
|
```bash
|
|
cols=$(tput cols)
|
|
printf "\033[?7h" # enable wraparound
|
|
printf "\033[?45h" # enable reverse wrap
|
|
printf "\033[1;1H" # move to top-left
|
|
printf "\033[0J" # clear screen
|
|
printf "\033[${cols}G" # move to end of line
|
|
printf "AB" # write and wrap
|
|
printf "\033[D" # move back two
|
|
printf "X"
|
|
```
|
|
|
|
```
|
|
|_________Xc
|
|
|B_________|
|
|
```
|
|
|
|
### CUB V-4: Extended Reverse Wrap Single Line
|
|
|
|
```bash
|
|
printf "\033[?7h" # enable wraparound
|
|
printf "\033[?1045h" # enable extended reverse wrap
|
|
printf "\033[1;1H" # move to top-left
|
|
printf "\033[0J" # clear screen
|
|
echo "A"
|
|
printf "B"
|
|
printf "\033[2D" # move back two
|
|
printf "X"
|
|
```
|
|
|
|
```
|
|
|A________Xc
|
|
|B_________|
|
|
```
|
|
|
|
### CUB V-5: Extended Reverse Wrap Wraps to Bottom
|
|
|
|
```bash
|
|
cols=$(tput cols)
|
|
printf "\033[?7h" # enable wraparound
|
|
printf "\033[?1045h" # enable extended reverse wrap
|
|
printf "\033[1;1H" # move to top-left
|
|
printf "\033[0J" # clear screen
|
|
printf "\033[1;3r" # set scrolling region
|
|
echo "A"
|
|
printf "B"
|
|
printf "\033[D" # move back one
|
|
printf "\033[${cols}D" # move back entire width
|
|
printf "\033[D" # move back one
|
|
printf "X"
|
|
```
|
|
|
|
```
|
|
|A_________|
|
|
|B_________|
|
|
|_________Xc
|
|
```
|
|
|
|
### CUB V-6: Reverse Wrap Outside of Margins
|
|
|
|
```bash
|
|
printf "\033[1;1H"
|
|
printf "\033[0J"
|
|
printf "\033[?45h"
|
|
printf "\033[3r"
|
|
printf "\b"
|
|
printf "X"
|
|
```
|
|
|
|
```
|
|
|__________|
|
|
|__________|
|
|
|Xc________|
|
|
```
|
|
|
|
### CUB V-7: Reverse Wrap with Pending Wrap State
|
|
|
|
```bash
|
|
|
|
cols=$(tput cols)
|
|
printf "\033[?45h"
|
|
printf "\033[${cols}G"
|
|
printf "\033[4D"
|
|
printf "ABCDE"
|
|
printf "\033[D"
|
|
printf "X"
|
|
```
|
|
|
|
```
|
|
|_____ABCDX|
|
|
```
|