fix(editor): re-window on terminal resize (harness-review P2)#54
Conversation
The editor captured columns/rows once at startEditor and IEditorHandle had no resize hook, so the CLI's resize handler only re-pinned the status bar — the editor kept wrapping at the old width and windowing at the old height. After a shrink, renderEditor produced a frame sized for the pre-resize terminal and setEditor (live rows) clipped it, dropping the current line off-screen. Reproduced via VirtualScreen: type 12 lines on a 24-row terminal, shrink to 10 → the current line vanished. Fix: IEditorHandle.resize(columns, rows) updates the (now-mutable) dims and repaints; cli.ts calls it from the resize handler via a resizeEditor callback (editorHandle lives in a nested scope). Ignores non-positive dims. 2 regression tests in editor-e2e.test.ts (shrink keeps the line visible; 0×0 is a no-op). bun run validate green (1781 pass).
The render/CLI manifest entry still described the readline REPL; PR #52 replaced it with the multi-line editor (src/editor/*), which had no contract. Refresh render/CLI invariants (bottom-anchored block, resize updates editor dims, use the VirtualScreen grid harness) and add a dedicated editor subsystem entry (grapheme cursor, paste-never-submits, non-ASCII accepted, window-to-visible-capacity).
There was a problem hiding this comment.
Code Review
This pull request adds support for terminal resizing in the REPL multi-line editor, ensuring the editor updates its dimensions and repaints correctly without clipping the current line. Feedback suggests addressing type safety issues where terminal dimensions might be undefined, preventing potential memory leaks by properly removing the resize event listener on REPL exit, and optimizing the editor's resize method to avoid redundant repaints when dimensions do not change.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…dims-changed guard - cli.ts: extract the resize listener to a named handleResize and detach it on loop exit (process.stdout.off) so an anonymous listener doesn't pin the REPL closure for the process lifetime (Gemini). Dropped the suggested ?? 0 — columns /rows are typed number here, so it's an unnecessary-condition lint error. - controller.ts: resize only repaints when the dimensions actually changed, so duplicate/high-frequency resize events don't cause no-op repaints/flicker (Gemini).
Harness-review finding (render/CLI subsystem)
P2 — render correctness after resize. The multi-line editor captured
columns/rowsonce instartEditorandIEditorHandlehad no resize hook, so the CLI'sprocess.stdout.on("resize")handler only re-pinned the status bar. The editor kept wrapping at the old width and windowing at the old height; after a shrink,renderEditorproduced a frame sized for the pre-resize terminal andsetEditor(liverows) clipped it — dropping the current line off-screen.This reintroduced the cursor-clip class (the EDITOR_RESERVED_ROWS fix only aligned dims at startup).
Reproduced (VirtualScreen)
Type 12 lines on a 24-row terminal (fits,
maxRows=21), shrink to 10 rows → the current linelastline!was not visible (rowsContaining= 0).Fix
IEditorHandle.resize(columns, rows)updates the now-mutable dims and repaints; ignores non-positive dims (transient 0×0).cli.tscalls it from the resize handler via aresizeEditorcallback (the editor handle lives in a nested scope, so an outer-scope callback avoids hoisting / listener leaks).Regression tests (
editor-e2e.test.ts)bun run validategreen (1781 pass, 0 fail).Also a manifest finding:
docs/harness-subsystems.mdrender/CLI entry still describes the readline REPL — PR #52 replaced it with the editor (src/editor/*), which has no manifest entry. Will refresh the manifest in a follow-up.