# Parameters

> How many parameters a control sequence can carry, and what happens to ones that are malformed.

- **Sequence:** `CSI Pn ; Pn ; … F`
- **DEC STD 070:** [§3.5.3.1 Parameter Values in Control Sequences, p. 3-24](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n128/mode/1up)
- **xterm:** [Definitions](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)

The [CSI](https://control-codes.page/esc/csi/index.html.md) page gives the rules for parameters as the standards
write them. This page is about where terminals have to choose.

**How many.** ECMA-48 sets no limit on the number of parameters. DEC STD 070
leaves the limit to the terminal, but asks for at least 16, and lets it
ignore any past its limit
([§3.5.3.1, p. 3-24](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n128/mode/1up)).
xterm keeps 30
([`NPARAM`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/ptyx.h#L425)).
Past that it does not give up: each further `;` is ignored, and the digits
after it run on into the 30th parameter, so `3` and then `;1` there make
`31`
([`CASE_ESC_DIGIT`, `CASE_ESC_SEMI`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L3851-L3870)).
libghostty-vt keeps 24, and ignores a sequence with more altogether
(`MAX_PARAMS` in `Parser.zig`). The difference matters in practice for
[SGR](https://control-codes.page/csi/sgr/index.html.md), where programs string many settings together.

**Malformed.** DEC STD 070 makes a sequence invalid, to be ignored through
its final byte, when a private marker (`<`, `=`, `>`, `?`) comes anywhere
but first
([§3.5.3.4, p. 3-26](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n130/mode/1up)),
when a parameter byte follows an intermediate
([§3.5.3, p. 3-23](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n127/mode/1up)),
and when it has `:`, which it reserves
([§3.5.3.1, p. 3-24](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n128/mode/1up)).
xterm's parse tables ignore all of these
([`csi2_table`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/VTPrsTbl.c#L801-L882),
[`dec_table`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/VTPrsTbl.c#L4127-L4130)),
except that it lets a few functions take `:`-separated subparameters, SGR
above all, and ignores any other function that is given them
([`doparsing`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L3496-L3539)).
libghostty-vt does the same.

## Validation

### PRM-1: Twenty-four parameters

Input, one step per line:

```text
\e[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1m  # 23 zeros, then bold
A
```

Expected screen:

```text
|A_______|
attr 1,1 bold
```

### PRM-2: Twenty-five

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

Input, one step per line:

```text
\e[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1m  # 24 zeros, then bold
A
```

Expected screen:

```text
|A_______|
attr 1,1 bold
```

### PRM-3: Past thirty, the digits run together

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

Input, one step per line:

```text
\e[0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;1m  # 29 zeros, 3, 1: the 30th is 31, red
A
```

Expected screen:

```text
|A_______|
attr 1,1 fg=1 -bold
```

### PRM-4: Subparameters where none are taken

Input, one step per line:

```text
\e[2:3H   # ignored
X
```

Expected screen:

```text
|X_______|
cursor 1,2
```

### PRM-5: A private marker in the wrong place

Input, one step per line:

```text
\e[2?3H
\e[??5h
X
```

Expected screen:

```text
|X_______|
cursor 1,2
```

### PRM-6: A parameter after an intermediate

Input, one step per line:

```text
\e[?1$2p   # not DECRQM
```

Expected screen:

```text
|________|
reply none
```

### PRM-7: Empty parameters

Input, one step per line:

```text
\e[;;3H   # CUP with defaults: the third is not used
X
```

Expected screen:

```text
|X_______|
cursor 1,2
```

---

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