光标后退 (CUB)

将光标向左移动 `n` 个单元格。

  1. 0x1B
    ESC
  2. 0x5B
    [
  3. ____
    n
  4. 0x44
    D

参数 n 必须是大于等于 1 的整数。如果 n 小于 等于 0,则将 n 调整为 1。如果省略 n,则 n 默认为 1。

此序列总是取消 待定换行状态。

光标可以移动到的最左边界由当前光标列和 左边距 决定。如果光标一开始就位于左边距左侧, 则在序列执行期间将左边距修改为最左列。光标可位于的最左列 就是左边距。

在上述设置就绪后,根据终端的模式状态,有三种不同的光标后退行为。 可能的行为列于下方。发生冲突时, 最上面的行为优先。

对于不换行行为,将光标向左移动 n 个单元格, 同时遵守上述最左边界。到达最左边界后, 无论 n 的剩余值如何,都停止向左移动光标。 光标行保持不变。

对于扩展反向换行行为,将光标向左移动 n 个单元格,同时遵守上述最左边界。到达 最左边界后,如果 n > 0,则将光标移到光标上方 一行的 右边距。如果光标已经在 上边距 上,则将光标移到 下边距 的右边距。在此模式下,光标列与行都可能改变。 与非扩展反向换行相比,两个关键区别是:扩展反向换行 不要求上一行是换行过的,并且扩展反向换行会绕回到底部边距。

对于反向换行(非扩展)行为,将光标向左移动 n 个单元格,同时遵守上述最左边界。到达 最左边界后,如果 n > 0 且上一行已换行,则将光标移到光标上方 一行的 右边距。如果上一行 未换行,则即使 n 有剩余值,光标左移操作也已完成。如果光标 已经位于 上边距 上,则不要将光标上移。 这种换行模式不会将光标行绕回到底部边距。

对于扩展反向换行或反向换行模式,如果设置了 待定换行状态,则将 n 减 1。在这些模式下,初始的 光标后退次数已被待定换行状态消耗,就像在空的新行上按下 “退格”键而光标移回上一行一样。

校验

CUB V-1:待定换行被取消

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:禁用反向换行时的最左边界

printf "\033[?45l" # disable reverse wrap
echo "A"
printf "\033[10D" # back
printf "B"
|A_________|
|Bc________|

CUB V-3:反向换行

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:扩展反向换行(单行)

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:扩展反向换行绕回到底部

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:边距之外的反向换行

printf "\033[1;1H"
printf "\033[0J"
printf "\033[?45h"
printf "\033[3r"
printf "\b"
printf "X"
|__________|
|__________|
|Xc________|

CUB V-7:带待定换行状态的反向换行

cols=$(tput cols)
printf "\033[?45h"
printf "\033[${cols}G"
printf "\033[4D"
printf "ABCDE"
printf "\033[D"
printf "X"
|_____ABCDX|