tui: /diff mode wraps long lines (#4891)

fixes a regression that stopped long lines from being wrapped when
viewing `/diff`.
This commit is contained in:
Jeremy Rose
2025-10-09 14:01:45 -07:00
committed by GitHub
parent 95b41dd7f1
commit 56296cad82
2 changed files with 34 additions and 12 deletions

View File

@@ -26,6 +26,7 @@ use ratatui::widgets::Clear;
use ratatui::widgets::Paragraph; use ratatui::widgets::Paragraph;
use ratatui::widgets::Widget; use ratatui::widgets::Widget;
use ratatui::widgets::WidgetRef; use ratatui::widgets::WidgetRef;
use ratatui::widgets::Wrap;
pub(crate) enum Overlay { pub(crate) enum Overlay {
Transcript(TranscriptOverlay), Transcript(TranscriptOverlay),
@@ -329,9 +330,9 @@ struct CachedRenderable {
} }
impl CachedRenderable { impl CachedRenderable {
fn new(renderable: Box<dyn Renderable>) -> Self { fn new(renderable: impl Into<Box<dyn Renderable>>) -> Self {
Self { Self {
renderable, renderable: renderable.into(),
height: std::cell::Cell::new(None), height: std::cell::Cell::new(None),
last_width: std::cell::Cell::new(None), last_width: std::cell::Cell::new(None),
} }
@@ -400,19 +401,19 @@ impl TranscriptOverlay {
.flat_map(|(i, c)| { .flat_map(|(i, c)| {
let mut v: Vec<Box<dyn Renderable>> = Vec::new(); let mut v: Vec<Box<dyn Renderable>> = Vec::new();
let mut cell_renderable = if c.as_any().is::<UserHistoryCell>() { let mut cell_renderable = if c.as_any().is::<UserHistoryCell>() {
Box::new(CachedRenderable::new(Box::new(CellRenderable { Box::new(CachedRenderable::new(CellRenderable {
cell: c.clone(), cell: c.clone(),
style: if highlight_cell == Some(i) { style: if highlight_cell == Some(i) {
user_message_style().reversed() user_message_style().reversed()
} else { } else {
user_message_style() user_message_style()
}, },
}))) as Box<dyn Renderable> })) as Box<dyn Renderable>
} else { } else {
Box::new(CachedRenderable::new(Box::new(CellRenderable { Box::new(CachedRenderable::new(CellRenderable {
cell: c.clone(), cell: c.clone(),
style: Style::default(), style: Style::default(),
}))) as Box<dyn Renderable> })) as Box<dyn Renderable>
}; };
if !c.is_stream_continuation() && i > 0 { if !c.is_stream_continuation() && i > 0 {
cell_renderable = Box::new(InsetRenderable::new( cell_renderable = Box::new(InsetRenderable::new(
@@ -496,12 +497,8 @@ pub(crate) struct StaticOverlay {
impl StaticOverlay { impl StaticOverlay {
pub(crate) fn with_title(lines: Vec<Line<'static>>, title: String) -> Self { pub(crate) fn with_title(lines: Vec<Line<'static>>, title: String) -> Self {
Self::with_renderables( let paragraph = Paragraph::new(Text::from(lines)).wrap(Wrap { trim: false });
vec![Box::new(CachedRenderable::new(Box::new(Paragraph::new( Self::with_renderables(vec![Box::new(CachedRenderable::new(paragraph))], title)
Text::from(lines),
))))],
title,
)
} }
pub(crate) fn with_renderables(renderables: Vec<Box<dyn Renderable>>, title: String) -> Self { pub(crate) fn with_renderables(renderables: Vec<Box<dyn Renderable>>, title: String) -> Self {
@@ -812,6 +809,18 @@ mod tests {
assert_snapshot!(term.backend()); assert_snapshot!(term.backend());
} }
#[test]
fn static_overlay_wraps_long_lines() {
let mut overlay = StaticOverlay::with_title(
vec!["a very long line that should wrap when rendered within a narrow pager overlay width".into()],
"S T A T I C".to_string(),
);
let mut term = Terminal::new(TestBackend::new(24, 8)).expect("term");
term.draw(|f| overlay.render(f.area(), f.buffer_mut()))
.expect("draw");
assert_snapshot!(term.backend());
}
#[test] #[test]
fn pager_view_content_height_counts_renderables() { fn pager_view_content_height_counts_renderables() {
let pv = PagerView::new( let pv = PagerView::new(

View File

@@ -0,0 +1,13 @@
---
source: tui/src/pager_overlay.rs
assertion_line: 798
expression: term.backend()
---
"/ S T A T I C / / / / / "
"a very long line that "
"should wrap when "
"rendered within a narrow"
"─────────────────── 0% ─"
" ↑/↓ to scroll pgup/pg"
" q to quit "
" "