Fullscreen the pane while an editor holds it
ctrl-g opens the prompt in $EDITOR, which takes the child's pty over via the alternate screen — something Claude Code never does itself. The compact frame looks for the input box's two rules, so an editor could only ever be cropped by it. Follow the alternate screen instead: give the pane the whole screen for as long as the editor lasts, then put it back. Edge-triggered, so ctrl-f still wins.
This commit is contained in:
32
CLAUDE.md
32
CLAUDE.md
@@ -160,7 +160,10 @@ src/term.rs embedded claude pane: spawns `claude --session-id <uuid>` in a
|
||||
see the pane-scroll invariant. `shows_error` reports whether
|
||||
the compact frame is currently holding an error Claude Code
|
||||
printed, which is what stops the ctrl-l wipe from deleting it —
|
||||
see the pane-error invariant
|
||||
see the pane-error invariant. `alt_screen` reports the
|
||||
*alternate* screen — an `$EDITOR` (nvim, `git commit`, a pager)
|
||||
Claude Code launched into the same pty — which auto-fullscreens
|
||||
the pane; see the alt-screen invariant
|
||||
src/reload.rs hot reload: ctrl-r `execve`s the binary now on disk *into this
|
||||
process* — same pid, so the listener socket, the `claude` child
|
||||
and (via a JSON snapshot) the live feed all cross over. Builds
|
||||
@@ -571,6 +574,33 @@ agentId: <hex>`), and the real completion is injected into the parent's next
|
||||
that already ran *before* you went fullscreen is gone for good though —
|
||||
Ink redraws only the live frame, so fullscreen shows history from that
|
||||
point on.
|
||||
|
||||
- **An editor on the child's alternate screen owns the whole pane.** ctrl-g
|
||||
opens the prompt in `$EDITOR` (so do `/memory` and a `git commit` a tool
|
||||
runs), and that program takes the pty over via the alternate buffer — which
|
||||
Claude Code itself never does (the pane-scroll invariant leans on the same
|
||||
fact). So `EmbeddedTerm::alt_screen` means exactly one thing: what is on
|
||||
screen is not a prompt to frame, and framing it can only crop it
|
||||
(`compact_frame` looks for the input box's two rules, which nvim never
|
||||
draws). `ui::sync_alt_screen` therefore fullscreens the pane for as long as
|
||||
the editor lasts and puts it back after. Four rules:
|
||||
1. **Edge-triggered, never re-asserted per frame**, which is what leaves
|
||||
ctrl-f in charge: a manual toggle mid-edit sticks instead of being undone
|
||||
on the next draw, and it clears the restore flag
|
||||
(`EmbedUi::alt_fullscreen`) so quitting the editor doesn't reverse it. A
|
||||
pane that was *already* fullscreen stays fullscreen afterwards — only a
|
||||
fullscreen we entered ourselves is undone.
|
||||
2. **Gated on pane focus**, keeping fullscreen ⇔ focused: ctrl-↑ hands the
|
||||
screen back to the feed mid-edit, ctrl-↓ returns it to the editor.
|
||||
3. **The ctrl-l wipe is cancelled** while the alternate screen is up, for a
|
||||
different reason than fullscreen's: that keystroke is meant for Claude
|
||||
Code's input box, and sending it into nvim is not ours to do. The scroll
|
||||
view also resets on both edges — the two screens index stable rows
|
||||
differently, and the alternate one holds no scrollback at all.
|
||||
4. **A hot reload reads the flag off the adopted child** before the first
|
||||
draw, so an editor still open at ctrl-r raises no edge and the
|
||||
snapshotted `PaneState::alt_fullscreen` stays meaningful.
|
||||
|
||||
- Tool input streams as raw JSON fragments; pretty-printed only on
|
||||
`content_block_stop`. Streaming text re-renders markdown on every change
|
||||
(FeedCache fingerprints by content length + done + result), so partial
|
||||
|
||||
Reference in New Issue
Block a user