跳到主要内容
ansicode

DCH — 删除字符(CSI Pn P)

删除光标处 N 个单元,把剩余内容左移填补 —— ICH 的逆操作。

字节形式

涵盖所有常见的字符串字面量写法,方便正反查找。

\\x1b[\x1b[PnP
\\033[\033[PnP
\\e[\e[PnP
ESC [ESC [ Pn P
hex1b 5b <Pn> 50

说明

Delete Character。末字节 P(0x50)—— 从光标处删除 Pn 个单元(默认 1),其右侧每个单元左移 Pn 列;行尾出现的 Pn 个单元为空格(SP,0x20,带当前 SGR 背景色)。光标位置不变。DCH 是 vim/emacs 行内退格、less 抹掉屏幕底端提示、readline 编辑提示符所用的底层原语。与 ICH(\x1b[Pn @)成对。DCH 受 DECSTBM 列边距(若启用)约束 —— 右边距外的单元不被拉入。terminfo 能力名为 dch1(Pn=1)或 dch(带参数)。

规范出处: ECMA-48 §8.3.26 (DCH)

示例

bash
# Print 'Hello world', move cursor to column 6, delete 6 cells.\nprintf 'Hello world\033[6G\033[6P'   # leaves 'Hello' followed by trailing blanks
python
import sys; sys.stdout.write('\x1b[3P')
go
fmt.Print("\x1b[3P")
javascript
process.stdout.write('\x1b[3P')
c
printf("\x1b[3P");

在哪里用到

实际会发出该序列的工具——把抽象字节锚定到你已经用过的命令上。

  • vim / neovim insert-mode `x` / `X` / `dw`插入模式 delete-char 和 delete-word 重绘时为每个丢失字符的行发出 `\x1b[<n>P`(DCH)—— `:set list listchars=trail:·` 后 `dw` 并用 `:set verbose=15` 跟踪可见按行的 DCH 流,而非整行重绘
  • less search-highlight clear with row preserve`less ≥ 633` 在窄列中清除过时 `--HILITE--` 标记时为每个受影响单元发 DCH 而不是整行擦除 —— 通过 `LESS_TERMCAP_so=$'\x1b[7m' less -+R file` 配 debug-trace 模式可观察
  • ncurses `delch()` / `wdelch()`Curses 原语 —— `delch(WINDOW *)` 和 `wdelch(WINDOW *)` 直接映射到 terminfo `dch1` 能力(单字符 DCH `\x1b[P`),可选 `dch`(多字符 `\x1b[<n>P`)做批量删除。TUI 库从 `terminfo_string("dch1")` 插入 DCH —— `infocmp xterm | grep dch` 查值
  • GNU readline `kill-word` / `unix-word-rubout`分别绑定到 `M-d` 和 `C-w`,二者重绘行编辑缓冲时对被删跨度用 DCH `\x1b[<n>P`,而不是完整提示符重绘 —— 用 `bind -p | grep -E 'kill-word|rubout'` 可见,通过 `READLINE_LINE` 内省可跟踪
  • mc command-line edit fieldMidnight Commander 底部命令行编辑域用 DCH 做按字符删除而不是重绘整个 1 行输入 —— 保持 `mc` 打开、按 `Ctrl+W` delete-word,`strace -f -e write -p $(pgrep mc)` 可见 `\x1b[<n>P` 字节

常见问题

针对这条序列,开发者真正会去搜索的问题的简短回答。

DCH(\x1b[5P)会移动光标吗?
不会 —— 光标原地不动。DCH 从光标*所在*单元开始(光标下的单元为第一删除项)删除 Pn 个单元,把行后续内容左移 Pn 位,行右端用带当前 SGR 背景色的 SP 单元补齐。光标列号保持不变。常见视觉误解:因为光标下的单元现在显示的是原本在右侧 Pn 列的字符,*看起来*像光标动了。TUI 列记账在 DCH 后偏移时,用 DSR \x1b[6n 实测一下。
DCH 和终端里按 Delete 键有何区别?
DCH 是*输出*序列 —— 程序把它写到 stdout,终端修改可见行。键盘上的 Delete 键是*输入*事件 —— 终端向前台进程的 stdin 发 \x7f(DEL,BS-key 仿真)、\x1b[3~(xterm Delete)或 \x1b[P(遗留 DEC),由该进程(shell / vim / 你的 TUI)决定如何处理。bash readline 的 delete-char 绑定最终在视觉更新里向终端发出 \x1b[P(DCH),两者因此常被混为一谈。它们相关,但数据流方向相反。

终端支持

xterm
支持
Linux console (fbcon)
支持
macOS Terminal.app
支持
iTerm2
支持
Windows Terminal
支持
cmd.exe / ConPTY
部分
kitty
支持
alacritty
支持
WezTerm
支持
Ghostty
支持
GNOME Terminal
支持
Konsole
支持
tmux
支持
GNU screen
支持

相关序列

在家族食谱中

CSI 食谱 · 6. 插入 / 删除 / 光标形状 —— IL / DL / ICH / DCH / ECH + DECSCUSR