Skip to main content
ansicode

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[\x1b[PnP
\\033[\033[PnP
\\e[\e[PnP
ESC [ESC [ Pn P
hex1b 5b <Pn> 50

Description

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

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");

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 Pn cells starting *at* the cursor (the cell under the cursor is the first deleted), shifts the row's trailing content left by Pn, 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 previously Pn columns to the right. Verify with DSR \x1b[6n if 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's delete-char binding 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

Related sequences

In the family cookbook

CSI cookbook · 6. Insert / delete / cursor shape — IL / DL / ICH / DCH / ECH + DECSCUSR