游標後退 (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|