Skip to content

feat: replay scrollback history on attach#69

Merged
ttak0422 merged 2 commits into
mainfrom
feat/scrollback-replay-on-attach
Jul 5, 2026
Merged

feat: replay scrollback history on attach#69
ttak0422 merged 2 commits into
mainfrom
feat/scrollback-replay-on-attach

Conversation

@ttak0422

@ttak0422 ttak0422 commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the "cannot scroll" bug: attaching to a session only rebuilt the visible screen via STATE_SYNC, so after a Neovim restart the terminal buffer had no scrollback — normal-mode scrolling, search, and markers found nothing above the viewport.

Implements proposals 0001 and 0002 (included under docs/proposals/):

  • Proto: PROTO_VERSION = 1, client HELLO (version + flags), server HELLO_ACK, server HISTORY, plus encode/parse helpers.
  • Session: history_formatted() pages through the vt100 scrollback with set_scrollback and emits history lines oldest-first as a raw escape-sequence stream. Wrapped rows are emitted without \r\n so long lines re-join in the terminal buffer and search works across wrap points. Ends with one viewport of padding so the following STATE_SYNC redraw does not overwrite the history tail. Empty while the alternate screen is active.
  • Server: records proto/wants_history from HELLO; queues HISTORY once, just before the initial STATE_SYNC. REDRAW and later RESIZE re-snapshots never resend history, so auto_redraw (which fires on every BufEnter) cannot duplicate it. HELLO_ACK is (re)queued ahead of the first STATE_SYNC even when replace_send_buf drops queued frames; duplicate ACKs are idempotent. Replay length capped by PTERM_HISTORY_REPLAY_LINES (default: unlimited).
  • Bridge: sends HELLO + RESIZE in a single write, writes HISTORY payloads to stdout like OUTPUT, and prints a one-line notice on protocol mismatch (a daemon that never sends HELLO_ACK before the first STATE_SYNC is treated as v0).

Backward compatible in both directions: clients or daemons without HELLO keep the legacy behavior.

Proposals 0003 (daemon handoff) and 0004 (reboot persistence) are recorded as withdrawn.

Test plan

  • cargo test: 37 + 9 proto tests pass, including new coverage for history content/no-duplication/max_lines/wrapped re-join/altscreen (session), frame ordering HELLO_ACKHISTORYSTATE_SYNC, once-only history, and legacy-client behavior (server), and hello/hello_ack roundtrips (proto).
  • E2E with the release binary: attached to a session holding 200 printed lines; observed history from line 1, viewport padding, then the STATE_SYNC redraw, with no protocol notice and clean detach.

🤖 Generated with Claude Code

ttak0422 and others added 2 commits July 5, 2026 19:03
Attaching to a session only rebuilt the visible screen via STATE_SYNC,
so after a Neovim restart the terminal buffer had no scrollback and
normal-mode scrolling/search found nothing above the viewport.

Add a HELLO/HELLO_ACK protocol version handshake (proposal 0001) and a
HISTORY frame (proposal 0002): clients that set REQUEST_HISTORY in
HELLO receive the daemon's vt100 scrollback as a raw escape-sequence
stream once, just before the initial STATE_SYNC. Wrapped rows are
re-joined so search works across wrap points, and viewport padding
keeps the STATE_SYNC redraw from overwriting the history tail. REDRAW
and later RESIZE re-snapshots never resend history, so auto_redraw
cannot duplicate it. Clients and daemons without HELLO keep the legacy
behavior, so mixed-version setups stay compatible.

The replay length is capped by PTERM_HISTORY_REPLAY_LINES (default:
unlimited).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0001 (protocol handshake) and 0002 (scrollback replay) are implemented;
0003 (daemon handoff) and 0004 (reboot persistence) are withdrawn as
not worth their complexity.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ttak0422
ttak0422 merged commit 27e1ec9 into main Jul 5, 2026
2 checks passed
@ttak0422
ttak0422 deleted the feat/scrollback-replay-on-attach branch July 5, 2026 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant