# Insert Line (IL)

> Insert n blank lines at the cursor, pushing the lines below it down.

- **Sequence:** `CSI Pn L`
- **Defaults:** Pn = 1
- **ECMA-48:** [§8.3.67 IL – Insert Line, p. 47](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n60/mode/1up)
- **DEC STD 070:** [§5.11 Insert Line, p. 5-146](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n400/mode/1up)
- **VT510:** [IL—Insert Line](https://vt100.net/docs/vt510-rm/IL.html)

Insert `Pn` blank lines at the line the cursor is on. That line and the lines
below it move down to make room, and lines pushed past the bottom margin are
lost. A `0` is taken as `1`.

Only the scrolling region is affected. Lines above the cursor and below the
bottom margin stay where they are, and with left and right margins set, only
the part of each line between them moves. If the cursor is outside the
scrolling region, whether above or below it or to one side of it, IL does
nothing at all.

Afterwards the cursor is at the left margin of the line it was on: DEC STD
070 says the active position is set to the left margin and the active line
does not change. ECMA-48 says the same in its own terms, moving the active
position to the *line home position*.

[DL](https://control-codes.page/csi/dl/index.html.md) is the reverse. [SD](https://control-codes.page/csi/sd/index.html.md) also moves lines down, but
from the top of the scrolling region, wherever the cursor is.

## Validation

### IL-1: Insert one line

Input, one step per line:

```text
1\r\n2\r\n3\r\n4
\e[2;3H
\e[L
```

Expected screen:

```text
|1____|
|_____|
|2____|
|3____|
cursor 2,1
```

### IL-2: Lines pushed off the bottom are lost

Input, one step per line:

```text
1\r\n2\r\n3\r\n4
\e[2;1H
\e[2L
```

Expected screen:

```text
|1____|
|_____|
|_____|
|2____|
```

### IL-3: Only the scrolling region moves

Input, one step per line:

```text
1\r\n2\r\n3\r\n4
\e[1;3r   # region is lines 1 to 3; homes the cursor
\e[2;1H
\e[L
```

Expected screen:

```text
|1____|
|_____|
|2____|
|4____|
```

### IL-4: Nothing happens outside the scrolling region

Input, one step per line:

```text
1\r\n2\r\n3\r\n4
\e[2;3r   # region is lines 2 and 3
\e[4;1H   # below it
\e[L
```

Expected screen:

```text
|1____|
|2____|
|3____|
|4____|
cursor 4,1
```

### IL-5: Inside left and right margins

Input, one step per line:

```text
abcde\r\nfGHIj\r\nkLMNo\r\npQRSt\r\nuvwxy
\e[?69h   # allow left and right margins
\e[2;4s   # margins at columns 2 and 4
\e[2;4r   # region is lines 2 to 4
\e[2;3H   # on the H
\e[L
```

Expected screen:

```text
|abcde|
|f___j|
|kGHIo|
|pLMNt|
|uvwxy|
cursor 2,2
```

---

This is the Markdown version of <https://control-codes.page/csi/il/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
