Skip to main content

grapheme_clusters/
grapheme_clusters.rs

1use txtview::{TxtView, TxtViewConfig};
2
3fn main() -> std::io::Result<()> {
4    // Fixed 20-column viewport so wrapping always happens at the same place,
5    // independent of the terminal size.
6    let doc = vec![
7        "Grapheme cluster wrapping demo".to_string(),
8        "".to_string(),
9        "Every cluster wraps as one unit, never split at a row boundary:".to_string(),
10        "".to_string(),
11        "skin-tone modifier: 123456789012345678👍🏿xyz".to_string(),
12        "ZWJ family emoji:   123456789012345678👨\u{200d}👩\u{200d}👧x".to_string(),
13        "flag pair:          1234567890123456789🇺🇸x".to_string(),
14        "".to_string(),
15        "combining marks stay with their base char:".to_string(),
16        "  na\u{303}i\u{303}ve cafe\u{301} re\u{301}sume\u{301}".to_string(),
17        "".to_string(),
18        "keycap and variation-selector sequences:".to_string(),
19        "  \u{23}\u{fe0f}\u{20e3} \u{31}\u{fe0f}\u{20e3} vs plain 3 and a ❤\u{fe0f} heart"
20            .to_string(),
21        "".to_string(),
22        "All of these stay intact even when a row boundary".to_string(),
23        "lands in the middle of one.".to_string(),
24    ];
25
26    let text = doc.join("\n");
27
28    let config = TxtViewConfig {
29        viewport_width: Some(20),
30        show_line_numbers: false,
31        show_scrollbar: false,
32        ..TxtViewConfig::default()
33    };
34
35    let mut viewer = TxtView::new(&text).with_config(config);
36    viewer.run()
37}