Skip to main content
ansicode

ICH — Insert Character (CSI Pn @)

Shift the rest of the current line right by N cells and blank-fill the gap — the primitive vim's insert mode is built on.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[Pn@
\\033[\033[Pn@
\\e[\e[Pn@
ESC [ESC [ Pn @
hex1b 5b <Pn> 40

Description

Insert Character. Final byte @ (0x40) shifts the cursor position and every cell to its right within the current line rightward by Pn cells (default 1); cells that fall off the right edge are discarded and the Pn-wide gap at the cursor is filled with blanks (SP, 0x20) carrying the current SGR background. The cursor itself does not move. ICH is the primitive vim insert mode emits per typed character — vim could redraw the whole line for every keystroke, but using ICH keeps screen updates O(1) per character. Pair with DCH (\x1b[Pn P) to delete the same way. ICH is bounded by the right margin (DECSTBM column-margins, if set); cells past the right margin are NOT shifted into. The terminfo capability is ich1 (Pn=1) or ich (parameterised).

Spec citation: ECMA-48 §8.3.64 (ICH)

Examples

bash
# Move cursor to column 5, insert 3 cells, then type 'xyz' (it lands at col 5).\nprintf 'Hello world\033[5G\033[3@xyz'
python
import sys; sys.stdout.write('\x1b[3@')   # open a 3-cell gap at the cursor
go
fmt.Print("\x1b[3@")
javascript
process.stdout.write('\x1b[3@')
c
printf("\x1b[3@");

Used in

Real-world tools that emit this sequence — anchors the bytes to commands you've already used.

  • vim insert-mode `i` / `I` / `a` primitivesvim emits ICH for in-row character insertion when `'insertmode'` redraws are partial — the row's trailing content shifts right, the inserted character takes the cursor cell. `:set verbose=15` shows `<Esc>[<N>@` patterns during fast typing
  • bash readline `quoted-insert` (Ctrl-V)readline's `quoted-insert` binding inserts a literal control character at the cursor with an ICH preceding the byte write — preserves the line-tail's column positions for in-line edits without falling back to a full-line redraw
  • zsh ZLE `self-insert` widgetzsh's line editor emits ICH when `INSERT_MODE` is on and the cursor is not at end-of-line — the line tail right-shifts cleanly with a single CSI byte rather than a row-redraw of the full content
  • less / more search-marker highlight insertionless ≥ 633 inserts a `>` search-marker at the cursor with ICH before applying the highlight SGR — keeps the row's existing content layout intact while the marker visually pushes everything one cell right within the search hit
  • ncurses `insch()` / `winsch()`ncurses' `insch()` maps to `\x1b[1@` (ICH defaulting to 1) on terminals advertising the `ich1` cap, or a parameterised `\x1b[<N>@` via `ich` on others — visible in `infocmp xterm-256color | grep ich`

Frequently asked

Short answers to the questions developers actually search for this sequence.

What's the difference between ICH (\x1b[5@) and IL (\x1b[5L)?
ICH (Insert Character — final byte @, 0x40) inserts Pn blank cells *in the current row at the cursor*, shifting the row's trailing content right by Pn; cells pushed past the right margin are lost. IL (Insert Line — final byte L, 0x4c) inserts Pn blank *rows* at the cursor's row, shifting subsequent rows down within the scroll region. ICH is what vim's i does for a single character; IL is what vim's O and o do for blank lines. Pick ICH for in-row edits, IL for row-level insertions.
Where do characters pushed past the right margin go when I run ICH?
They're discarded — pushed off the row and gone forever. ICH does NOT wrap pushed-off content onto the next row (that would be a line-rewrap, which is a separate concept — see DECAWM \x1b[?7h). The row's final cells past the right margin are simply truncated. If the cursor is past the right margin when ICH fires (only possible with DECAWM in the post-wrap pending state), the behaviour is implementation-defined — xterm treats it as a no-op, kitty and Ghostty wrap the cursor first then insert.

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