# `Raxol.Terminal.InlineDriver.Sequences`
[🔗](https://github.com/DROOdotFOO/raxol/blob/v2.7.0/lib/raxol/terminal/inline_driver/sequences.ex#L1)

Pure ANSI byte-sequence constants + builders for the inline driver
profile (unit T2d).

Kept separate from the GenServer (`Raxol.Terminal.InlineDriver`) so the
Tier A suite can assert on exact bytes without a process, a device, or
the OS tty -- this module has no side effects at all.

## The canonical teardown order (pinned, load-bearing)

Ordering is not cosmetic: the negative suite proves each swap strands the
cursor or echoes escapes into the restored shell.

  1. **input modes off** (`modes_off/0`) -- while raw mode is still on,
     so the bytes are never echoed back as if typed.
  2. **release the scroll region** (`release_region/0`, `CSI r`) -- BEFORE
     any absolute cursor move, else the move clamps into the old region
     (INV-1).
  3. **autowrap + cursor restore** (`autowrap_cursor/0`) -- before the
     final prompt handoff (INV-2).
  4. **cursor to bottom + fresh line** (`move_bottom/1`) -- unclamped now
     that the region is gone.
  5. **stty restore** -- LAST, after every escape write, else cooked mode
     line-processes the escapes as garbage (INV-3). This step is OS-level
     and lives in `Raxol.Terminal.InlineDriver.emit_teardown/2`, not here.

# `autowrap_cursor`

```elixir
@spec autowrap_cursor() :: binary()
```

Step 3: re-enable autowrap (DECAWM) and show the cursor.

# `cursor_position_request`

```elixir
@spec cursor_position_request() :: binary()
```

DSR-6 (`CSI 6n`): ask the terminal where its cursor is. The terminal
replies on the INPUT stream with a CPR (`CSI row ; col R`), which
`Raxol.Terminal.InlineDriver.probe_cursor/2` consumes via
`Raxol.Terminal.InlineDriver.CursorReport` — the reply is never
allowed to reach the app's input path. Emitted only by that opt-in
probe, never by `init_bytes/0`: a probe writes bytes to the device,
so callers must ask for it.

# `init_bytes`

```elixir
@spec init_bytes() :: binary()
```

Startup bytes. Deliberately contains **no** `\e[?1049h` -- the inline
profile never owns the alternate screen (LC-P-NOALT, T2d's headline
invariant). Resets stray mouse modes, then enables focus reporting and
bracketed paste (both reversed by `modes_off/0` at teardown).

# `modes_off`

```elixir
@spec modes_off() :: binary()
```

Step 1: disable bracketed paste, focus reporting, and all mouse modes.

# `mouse_on`

```elixir
@spec mouse_on() :: binary()
```

Enable click reporting (SGR encoding, press/release only). Written by
the driver AFTER `init_bytes/0` when its `mouse?:` option is set; the
teardown's `modes_off/0` disables it unconditionally either way.

# `move_bottom`

```elixir
@spec move_bottom(pos_integer()) :: binary()
```

Step 4: absolute-move to `(rows, 1)` (`park_bottom/1`) then CRLF. Safe
to be unclamped because the scroll region is already gone by this
point (step 2).

# `park_bottom`

```elixir
@spec park_bottom(pos_integer()) :: binary()
```

The bare absolute park at `(rows, 1)` -- the shared "magic byte"
builder both `move_bottom/1` (park + fresh-line CRLF, for the shell
handoff) and `suspend_bytes/1` (park only, for the editor handoff)
compose from. Safe to be unclamped only AFTER the region release
(step 2).

# `release_region`

```elixir
@spec release_region() :: binary()
```

Step 2: `CSI r` -- reset the scroll region to the full screen.

# `suspend_bytes`

```elixir
@spec suspend_bytes(pos_integer()) :: binary()
```

Suspend bytes -- the editor-handoff sibling of `teardown_bytes/1`
(an external `$EDITOR` process, not process exit, is about to own the
tty). Steps 1-3 of the canonical teardown order, verbatim
(`modes_off/0`, `release_region/0`, `autowrap_cursor/0`), plus an
absolute cursor park at `(rows, 1)` -- WITHOUT step 4's trailing CRLF.

## Why steps 1-3 apply unchanged

Same reasoning as the teardown order: modes must go off WHILE STILL
RAW (else the escapes echo back as if typed), and `CSI r` must precede
any absolute cursor move (else the move clamps into the still-active
old region, INV-1).

## Why this DROPS step 4's trailing CRLF

`move_bottom/1`'s CRLF exists to hand the SHELL a fresh line after this
process exits for good -- the shell prompt that appears next expects to
start at column 1 of a blank row. An editor handoff is not that: the
region has just been released, so a CRLF here would scroll the FULL
(now region-free) screen up by one line, smearing whatever was on the
bottom row (a stale footer) into the row above it -- and that row is
inside the just-released history area, which cannot be re-addressed
once scrolled (the seal-time-only invariant). The bare park (`CSI
rows;1 H`, no `\r\n`) leaves the cursor at the right row without
scrolling anything, which is exactly what the editor needs: it will
clear/redraw its own screen (or, for a non-alt-screen editor, simply
start typing from wherever the cursor already is) without this driver
having pre-scrolled a footer row into unreachable history first.

Never emits `\e[2J`/`\e[3J` -- same substrate law as every other
sequence builder in this module.

# `teardown_bytes`

```elixir
@spec teardown_bytes(pos_integer()) :: binary()
```

Steps 1-4 concatenated in canonical order. Step 5 (stty restore) is
OS-level and not modeled here -- see
`Raxol.Terminal.InlineDriver.emit_teardown/2`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
