tui: reserve 1 cell right margin for composer and user history (#5026)

keep a 1 cell margin at the right edge of the screen in the composer
(and in the user message in history).

this lets us print clear-to-EOL 1 char before the end of the line in
history, so that resizing the terminal will keep the background color
(at least in iterm/terminal.app). it also stops the cursor in the
textarea from floating off the right edge.

---------

Co-authored-by: joshka-oai <joshka@openai.com>
This commit is contained in:
Jeremy Rose
2025-10-14 11:02:11 -07:00
committed by GitHub
parent f7b4e29609
commit 9be704a934
5 changed files with 17 additions and 9 deletions

View File

@@ -165,8 +165,9 @@ impl ChatComposer {
.unwrap_or_else(|| footer_height(footer_props));
let footer_spacing = Self::footer_spacing(footer_hint_height);
let footer_total_height = footer_hint_height + footer_spacing;
const COLS_WITH_MARGIN: u16 = LIVE_PREFIX_COLS + 1;
self.textarea
.desired_height(width.saturating_sub(LIVE_PREFIX_COLS))
.desired_height(width.saturating_sub(COLS_WITH_MARGIN))
+ 2
+ match &self.active_popup {
ActivePopup::None => footer_total_height,
@@ -197,7 +198,9 @@ impl ChatComposer {
let [composer_rect, popup_rect] =
Layout::vertical([Constraint::Min(1), popup_constraint]).areas(area);
let mut textarea_rect = composer_rect;
textarea_rect.width = textarea_rect.width.saturating_sub(LIVE_PREFIX_COLS);
textarea_rect.width = textarea_rect.width.saturating_sub(
LIVE_PREFIX_COLS + 1, /* keep a one-column right margin for wrapping */
);
textarea_rect.x = textarea_rect.x.saturating_add(LIVE_PREFIX_COLS);
[composer_rect, textarea_rect, popup_rect]
}

View File

@@ -2,4 +2,4 @@
source: tui/src/bottom_pane/mod.rs
expression: "render_snapshot(&pane, area1)"
---
Ask Codex to do an
Ask Codex to do a

View File

@@ -3,4 +3,4 @@ source: tui/src/bottom_pane/mod.rs
expression: "render_snapshot(&pane, area2)"
---
Ask Codex to do an
Ask Codex to do a

View File

@@ -114,7 +114,11 @@ impl HistoryCell for UserHistoryCell {
fn display_lines(&self, width: u16) -> Vec<Line<'static>> {
let mut lines: Vec<Line<'static>> = Vec::new();
let wrap_width = width.saturating_sub(LIVE_PREFIX_COLS);
let wrap_width = width
.saturating_sub(
LIVE_PREFIX_COLS + 1, /* keep a one-column right margin for wrapping */
)
.max(1);
let style = user_message_style();
@@ -125,7 +129,8 @@ impl HistoryCell for UserHistoryCell {
.map(|l| Line::from(l).style(style))
.collect::<Vec<_>>(),
// Wrap algorithm matches textarea.rs.
RtOptions::new(wrap_width as usize).wrap_algorithm(textwrap::WrapAlgorithm::FirstFit),
RtOptions::new(usize::from(wrap_width))
.wrap_algorithm(textwrap::WrapAlgorithm::FirstFit),
);
lines.push(Line::from("").style(style));

View File

@@ -3,6 +3,6 @@ source: tui/src/history_cell.rs
expression: rendered
---
one two
three four
five six
seven
three
four five
six seven