Skip to content

Commit 5678213

Browse files
authored
fix(tui2): render copy pill at viewport bottom (#8716)
When the selection ends on the last visible row, the copy affordance had no space below and never rendered. Fall back to placing it above (or on the same row for 1-row viewports) and add a regression test.
1 parent 279283f commit 5678213

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

codex-rs/tui2/src/transcript_copy_ui.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,16 @@ impl TranscriptCopyUi {
249249
let Some((y, to_x)) = last_visible_segment else {
250250
return;
251251
};
252-
// Place the pill on the row below the last visible selection segment.
253-
let Some(y) = y.checked_add(1).filter(|y| *y < area.bottom()) else {
252+
// Prefer placing the pill on the row below the last visible selection segment. If the
253+
// selection ends on the last visible row, fall back to placing it above (or, if the view
254+
// is only one row tall, on the same row).
255+
let Some(y) = y
256+
.checked_add(1)
257+
.filter(|y| *y < area.bottom())
258+
.or_else(|| y.checked_sub(1).filter(|y| *y >= area.y))
259+
.or(Some(y))
260+
.filter(|y| *y < area.bottom())
261+
else {
254262
return;
255263
};
256264

@@ -329,4 +337,26 @@ mod tests {
329337
assert!(!rendered.contains("ctrl + shift + c"));
330338
assert!(ui.affordance_rect.is_some());
331339
}
340+
341+
#[test]
342+
fn pill_renders_when_selection_on_last_row() {
343+
let area = Rect::new(0, 0, 60, 3);
344+
let mut buf = Buffer::empty(area);
345+
for y in 0..area.height {
346+
for x in 2..area.width.saturating_sub(1) {
347+
buf[(x, y)].set_symbol("X");
348+
}
349+
}
350+
351+
let mut ui = TranscriptCopyUi::new_with_shortcut(CopySelectionShortcut::CtrlShiftC);
352+
ui.render_copy_pill(area, &mut buf, (2, 2), (2, 6), 0, 3);
353+
354+
let rendered = buf_to_string(&buf, area);
355+
assert!(rendered.contains("copy"));
356+
assert!(rendered.contains("ctrl + shift + c"));
357+
358+
let rect = ui.affordance_rect.expect("expected pill to render");
359+
assert_eq!(rect.y, 1);
360+
assert!(ui.hit_test(rect.x, rect.y));
361+
}
332362
}

0 commit comments

Comments
 (0)