# Back Index and Forward Index (DECBI, DECFI)

> Move the cursor one column, scrolling the region sideways at the margin.

- **Sequence:** `ESC 6`
- **DEC STD 070:** [§5.4.3 Back Index, p. 5-39](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n293/mode/1up)
- **VT510:** [DECBI—Back Index](https://vt100.net/docs/vt510-rm/DECBI.html)

The sideways versions of [RI](https://control-codes.page/esc/ri/index.html.md) and [IND](https://control-codes.page/c0/lf/index.html.md): `ESC 6` (DECBI)
moves the cursor one column left, and `ESC 9` (DECFI) one column right. At
the edge they scroll instead. DECBI at the left margin shifts the region
between the margins one column right, losing the column at the right margin
and bringing in a blank one at the left, with the cursor staying put; DECFI
at the right margin does the same the other way. With no margins set, the
margins are the edges of the screen.

A cursor outside the left and right margins just moves one column, and at
the edge of the screen it does nothing. DEC STD 070 defines DECFI at
[§5.4.3, p. 5-37](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n291/mode/1up),
and the VT510 manual has [DECFI—Forward Index](https://vt100.net/docs/vt510-rm/DECFI.html).

DEC STD 070 makes both part of level 4's horizontal scrolling extension.
xterm, a VT420 unless told otherwise, implements them
([`CASE_DECBI`, `CASE_DECFI`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L5414-L5428),
[`xtermColIndex`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/util.c#L1145-L1170)),
and the cases follow it and esctest2's `decbi.py` and `decfi.py`.

libghostty-vt, a VT220 (see [DA](https://control-codes.page/csi/da/index.html.md)), has no case for `ESC 6` or
`ESC 9` in `stream.zig` and ignores both, so the cases are known
differences.

## Validation

### DECBI-1: Back one column

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

Input, one step per line:

```text
\e[1;4H
\e6
X
```

Expected screen:

```text
|__X__|
cursor 1,4
```

### DECBI-2: At the left edge, the screen scrolls right

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

Input, one step per line:

```text
ABCD
\e[1;1H
\e6
```

Expected screen:

```text
|_ABCD|
cursor 1,1
```

### DECBI-3: At the left margin, the region scrolls right

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

Input, one step per line:

```text
ABCDE
\e[?69h   # allow left and right margins
\e[2;4s   # margins at columns 2 and 4
\e[1;2H   # on the left margin
\e6
```

Expected screen:

```text
|A_BCE|
cursor 1,2
```

### DECBI-4: Left of the margin, it only moves

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

Input, one step per line:

```text
ABCDE
\e[?69h   # allow left and right margins
\e[3;5s   # margins at columns 3 and 5
\e[1;2H
\e6
X
```

Expected screen:

```text
|XBCDE|
cursor 1,2
```

### DECBI-5: DECFI forward one column

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

Input, one step per line:

```text
\e[1;2H
\e9
X
```

Expected screen:

```text
|__X__|
cursor 1,4
```

### DECBI-6: DECFI at the right edge scrolls left

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

Input, one step per line:

```text
ABCDE
\e[1;5H
\e9
```

Expected screen:

```text
|BCDE_|
cursor 1,5
```

### DECBI-7: DECFI right of the margin only moves

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

Input, one step per line:

```text
\e[?69h   # allow left and right margins
\e[1;3s   # margins at columns 1 and 3
\e[1;4H
\e9
X
```

Expected screen:

```text
|____X|
```

---

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