Avoid redundant terminal size queries during history insertion (#39100)

## What changed

- Pass the screen size already available to TUI draw and history-tail paths into history insertion.
- Use the terminal's cached screen size for direct history insertion calls instead of querying the backend again.
- Extend the terminal size-query regression test to cover history insertion.

GitOrigin-RevId: 44c7a0f0bc5bc365d8d0c72d7e26587ed17a4821
This commit is contained in:
Tamir Duberstein
2026-08-17 22:51:09 +00:00
committed by copyberry
parent fd34ad7297
commit 050aa077b5
5 changed files with 21 additions and 2 deletions

View File

@@ -1011,6 +1011,12 @@ mod tests {
terminal.draw_with_size(screen_size, |_| {}).expect("draw");
}
terminal.set_viewport_area(Rect::new(
/*x*/ 0, /*y*/ 23, /*width*/ 80, /*height*/ 1,
));
crate::insert_history::insert_history_lines(&mut terminal, vec![Line::from("history")])
.expect("insert history");
assert_eq!(terminal.backend().size_call_count.get(), 1);
}

View File

@@ -94,11 +94,13 @@ pub(crate) fn insert_history_lines_with_mode_and_wrap_policy<B>(
where
B: Backend<Error = io::Error> + Write,
{
let screen_size = terminal.last_known_screen_size;
insert_history_hyperlink_lines_with_mode_and_wrap_policy(
terminal,
&plain_hyperlink_lines(lines.iter().map(line_to_static).collect()),
mode,
wrap_policy,
screen_size,
)
}
@@ -107,12 +109,11 @@ pub(crate) fn insert_history_hyperlink_lines_with_mode_and_wrap_policy<B>(
lines: &[HyperlinkLine],
mode: InsertHistoryMode,
wrap_policy: HistoryLineWrapPolicy,
screen_size: Size,
) -> io::Result<()>
where
B: Backend<Error = io::Error> + Write,
{
let screen_size = terminal.backend().size().unwrap_or(Size::new(0, 0));
let mut area = terminal.viewport_area;
let mut should_update_area = false;
let last_cursor_pos = terminal.last_known_cursor_pos;
@@ -832,11 +833,13 @@ mod tests {
.map(|line| line.style(ratatui::style::Style::default().bg(Color::Blue)))
.collect::<Vec<_>>();
let screen_size = term.last_known_screen_size;
insert_history_hyperlink_lines_with_mode_and_wrap_policy(
&mut term,
&lines,
InsertHistoryMode::Standard,
HistoryLineWrapPolicy::PreWrap,
screen_size,
)
.expect("insert wrapped user message");

View File

@@ -932,6 +932,7 @@ impl Tui {
terminal: &mut Terminal,
pending_history_lines: &mut Vec<PendingHistoryLines>,
is_zellij: bool,
screen_size: Size,
) -> Result<()> {
if pending_history_lines.is_empty() {
return Ok(());
@@ -948,6 +949,7 @@ impl Tui {
&batch.lines,
mode,
batch.wrap_policy,
screen_size,
)?;
}
pending_history_lines.clear();
@@ -1006,6 +1008,7 @@ impl Tui {
terminal,
&mut self.pending_history_lines,
self.is_zellij,
screen_size,
)?;
// Update the y position for suspending so Ctrl-Z can place the cursor correctly.
@@ -1121,6 +1124,7 @@ impl Tui {
terminal,
&mut self.pending_history_lines,
self.is_zellij,
screen_size,
)?;
if needs_full_repaint || history_can_overlap_viewport {

View File

@@ -27,10 +27,12 @@ impl Tui {
replacement: &[HyperlinkLine],
wrap_policy: HistoryLineWrapPolicy,
) -> io::Result<bool> {
let screen_size = self.terminal.last_known_screen_size;
Self::flush_pending_history_lines(
&mut self.terminal,
&mut self.pending_history_lines,
self.is_zellij,
screen_size,
)?;
let mode = if self.is_zellij && wrap_policy == HistoryLineWrapPolicy::Terminal {
InsertHistoryMode::ZellijRaw
@@ -61,6 +63,7 @@ fn replace_visible_terminal_history_tail<B>(
where
B: Backend<Error = io::Error> + Write,
{
let screen_size = terminal.last_known_screen_size;
let mut viewport = terminal.viewport_area;
let wrap_width = usize::from(viewport.width.max(/*other*/ 1));
let (_, previous_rows) = wrap_history_hyperlink_lines(previous_lines, wrap_width, wrap_policy);
@@ -80,6 +83,7 @@ where
replacement,
mode,
wrap_policy,
screen_size,
)?;
Ok(true)
}

View File

@@ -118,11 +118,13 @@ fn replacing_soft_wrapped_history_counts_physical_terminal_rows() {
/*height*/ 2,
));
let previous_lines = plain_hyperlink_lines(vec![Line::from("old-long-line-spanning-two-rows")]);
let screen_size = terminal.last_known_screen_size;
crate::insert_history::insert_history_hyperlink_lines_with_mode_and_wrap_policy(
&mut terminal,
&previous_lines,
InsertHistoryMode::Standard,
HistoryLineWrapPolicy::Terminal,
screen_size,
)
.expect("insert soft-wrapped history");
let replacement = plain_hyperlink_lines(vec![Line::from("new billing")]);