Skip to content

Commit c21e3f6

Browse files
committed
Use ratatui's line_count for exact wrapped-row count
v0.1.1's max_scroll used ceil(display_width / width) per Line to estimate wrapped rows, but ratatui's WordWrapper can exceed that ceiling: with trim: false, a short trailing word forces the next word to the next row while leaving whitespace on the previous row, producing more rows than a naive division. Concrete case: "one two three four five six seven eight" at W=10 word-wraps to 5 rows, but ceil(39/10) = 4. Our estimate was one row short — exactly the bug the user saw after v0.1.1. Defer to ratatui by enabling its unstable-rendered-line-info feature and calling Paragraph::line_count(width), which runs the same WordWrapper the renderer uses. Counts are authoritative. Add a regression test that captures the word-boundary case ratatui exceeds the ceiling on; correct the previous "hello world" at W=4 assertion to the 4 rows ratatui actually produces.
1 parent 52811c6 commit c21e3f6

3 files changed

Lines changed: 16 additions & 17 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mdview"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
edition = "2024"
55
description = "A terminal markdown viewer"
66
license = "MIT"
@@ -13,6 +13,6 @@ ansi-to-tui = "7"
1313
crossterm = { version = "0.28", features = ["event-stream"] }
1414
notify = "7"
1515
pulldown-cmark = { version = "0.12", default-features = false, features = ["simd"] }
16-
ratatui = "0.29"
16+
ratatui = { version = "0.29", features = ["unstable-rendered-line-info"] }
1717
syntect = { version = "5", default-features = false, features = ["default-syntaxes", "default-themes", "regex-fancy"] }
1818
unicode-width = "0.2"

src/scroll.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use ratatui::text::Text;
2-
use unicode_width::UnicodeWidthStr;
2+
use ratatui::widgets::{Paragraph, Wrap};
33

44
pub struct App {
55
pub text: Text<'static>,
@@ -12,18 +12,9 @@ pub fn wrapped_row_count(text: &Text<'_>, width: u16) -> u32 {
1212
if width == 0 {
1313
return text.lines.len() as u32;
1414
}
15-
let w = width as u32;
16-
text.lines
17-
.iter()
18-
.map(|line| {
19-
let display: u32 = line
20-
.spans
21-
.iter()
22-
.map(|s| UnicodeWidthStr::width(s.content.as_ref()) as u32)
23-
.sum();
24-
if display == 0 { 1 } else { display.div_ceil(w) }
25-
})
26-
.sum()
15+
Paragraph::new(text.clone())
16+
.wrap(Wrap { trim: false })
17+
.line_count(width) as u32
2718
}
2819

2920
impl App {
@@ -95,7 +86,15 @@ mod tests {
9586
Span::raw("hello "),
9687
Span::raw("world"),
9788
])]);
98-
assert_eq!(wrapped_row_count(&text, 4), 3);
89+
assert_eq!(wrapped_row_count(&text, 4), 4);
90+
}
91+
92+
#[test]
93+
fn wrapped_row_count_exceeds_naive_ceiling_for_word_boundaries() {
94+
let text = Text::from(vec![Line::from(Span::raw(
95+
"one two three four five six seven eight",
96+
))]);
97+
assert_eq!(wrapped_row_count(&text, 10), 5);
9998
}
10099

101100
#[test]

0 commit comments

Comments
 (0)