|
tui: copy chat to system clipboard via reading mode + selection fixes
Two ways to copy chat content out of the TUI now work: 1. In-app selection (Ctrl+C, OSC 52): _ChatItemView.render() now builds a selection-aware Content from the rich renderable instead of letting Static wrap a Panel into a non-selection-aware RichVisual — so the magenta drag-select highlight actually renders and get_selection returns clean, chrome-free text. rich Segment styles are converted to Textual Style (Style.from_rich_style) so the selection_style merge doesn't crash, and None segment styles are guarded. get_content_height is overridden to compute auto-height straight from the rich renderable; without it the width-keyed Content churned new Visual objects per width change and spread the layout-settling cascade across refreshes, leaving a deferred scroll_end at an intermediate max_scroll_y (chat no longer stuck to bottom). Theme defines screen-selection-background/foreground so the highlight is visible. 2. Reading mode (Ctrl+R) for terminals without OSC 52 (e.g. GNOME Console, TERM_PROGRAM=kgx, which silently ignores OSC 52 so Ctrl+C never reaches the OS clipboard). Toggling the app's reading-mode class hides the chrome around the chat (right status/todo column, input prompt, status bar, chat outer border) and re-renders every message without its Panel borders via the registry's new render_plain — so Shift+drag + Ctrl+Shift+C copies just the conversation text to the system clipboard. ContentRenderer.render_plain defaults to unwrapping Panel/Padding(Panel) to its body; assistant messages and plan_ready override it to raw Text(content) so rich Markdown doesn't re-wrap fenced code blocks in their own bordered Panels. ChatPanel tracks reading mode and re-renders visible widgets in place (scroll preserved); new streamed items pick up the mode on mount. Help (/help) now lists keys and documents both copy paths. Tests: render_plain parametrized across all item types, message renderer plain tests, chat panel reading-mode toggle (borders off/on, scroll kept, new items borderless), tui_app reading-mode chrome hide, plus the existing selection suite. Full suite green (922 passed, 1 skipped). |
|---|
|
|
| clients/terminal/tui/commands/builtin.py |
|---|
| clients/terminal/tui/renderers/base.py |
|---|
| clients/terminal/tui/renderers/message.py |
|---|
| clients/terminal/tui/renderers/planning.py |
|---|
| clients/terminal/tui/renderers/registry.py |
|---|
| clients/terminal/tui/themes.py |
|---|
| clients/terminal/tui/tui_app.py |
|---|
| clients/terminal/tui/widgets/chat_panel.py |
|---|
| tests/clients/test_chat_panel.py |
|---|
| tests/clients/test_message_renderers.py |
|---|
| tests/clients/test_render_plain.py 0 → 100644 |
|---|
| tests/clients/test_tui_app.py |
|---|