カーソル後退 (CUB)
カーソルを `n` セル左へ移動します。
- 0x1B
- ESC
- 0x5B
- [
- ____
- n
- 0x44
- D
パラメーター n は 1 以上の整数でなければなりません。n が 0 以下の
場合は n を 1 に調整します。n が省略された場合は n が既定で 1 になります。
このシーケンスは常に 保留中の折り返し状態 を解除します。
カーソルが移動できる最も左の境界は、現在のカーソル列と 左マージン によって決まります。カーソルが最初から左マージンより左にある場合、シーケンス実行中は左マージンを最左列へ変更します。カーソルが位置できる 最も左の列は左マージンです。
以上を踏まえると、ターミナルのモード状態に応じて 3 種類のカーソル後退挙動があります。 可能な挙動を以下に挙げます。競合する場合は、 最も上の挙動が優先されます。
- 拡張逆方向折り返し:折り返し (モード 7) と 拡張逆方向折り返し (モード 1045) が 両方有効
- 逆方向折り返し:折り返し (モード 7) と 逆方向折り返し (モード 45) が 両方有効
- 折り返しなし:上記の折り返し挙動の条件が 満たされない場合の既定の挙動。
折り返しなしの挙動では、前述の最左境界を尊重しながらカーソルを左へ n セル移動します。
最左境界に達した時点で、n の残り値がどれだけあってもカーソルの左移動を止めます。
カーソルの行は変化しません。
拡張逆方向折り返しの挙動では、前述の最左境界を尊重しながらカーソルを左へ n セル移動します。最左境界に達した際、n > 0 であればカーソルを上の行の
右マージン へ移動します。
カーソルがすでに
上マージン にある場合は、下マージン の
右マージンへ移動します。このモードではカーソルの列と行のどちらも変わり得ます。
非拡張の逆方向折り返しと比較した場合の 2 つの重要な違いは、拡張逆方向折り返しでは
前の行が折り返された行である必要がなく、拡張逆方向折り返しは下マージンへ折り返す点です。
逆方向折り返し(非拡張)の挙動では、前述の最左境界を尊重しながらカーソルを左へ n セル移動します。最左境界に達した際、n > 0 かつ
前の行が折り返された行であれば、カーソルを上の行の 右マージン へ移動します。前の行が
折り返されていなければ、n に残り値があってもカーソル左移動操作は完了です。カーソルが
すでに 上マージン にある場合は、カーソルを上へ移動しません。
この折り返しモードでは、カーソル行を下マージンへ折り返しません。
拡張逆方向折り返しまたは逆方向折り返しモードでは、保留中の折り返し状態がセットされている場合、n を 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________|
printf "\033[?45l" # disable reverse wrap
echo "A"
printf "\033[10D" # back
printf "B"
|A_________|
|Bc________|
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_________|
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_________|
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
printf "\033[1;1H"
printf "\033[0J"
printf "\033[?45h"
printf "\033[3r"
printf "\b"
printf "X"
|__________|
|__________|
|Xc________|
cols=$(tput cols)
printf "\033[?45h"
printf "\033[${cols}G"
printf "\033[4D"
printf "ABCDE"
printf "\033[D"
printf "X"
|_____ABCDX|