DCH — Delete Character (CSI Pn P)
Delete N cells at the cursor and shift the rest of the line left to fill the gap — the inverse of ICH.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[PnP\033[PnP\e[PnPESC [ Pn P1b 5b <Pn> 50Description
Delete Character. Final byte P (0x50) removes Pn cells starting at the cursor (default 1) and shifts every cell to the right of that range left by Pn columns; the Pn cells that appear at the right edge are blank (SP, 0x20) with the current SGR background. The cursor itself does not move. DCH is what vim/emacs emit when you backspace mid-line, what less uses to remove the bottom-of-screen prompt, and the primitive readline edits the prompt with. Pair with ICH (\x1b[Pn @). DCH stops at the right margin set by DECSTBM column-margins (if active) — cells past the margin are not pulled in. Terminfo cap: dch1 (Pn=1) or dch (parameterised).
Spec citation: ECMA-48 §8.3.26 (DCH)
Examples
# Print 'Hello world', move cursor to column 6, delete 6 cells.\nprintf 'Hello world\033[6G\033[6P' # leaves 'Hello' followed by trailing blanksimport sys; sys.stdout.write('\x1b[3P')fmt.Print("\x1b[3P")process.stdout.write('\x1b[3P')printf("\x1b[3P");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- vim / neovim insert-mode `x` / `X` / `dw`Insert-mode delete-char and delete-word redraw by emitting `\x1b[<n>P` (DCH) for each row that lost characters — `:set list listchars=trail:·` then `dw` and trace with `:set verbose=15` shows the per-row DCH stream rather than full-line repaint
- less search-highlight clear with row preserve`less ≥ 633` clears stale `--HILITE--` markers in narrow columns by emitting DCH per affected cell instead of full-row erase — observable via `LESS_TERMCAP_so=$'\x1b[7m' less -+R file` with debug-trace mode
- ncurses `delch()` / `wdelch()`Curses primitive — `delch(WINDOW *)` and `wdelch(WINDOW *)` map directly to the terminfo `dch1` capability (single-char DCH `\x1b[P`) with optional `dch` (multi-char `\x1b[<n>P`) for batch delete. The TUI library inserts the DCH from `terminfo_string("dch1")` — `infocmp xterm | grep dch` shows the value
- GNU readline `kill-word` / `unix-word-rubout`Bound to `M-d` and `C-w` respectively, both redraw the line-edit buffer using DCH `\x1b[<n>P` for the deleted span rather than a full prompt repaint — visible with `bind -p | grep -E 'kill-word|rubout'` and tracing via `READLINE_LINE` introspection
- mc command-line edit fieldMidnight Commander's bottom command-line edit field uses DCH for per-char delete instead of redrawing the whole 1-line input — keep `mc` open, press `Ctrl+W` to delete-word, and `strace -f -e write -p $(pgrep mc)` shows the `\x1b[<n>P` bytes
Frequently asked
Short answers to the questions developers actually search for this sequence.
- Does DCH (
\x1b[5P) move the cursor? - No — the cursor stays in place. DCH removes
Pncells starting *at* the cursor (the cell under the cursor is the first deleted), shifts the row's trailing content left byPn, and pads the right end of the row with SP cells carrying the current SGR background. The cursor remains at its original column. Common visual confusion: it *looks* like the cursor moved because the cell under it now shows the character that was previouslyPncolumns to the right. Verify with DSR\x1b[6nif your TUI's column accounting drifts after DCH. - What's the difference between DCH and pressing the Delete key in my terminal?
- DCH is an *output* sequence — a program writes it to stdout and the terminal modifies the visible row. The Delete key on your keyboard is an *input* event — the terminal sends one of
\x7f(DEL, BS-key emulation),\x1b[3~(xterm Delete), or\x1b[P(legacy DEC) to the foreground process's stdin, and that process (shell / vim / your TUI) decides what to do. Bash readline'sdelete-charbinding ends up emitting\x1b[P(DCH) on the terminal as part of its visual update, which is how the two get conflated. They're related but the direction of dataflow is opposite.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- yes
- macOS Terminal.app
- yes
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- partial
- kitty
- yes
- alacritty
- yes
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- yes
- Konsole
- yes
- tmux
- yes
- GNU screen
- yes
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | yes | yes | partial | yes | yes | yes | yes | yes | yes | yes | yes |
Related sequences
In the family cookbook
CSI cookbook · 6. Insert / delete / cursor shape — IL / DL / ICH / DCH / ECH + DECSCUSR