#![doc = include_str!("../README.md")]
use unicode_segmentation::UnicodeSegmentation;
#[cfg(test)]
mod tests;
pub fn termwrap(s: &str, width: usize, continuation: &str) -> String {
if width == 0 {
return s.to_string();
}
let b = String::from_utf8(strip_ansi_escapes::strip(s.as_bytes())).unwrap();
let mut gb = b.graphemes(true).collect::<Vec<_>>();
let mut ga = s.graphemes(true).collect::<Vec<_>>();
let gc = continuation.graphemes(true).collect::<Vec<_>>();
let cw = gc.len();
let cwp = cw + 1;
let w = width - cw;
let mut r = String::new(); let mut l = 0; let mut ca; let mut cb;
fn update(ca: &str, r: &mut String, l: &mut usize, counts: bool) {
if ca == "\t" {
for _ in 0..(8 - *l % 8) {
*l += 1;
r.push(' ');
}
} else {
if counts {
*l = if ca == "\n" { 0 } else { *l + 1 };
}
r.push_str(ca);
}
}
while !ga.is_empty() {
while l < w {
if ga.is_empty() {
break;
}
ca = ga.remove(0);
cb = gb.remove(0);
while ca != cb && !ga.is_empty() {
update(ca, &mut r, &mut l, false);
ca = ga.remove(0);
}
update(ca, &mut r, &mut l, true);
}
let gal = ga.len();
if gal == cw || (gal == cwp && ga[1] == "\n") {
r.push_str(ga.remove(0));
} else if gal != 0 {
r.push_str(continuation);
r.push('\n');
}
l = 0;
}
r
}