tui: wrapping bugfix (#4674)

this fixes an issue where text lines with long words would sometimes
overflow.

- the default penalties for the OptimalFit algorithm allow overflowing
in some cases. this seems insane to me, and i considered just banning
the OptimalFit algorithm by disabling the 'smawk' feature on textwrap,
but decided to keep it and just bump the overflow penalty to ~infinity
since optimal fit does sometimes produce nicer wrappings. it's not clear
this is worth it, though, and maybe we should just dump the optimal fit
algorithm completely.
- user history messages weren't rendering with the same wrap algorithm
as used in the composer, which sometimes resulted in wrapping messages
differently in the history vs. in the composer.
This commit is contained in:
Jeremy Rose
2025-10-07 11:32:13 -07:00
committed by GitHub
parent 75176dae70
commit 4b0f5eb6a8
2 changed files with 8 additions and 2 deletions

View File

@@ -104,7 +104,8 @@ impl HistoryCell for UserHistoryCell {
.lines()
.map(|l| Line::from(l).style(style))
.collect::<Vec<_>>(),
RtOptions::new(wrap_width as usize),
// Wrap algorithm matches textarea.rs.
RtOptions::new(wrap_width as usize).wrap_algorithm(textwrap::WrapAlgorithm::FirstFit),
);
lines.push(Line::from("").style(style));

View File

@@ -2,6 +2,7 @@ use ratatui::text::Line;
use ratatui::text::Span;
use std::ops::Range;
use textwrap::Options;
use textwrap::wrap_algorithms::Penalties;
use crate::render::line_utils::push_owned_lines;
@@ -90,7 +91,11 @@ impl<'a> RtOptions<'a> {
subsequent_indent: Line::default(),
break_words: true,
word_separator: textwrap::WordSeparator::new(),
wrap_algorithm: textwrap::WrapAlgorithm::new(),
wrap_algorithm: textwrap::WrapAlgorithm::OptimalFit(Penalties {
// ~infinite overflow penalty, we never want to overflow a line.
overflow_penalty: usize::MAX / 4,
..Default::default()
}),
word_splitter: textwrap::WordSplitter::HyphenSplitter,
}
}