WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@joshka-oai
Copy link
Collaborator

Title: feat(tui2): improve transcript copy fidelity

This PR improves transcript selection → clipboard output in TUI2 so copied text matches user intent rather than the current viewport layout.

Note

streaming output still bakes in newlines during the stream — see streaming_wrapping_design.md for more details on fixing this.

What changes for users

  • Copy treats soft-wrapped prose as a single logical line (no hard newlines introduced purely due to wrapping).
  • Copy preserves meaningful indentation for code/preformatted content and avoids “narrow terminal truncates the copied line”.
  • Copy emits Markdown source markers (inline backticks + fenced code blocks) even when we render via styling.

Design notes (what’s different vs tui)

  • codex-tui largely deals with terminal-native selection/copy and only needs HistoryCell::transcript_lines(...).
  • codex-tui2 implements app-driven selection/copy that can span off-screen content and soft-wrap boundaries, so we need extra metadata to preserve intent across reflow/scroll.

Implementation overview

Joiner plumbing (soft-wrap fidelity)

  • codex-rs/tui2/src/history_cell.rs
    • Introduces TranscriptLinesWithJoiners { lines, joiner_before } + HistoryCell::transcript_lines_with_joiners(...).
    • joiner_before[i] is Some(joiner) when line i is a soft-wrap continuation and copy should insert joiner instead of ; None indicates a hard break.
  • codex-rs/tui2/src/wrapping.rs
    • Adds word_wrap_line_with_joiners / word_wrap_lines_with_joiners.
    • Simplified so word_wrap_line delegates to word_wrap_line_with_joiners (single source of truth).

Transcript rendering split

  • codex-rs/tui2/src/transcript_render.rs
    • Centralizes “cells → flattened visual lines”, TranscriptLineMeta, spacer rows, and joiners.
    • Applies viewport wrapping to prose while leaving preformatted/code lines unwrapped to preserve indentation.
    • Moves ANSI-export rendering (render_lines_to_ansi) out of app.rs.

Clipboard reconstruction

  • codex-rs/tui2/src/transcript_copy.rs
    • Reconstructs clipboard text from the wrapped visual lines + joiners.
    • Uses style-derived cues to decide inline code vs code runs:
      • inline code spans are wrapped in backticks
      • code/preformatted runs are fenced with triple backticks
    • Selection slicing is display-width aware (handles wide glyphs).
    • Includes explicit handling so selecting “to the right edge” on code lines copies the full logical line (not viewport-truncated).

Copy UX separation

  • codex-rs/tui2/src/transcript_copy_ui.rs
    • Shortcut detection + key matching + on-screen “copy” pill rendering/hit testing.

ANSI emission consistency

  • codex-rs/tui2/src/insert_history.rs
    • Documents and implements direct SGR fg/bg emission for ratatui::Color (including Rgb/Indexed) so ANSI output is deterministic across impl Write backends (used by render_lines_to_ansi and tests).

Markdown rendering style fix (code-in-blockquote)

  • codex-rs/tui2/src/markdown_render.rs
    • Ensures code blocks keep code styling even under blockquote style so downstream copy cues remain stable.

Reviewer notes / maintenance hazards

  • Code/preformatted detection currently uses “cyan line/span styling” as the cue. If transcript styling changes, update:
    • transcript_copy’s is_code_block_line / span_is_inline_code
    • transcript_render’s preformatted “don’t wrap” predicate
  • lines and joiner_before must stay aligned; transcript_render is the source of truth for both.

Tests

  • Added/updated unit tests for:
    • joiner behavior and invariants in wrapping
    • copy reconstruction (soft-wrap joins, Markdown markers, code fences/indentation, viewport-edge code copying)
    • wide glyph selection/slicing cases
  • Ran: cargo test -p codex-tui2

Improve clipboard output for transcript selections, even when content is wrapped.

- Preserve meaningful indentation for code blocks.
- Treat soft-wrapped prose as a single logical line via wrap joiners.
- Emit Markdown source markers when copying (inline backticks, code fences).
- Extract selection/copy reconstruction into `transcript_copy`.
- Thread joiner metadata through history rendering and wrapping helpers.
- Update docs and add focused test coverage.
@joshka-oai joshka-oai force-pushed the joshka/tui2-copy-fidelity branch from f7d4640 to c8901b3 Compare December 23, 2025 07:09
@joshka-oai
Copy link
Collaborator Author

Left side is select + copy of text from codex on right.
Lines are correctly rendered with corerct markdown and wrapping

image

@joshka-oai joshka-oai marked this pull request as draft December 23, 2025 07:51
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.

2 participants