refactor(ui)!: remove alternate screen, mouse capture, and in-app scrolling - #243
Open
wowi42 wants to merge 6 commits into
Open
refactor(ui)!: remove alternate screen, mouse capture, and in-app scrolling#243wowi42 wants to merge 6 commits into
wowi42 wants to merge 6 commits into
Conversation
Enabling crossterm mouse capture hijacks the terminal emulator's native text selection: users cannot select text with the mouse while the app runs. Wheel-scroll events require the same mouse-reporting mode, so there is no partial fix — capture stays on or goes off entirely. Decision: drop mouse capture and all mouse-driven features (wheel scroll, click-to-place-cursor, drag selection/copy, click-to-open links) to shrink the codebase and restore native terminal selection and OSC8 link clicking handled by the terminal emulator itself. Keyboard scrolling (PageUp/PageDown/Home/End) is unchanged, and the multiline input viewport still follows the cursor.
Owner
|
Can you pls rebase on last commit? Everything looks ready to merge |
…se-capture Keep the headless test infrastructure from gi-dellav#241 (RenderBackend/FakeBackend, tui_loop_tests) alongside the mouse-support removal; the scroll/resize loop test now drives scrolling through PageUp/PageDown keys since the wheel UserEvent variants are gone.
Remove the alternate screen so the terminal's native scrollback and mouse text selection work like a normal shell, and delete the in-app scroll feature (PageUp/PageDown/Home/End handlers, scroll_offset machinery, SCROLL indicators) that native scrollback replaces. New rendering model (renderer.rs): - Committed lines: finalized feed content is printed exactly once into native scrollback, tracked by a (block, line, width) print watermark with pure advance/clamp/commit-count math (unit-tested). - Live block: the only redrawn region, bottom-anchored — streaming region (tail of the running feed block + partial scratch) above the input box and statusline. Redraws are relative (cursor up, clear below); the cursor never moves above the block start. - Over-tall running blocks spill their top lines into scrollback; resize keeps printed lines' old wrap and remaps the watermark to the same (block, line); /clear wipes the screen shell-style and resets the watermark; feed rebuilds (undo/redo/rewind) clamp the watermark so nothing reprints. - Sub-shell escapes ($EDITOR, Ctrl+G editor, Ctrl+H lazygit, /init, /tutor) become suspend (erase live block, raw off) / resume (raw on, redraw block) instead of alt-screen dances; /docs prints inline. - Pickers paint just above the live block using its current height. TerminalGuard keeps raw mode, bracketed paste and keyboard enhancement flags, and anchors the UI to the bottom row at startup; teardown erases the live block and leaves the cursor on a fresh line.
Long input lines no longer scroll horizontally: each hard line is soft-wrapped at the text width (cols minus prompt) and occupies 1..N display rows, with the existing vertical windowing (input capped to ~30% of rows) and caret mapping now operating on wrapped rows. The input_scroll_offset machinery is gone; wrap math lives in pure pub(crate) fns wrap_input_segments / wrapped_cursor with unit tests. New keybindings in the input editor: - Alt+Left / Alt+Right: previous word start / next word end (same as the existing Alt+B / Alt+F). - Ctrl+Left / Ctrl+Right: same word jumps. - Ctrl+Backspace: delete previous word into the kill ring. Plain and Shift+ arrows keep char-wise movement. /help keys section and docs/COMMANDS.md list the new bindings.
The stderr tracing layer (default filter warn) printed log lines straight to the terminal mid-session. The alternate screen used to hide this behind full repaints; with inline rendering a stray write shifts the screen and corrupts the live block's cursor math. Interactive mode now never attaches the stderr layer; explicitly requested console logging (--log-level / RUST_LOG) is redirected to a timestamped log file with the path printed at startup. Print mode (-p) keeps stderr logging.
In the inline-rendering model there is no alternate screen and the live block is the only redrawn region. Pickers used to paint directly to stdout at absolute rows above the block; the block's relative erase could never reach those rows, so closing a slash-command picker (or the models/file/rewind pickers) left permanent remnants on screen. Fix: make the picker a section of the live block. - Add renderer types PickerRow/PickerView; draw_live_block now accepts an optional picker view and renders it between the streaming region and the input separator. - Replace each picker's draw() method with a view() that returns a pure PickerView (rows + optional header). The list-windowing logic is now a pure helper in pickers/mod.rs. - Pickers no longer write to stdout directly; their rows flow through the same RenderBackend as the rest of the UI, so the headless test guard remains intact and FakeBackend can capture picker output. - snapshot/LiveArgs now include the picker view, so closing/shrinking a picker naturally triggers a full block redraw and erases the old rows. - Remove the separate renderer.invalidate() hack that used to paper over the direct-stdout picker painting. - Drop per-picker monochrome fields/plumbing; the renderer's own monochrome flag resolves Green/DarkGrey for picker rows. Regression tests: bottom_snapshot dirty tests plus FakeBackend tests for picker painting, close-erase, shrink-erase, and header-row accounting; pure picker-window tests in pickers/mod.rs. ARCHITECTURE.md updated to note that the live block includes the picker overlay.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Two terminal-takeover behaviors break the host terminal's native affordances:
Two related input-box UX issues are fixed along the way (same terminal-native theme): long input lines horizontally scrolled (the whole line visibly shifted while typing at the window edge), and cursor placement for edits was char-by-char only.
What is removed
What is added
--log-level/RUST_LOGare redirected to a timestamped log file. Print mode (-p) keeps stderr logging./command picker, models picker, etc. now render inside the live block so their rows are erased on close. Painting directly to stdout above the live block left permanent remnants in the inline model.What stays the same
Input box, statusline, streaming, spinners, permission/chain prompts, picker UX — a small live block at the bottom redraws in place as before. Links remain clickable via terminal-native OSC8. /clear behaves like shell Ctrl-L; /undo prints a rewind banner instead of un-printing.
Trade-offs
Verification
/+Esc and/helpleave no picker remnants; clean exit