fix: wrap long exec lines in transcript overlay (#7481)
What ----- - Fix the Ctrl+T transcript overlay so that very long exec output lines are soft‑wrapped to the viewport width instead of being rendered as a single truncated row. - Add a regression test to `TranscriptOverlay` to ensure long exec outputs are rendered on multiple lines in the overlay. Why ---- - Previously, the transcript overlay rendered extremely long single exec lines as one on‑screen row and simply cut them off at the right edge, with no horizontal scrolling. - This made it impossible to inspect the full content of long tool/exec outputs in the transcript view, even though the main TUI view already wrapped those lines. - Fixes #7454. How ---- - Update `ExecCell::transcript_lines` to wrap exec output lines using the existing `RtOptions`/`word_wrap_line` helpers so that transcript rendering is width‑aware. - Reuse the existing line utilities to expand the wrapped `Line` values into the transcript overlay, preserving styling while respecting the current viewport width. - Add `transcript_overlay_wraps_long_exec_output_lines` test in `pager_overlay.rs` that constructs a long single‑line exec output, renders the transcript overlay into a small buffer, and asserts that the long marker string spans multiple rendered lines.
This commit is contained in:
parent
1cfc967eb8
commit
70b97790be
2 changed files with 49 additions and 1 deletions
|
|
@ -219,7 +219,12 @@ impl HistoryCell for ExecCell {
|
|||
|
||||
if let Some(output) = call.output.as_ref() {
|
||||
if !call.is_unified_exec_interaction() {
|
||||
lines.extend(output.formatted_output.lines().map(ansi_escape_line));
|
||||
let wrap_width = width.max(1) as usize;
|
||||
let wrap_opts = RtOptions::new(wrap_width);
|
||||
for unwrapped in output.formatted_output.lines().map(ansi_escape_line) {
|
||||
let wrapped = word_wrap_line(&unwrapped, wrap_opts.clone());
|
||||
push_owned_lines(&wrapped, &mut lines);
|
||||
}
|
||||
}
|
||||
let duration = call
|
||||
.duration
|
||||
|
|
|
|||
|
|
@ -748,6 +748,49 @@ mod tests {
|
|||
assert_snapshot!("transcript_overlay_apply_patch_scroll_vt100", snapshot);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_overlay_wraps_long_exec_output_lines() {
|
||||
let marker = "Z";
|
||||
let long_line = marker.repeat(200);
|
||||
|
||||
let mut exec_cell = crate::exec_cell::new_active_exec_command(
|
||||
"exec-long".into(),
|
||||
vec!["bash".into(), "-lc".into(), "echo long".into()],
|
||||
vec![ParsedCommand::Unknown {
|
||||
cmd: "echo long".into(),
|
||||
}],
|
||||
ExecCommandSource::Agent,
|
||||
None,
|
||||
false,
|
||||
);
|
||||
exec_cell.complete_call(
|
||||
"exec-long",
|
||||
CommandOutput {
|
||||
exit_code: 0,
|
||||
aggregated_output: format!("{long_line}\n"),
|
||||
formatted_output: long_line,
|
||||
},
|
||||
Duration::from_millis(10),
|
||||
);
|
||||
let exec_cell: Arc<dyn HistoryCell> = Arc::new(exec_cell);
|
||||
|
||||
let mut overlay = TranscriptOverlay::new(vec![exec_cell]);
|
||||
let area = Rect::new(0, 0, 20, 10);
|
||||
let mut buf = Buffer::empty(area);
|
||||
|
||||
overlay.render(area, &mut buf);
|
||||
let rendered = buffer_to_text(&buf, area);
|
||||
|
||||
let wrapped_lines = rendered
|
||||
.lines()
|
||||
.filter(|line| line.contains(marker))
|
||||
.count();
|
||||
assert!(
|
||||
wrapped_lines >= 2,
|
||||
"expected long exec output to wrap into multiple lines in transcript overlay, got:\n{rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_overlay_keeps_scroll_pinned_at_bottom() {
|
||||
let mut overlay = TranscriptOverlay::new(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue