IL — Insert Line (CSI Pn L)
Open N blank lines at the cursor row and push subsequent lines down within the scrolling region — vim's 'O' command primitive.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[PnL\033[PnL\e[PnLESC [ Pn L1b 5b <Pn> 4cDescription
Insert Line. Final byte L (0x4c) inserts Pn blank lines at the cursor row (default 1); every subsequent line inside the active scrolling region (DECSTBM, default = full screen) is pushed downward by Pn, and the Pn lines that would fall below the bottom margin are discarded. Cells in the freshly-inserted blank lines carry the current SGR background. The cursor moves to column 1 of its row (ECMA-48 says column unchanged, but most modern terminals follow the xterm convention of resetting to column 1 because that's what every TUI app expects). Used by vim's O command (open line above), tmux's pane re-layout, and any less-style scroll-up-by-N. Counterpart is DL (\x1b[Pn M). Terminfo cap: il1 (Pn=1) or il (parameterised).
Spec citation: ECMA-48 §8.3.67 (IL)
Examples
# Set scroll region rows 1..5, position cursor at row 3, insert 2 blank lines.\nprintf '\033[1;5r\033[3;1H\033[2L'import sys; sys.stdout.write('\x1b[2L') # insert 2 lines at cursor rowfmt.Print("\x1b[2L")process.stdout.write('\x1b[2L')printf("\x1b[2L");Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- vim, neovim — `O` (open line above) primitiveevery `O` / `o` / `:put!` boils down to `\x1b[1L` at the cursor row inside a DECSTBM-bracketed region — the editor reuses the terminal's native insert-line rather than redrawing every row below the cursor
- less, more — scroll-up by Nscrolling backward through a long file emits `\x1b[<N>L` at row 1 inside the page region — the bottom N lines fall off, and the freshly-revealed top lines are then written into the blank slots
- tmux — pane resize / split-window redrawgrowing a pane vertically uses IL inside the new pane's DECSTBM region to make room without forcing the surrounding panes through a full repaint — `tmux send-keys` benchmarks show ~10× fewer bytes vs. full-screen rewrite
- ncurses — `insertln()` / `winsertln()`the libncurses API `insertln(WIN)` maps directly to `il1` (no Pn) or `il` (with Pn) terminfo capabilities — every TUI built on ncurses (htop, vifm, mc, weechat) inherits IL the moment the underlying terminal exports the cap
- git diff --color-moved=zebra inside `less -R`the zebra stripe colouring on moved-block diff hunks works because `less` lays them out with IL + DL pairs inside a DECSTBM region — interleaving the alternating background colours without smearing the unchanged context
Frequently asked
Short answers to the questions developers actually search for this sequence.
- Does
\x1b[Linsert a line or scroll the screen? - Insert. IL (
\x1b[Pn L) opensPnblank lines *at the cursor row* and pushes subsequent rows down within the active scroll region — no scrolling of the top of the region, no content loss above the cursor. Lines that get pushed past the bottom of the scroll region (set bydecstbm) are discarded; if you haven't set a scroll region, the bottom lines fall off the visible screen. This is the primitive vim / neovim use for theOandocommands; rolling your own with\nre-implements the bug ed(1) ships with. - How does IL interact with the scroll region (DECSTBM)?
- IL only takes effect when the cursor sits *inside* the active scroll region. If the cursor is above the top margin or below the bottom margin, IL is a no-op on most terminals (xterm, kitty, alacritty, wezterm, ghostty) — your draw silently fails to open lines. Inside the region, lines push down toward the bottom margin and any rows past the margin are discarded. The portable pattern is: set DECSTBM (
\x1b[<top>;<bottom>r) → move the cursor inside with CUP → emit IL → reset DECSTBM with\x1b[r(defaults to full screen) when done. See pitfallalt-screen-newlinefor a related cursor-row off-by-one trap.
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