# Scrolling Mode (DECSCLM)

> Choose between jump scrolling and smooth, slow scrolling.

- **Sequence:** `CSI ? 4 h/l`
- **Defaults:** reset (jump scrolling) in xterm
- **DEC STD 070:** [§5.4.3 Set/Reset Scrolling Mode, p. 5-32](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n286/mode/1up)
- **VT220:** [§4.6.11 Scrolling Mode (DECSCLM)](https://vt100.net/docs/vt220-rm/chapter4.html#S4.6.11)
- **VT510:** [DECSCLM—Scrolling Mode](https://vt100.net/docs/vt510-rm/DECSCLM.html)

Mode 4 chooses how fast the screen scrolls. Set (`CSI ? 4 h`), it scrolls
slowly and smoothly; DEC STD 070 asks for about six lines a second, slow
enough to make the text "recognizable". Reset (`CSI ? 4 l`), it jumps, as fast
as the terminal can.

Only the speed changes. What ends up on the screen is the same either way,
so the cases here can check only that the mode is recorded, through
[DECRQM](https://control-codes.page/csi/decrqm/index.html.md), and that scrolling still scrolls.

DEC STD 070 and the VT510 manual make smooth scrolling the default. xterm
starts in jump scrolling: its `jumpScroll` resource is true by default
([`charproc.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L451)), and only when it is false does xterm
start with smooth scrolling set
([`charproc.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L11996-L11997)). Setting the mode
([`charproc.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L7581-L7589)) turns jump scrolling off, and
DECRQM reports the mode as set or reset
([`do_dec_rqm`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L5493-L5495)). The cases follow xterm, and
libghostty-vt matches it.

## Support

| Terminal | Version | Support | Notes |
| --- | --- | --- | --- |
| VT220 | [manual](https://vt100.net/docs/vt220-rm/), 2nd ed., 1984 | Yes | [§4.6.11 Scrolling Mode (DECSCLM)](https://vt100.net/docs/vt220-rm/chapter4.html#S4.6.11) |
| VT510 | [manual](https://vt100.net/docs/vt510-rm/), 1st ed., 1993 | Yes | [DECSCLM](https://vt100.net/docs/vt510-rm/DECSCLM.html) |
| xterm | patch 412, [xterm-411a](https://github.com/ThomasDickey/xterm-snapshots/tree/xterm-411a) | Yes | jump scrolling by default (`jumpScroll`) |
| libghostty-vt | [0f171f6](https://github.com/ghostty-org/ghostty/tree/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90) | Yes | records the mode |
| kitty | 0.49.1, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/kitty.json) | No | fails the case that shows it working |
| foot | 1.28.0, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/foot.json) | No | fails the case that shows it working |
| xterm.js headless | 6.0.0, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/xtermjs.json) | No | fails the case that shows it working |
| alacritty_terminal | 0.26.0, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/alacritty.json) | No | fails the case that shows it working |
| ConEmu | build 230724, its [documentation](https://conemu.github.io/en/AnsiEscapeCodes.html) | No | not in ConEmu's list, [ANSI escape codes](https://conemu.github.io/en/AnsiEscapeCodes.html) |
| rxvt-unicode | 9.31, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/urxvt.json) | Yes | passes the case that shows it working |
| VTE | 0.84.1, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/vte.json) | No | fails the case that shows it working |

## Validation

### DECSCLM-1: Jump scrolling by default

Input, one step per line:

```text
\e[?4$p
```

Expected screen:

```text
|_____|
reply \e[?4;2$y
```

### DECSCLM-2: Set and reset

Input, one step per line:

```text
\e[?4h
\e[?4$p
\e[?4l
\e[?4$p
```

Expected screen:

```text
|_____|
reply \e[?4;1$y\e[?4;2$y
```

### DECSCLM-3: Smooth scrolling still scrolls

Input, one step per line:

```text
A\r\nB\r\nC
\e[?4h     # smooth scrolling
\r\nD
```

Expected screen:

```text
|B____|
|C____|
|D____|
```

---

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