# Line Size (DECDWL, DECDHLT, DECDHLB, DECSWL)

> Make the cursor's line double-width or double-height, or put it back to single-width.

- **Sequence:** `ESC # 6`
- **DEC STD 070:** [§5.6.1 Double-Width Line, p. 5-97](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n351/mode/1up)
- **VT510:** [DECDWL—Double-Width, Single-Height Line](https://vt100.net/docs/vt510-rm/DECDWL.html)

Four escape sequences set how the line the cursor is on is drawn:

| Sequence | Function | The line is drawn |
| --- | --- | --- |
| `ESC # 6` | DECDWL, double-width line | with every character twice as wide |
| `ESC # 3` | DECDHLT, double-height line, top half | as the top half of characters twice as wide and twice as tall |
| `ESC # 4` | DECDHLB, double-height line, bottom half | as the bottom half of the same |
| `ESC # 5` | DECSWL, single-width line | normally again |

A double-height line is two lines: the same text written on adjacent lines,
one set to the top half and the other to the bottom. DEC STD 070 defines
them in §5.6.1, Line Renditions, DECSWL on
[p. 5-96](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n350/mode/1up) and DECDHLT and DECDHLB on
[p. 5-99](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n353/mode/1up); the VT510 manual has
[DECDHL](https://vt100.net/docs/vt510-rm/DECDHL.html) and
[DECSWL](https://vt100.net/docs/vt510-rm/DECSWL.html). All four are levels 1
to 4 in DEC STD 070, so a level 2 terminal is expected to have them.

The case runner cannot see how a line is drawn, but it can see what a line
size does to positions. A double-width or double-height line holds only half
as many characters, so text written to it wraps at the middle of the screen
rather than the edge. In xterm, the last column of such a line is half the
last column of the screen
([`LineMaxCol`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/ptyx.h#L1701-L1704)), and that is where text wraps
([`dotext`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L7040-L7049)). When a line becomes double-size,
xterm also moves a cursor that was in the right half back to the middle of
the line ([`repaint_line`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/doublechr.c#L49-L80)).

DEC STD 070 says the characters in the right half of a line made
double-width are lost. xterm keeps them: it repaints the line but leaves its
contents alone, so they reappear when the line is made single-width again.
The cases follow xterm, as this site does wherever the two disagree. Both
agree that a line size cannot be set while left and right margins are
enabled ([DECSLRM](https://control-codes.page/csi/decslrm/index.html.md)): DEC STD 070 says the control "does not
operate when DECLRMM (Left Right Margin Mode) is set", and xterm's
`repaint_line` does nothing in that mode. Clearing the whole line, as
[ED](https://control-codes.page/csi/ed/index.html.md) `2` or [DECALN](https://control-codes.page/esc/decaln/index.html.md) do, puts it back to single-width
([`ClearBufRows`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L2105-L2117),
[`CASE_DECALN`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L4837-L4850)).

libghostty-vt does not implement line sizes at all. Its escape-sequence
dispatch in `stream.zig` has no case for `ESC #` followed by `3`, `4`, `5`
or `6`, so every line keeps its full width, and the cases that depend on
the halved line are known differences.

## Validation

### DECDWL-1: Text wraps at the middle

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e#6      # double-width line
ABCDEFGHIJ
```

Expected screen:

```text
|ABCDE_____|
|FGHIJ_____|
cursor 2,6
```

### DECDWL-2: Double height does the same

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e#3      # top half of a double-height line
ABCDEFGH
```

Expected screen:

```text
|ABCDE_____|
|FGH_______|
```

### DECDWL-3: The cursor comes back to the middle

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e[1;10H  # last column
\e#6
```

Expected screen:

```text
|__________|
cursor 1,6
```

### DECDWL-4: Single width restores the whole line

Input, one step per line:

```text
\e#6
\e#5      # single-width again
ABCDEFGHIJ
```

Expected screen:

```text
|ABCDEFGHIJ|
|__________|
```

### DECDWL-5: The right half is kept

Input, one step per line:

```text
ABCDEFGHIJ
\e#6      # F to J are no longer shown
\e#5      # but are still there
```

Expected screen:

```text
|ABCDEFGHIJ|
```

### DECDWL-6: Not with left and right margins

Input, one step per line:

```text
\e[?69h   # allow left and right margins
\e#6      # ignored
ABCDEFGHIJ
```

Expected screen:

```text
|ABCDEFGHIJ|
|__________|
```

---

This is the Markdown version of <https://control-codes.page/esc/decdwl/>. 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>.
