擦除字符 (ECH)

从光标处开始(含光标)向右擦除 `n` 个单元格。

  1. 0x1B
    ESC
  2. 0x5B
    [
  3. ____
    n
  4. 0x58
    X

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

可擦除的最右列是屏幕的最右列。 右边距 对此序列没有影响。

此序列总是取消待定换行状态。如果光标所在的行 是软换行的,那么软换行状态也会被重置。

对于 n 个单元格(直至最右列),通过将其替换为 一个空白字符来清空单元格,其背景色按 当前 SGR 状态着色。不保留其他 SGR 属性。

如果多单元格字符会被拆分,则擦除整个多单元格字符。例如, 如果打印了“橋”并发出 ECH n = 1, 则即使该字符占用两个单元格,也应擦除整个字符。 被擦除的两个单元格都按当前 SGR 状态以当前背景色着色。

如果 字符选择属性选择 (DECSCA) 已启用, 或它是当前活动屏幕上最近一次启用的保护模式, 则受保护属性会被忽略,仿佛从未设置过,带有这些属性的单元格会被擦除。 即使 DECSCA 当前已禁用也没有关系,只要 DECSCA 是 _最近一次启用_的保护模式,受保护属性仍会被忽略。

如果 DECSCA 当前未启用,也不是当前活动屏幕上最近一次启用的 保护模式,则带有受保护属性的单元格会被尊重,不被擦除,但仍计入 n。 单元格的保护属性最初是否由 DECSCA 设置并不重要。

校验

ECH V-1:简单操作

printf "ABC"
printf "\033[1G"
printf "\033[2X"
|c_C_____|

ECH V-2:擦除越出屏幕边缘

cols=$(tput cols)
printf "\033[${cols}G"
printf "\033[2D"
printf "ABC"
printf "\033[D"
printf "\033[10X"
|_____Ac_|

ECH V-3:重置待定换行状态

cols=$(tput cols)
printf "\033[${cols}G" # move to last column
printf "A" # set pending wrap state
printf "\033[X"
printf "X"
|_______Xc

ECH V-4:SGR 状态

printf "ABC"
printf "\033[1G"
printf "\033[41m"
printf "\033[2X"
|c_C_____|

c_ 个单元格都应有红色背景。所有其他单元格样式保持不变。

ECH V-5:多单元格字符

printf "橋BC"
printf "\033[1G"
printf "\033[X"
printf "X"
|XcBC____|

ECH V-6:左/右滚动区域被忽略

printf "\033[1;1H" # move to top-left
printf "\033[0J" # clear screen
printf "\033[?69h" # enable left/right margins
printf "\033[1;3s" # scroll region left/right
printf "\033[4G"
printf "ABC"
printf "\033[1G"
printf "\033[4X"
|c___BC____|

ECH V-7:使用 DECSCA 时忽略受保护属性

printf "\033V"
printf "ABC"
printf "\033[1\"q"
printf "\033[0\"q"
printf "\033[1G"
printf "\033[2X"
|c_C_______|

ECH V-8:不使用 DECSCA 时尊重受保护属性

printf "\033[1\"q"
printf "ABC"
printf "\033V"
printf "\033[1G"
printf "\033[2X"
|ABC_______|

光标保持在 A 处。