diff --git a/ui/src/terminal/cells.rs b/ui/src/terminal/cells.rs index 588517049..f62e2cd7f 100644 --- a/ui/src/terminal/cells.rs +++ b/ui/src/terminal/cells.rs @@ -575,7 +575,7 @@ pub fn copy_area_with_break( ) -> Pos { if !is_valid_area!(dest) || !is_valid_area!(src) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!( + eprintln!( "BUG: Invalid areas in copy_area:\n src: {:?}\n dest: {:?}", src, dest ); @@ -623,7 +623,7 @@ eprintln!( pub fn copy_area(grid_dest: &mut CellBuffer, grid_src: &CellBuffer, dest: Area, src: Area) -> Pos { if !is_valid_area!(dest) || !is_valid_area!(src) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!( + eprintln!( "BUG: Invalid areas in copy_area:\n src: {:?}\n dest: {:?}", src, dest ); @@ -641,7 +641,7 @@ eprintln!( if src_x >= cols || src_y >= rows { if cfg!(debug_assertions) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!("DEBUG: src area outside of grid_src in copy_area",); + eprintln!("DEBUG: src area outside of grid_src in copy_area",); } return upper_left!(dest); } @@ -681,14 +681,14 @@ pub fn change_colors(grid: &mut CellBuffer, area: Area, fg_color: Color, bg_colo { if cfg!(debug_assertions) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area); + eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area); } return; } if !is_valid_area!(area) { if cfg!(debug_assertions) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area); + eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area); } return; } @@ -741,7 +741,7 @@ pub fn write_string_to_grid( { if cfg!(debug_assertions) { eprint!("{}:{}_{}: ", file!(), line!(), column!()); -eprintln!(" Invalid area with string {} and area {:?}", s, area); + eprintln!(" Invalid area with string {} and area {:?}", s, area); } return (x, y); } @@ -770,45 +770,6 @@ eprintln!(" Invalid area with string {} and area {:?}", s, area); (x, y) } -pub fn word_break_string(mut s: &str, width: usize) -> Vec<&str> { - let mut ret: Vec<&str> = Vec::with_capacity(16); - loop { - if s.is_empty() { - break; - } - s = s.trim_start_matches(|c| c == ' '); - if s.starts_with('\n') { - ret.push(&s[0..0]); - s = &s["\n".len()..]; - continue; - } - if let Some(next_idx) = s.as_bytes().iter().position(|&c| c == b'\n') { - if next_idx <= width { - ret.push(&s[..next_idx]); - s = &s[next_idx + 1..]; - continue; - } - } - let graphemes = s.graphemes_indices(); - if graphemes.len() > width { - // use grapheme indices and find position of " " graphemes - if let Some(next_idx) = graphemes[..width].iter().rposition(|(_, g)| *g == " ") { - let next_idx = graphemes[next_idx].0; - ret.push(&s[..next_idx]); - s = &s[next_idx + 1..]; - } else { - ret.push(&s[..width]); - s = &s[width..]; - } - } else { - ret.push(s); - break; - } - } - - ret -} - /// Completely clear an `Area` with an empty char and the terminal's default colors. pub fn clear_area(grid: &mut CellBuffer, area: Area) { if !is_valid_area!(area) { diff --git a/ui/src/terminal/grapheme_clusters.rs b/ui/src/terminal/grapheme_clusters.rs index 69303e198..2a2b92c5a 100644 --- a/ui/src/terminal/grapheme_clusters.rs +++ b/ui/src/terminal/grapheme_clusters.rs @@ -39,6 +39,58 @@ pub trait Graphemes: UnicodeSegmentation + CodePointsIter { impl Graphemes for str {} +pub struct WordBreakIter<'s> { + input: &'s str, + width: usize, +} +impl<'s> Iterator for WordBreakIter<'s> { + type Item = &'s str; + + fn next(&mut self) -> Option<&'s str> { + if self.input.is_empty() { + return None; + } + self.input = self.input.trim_start_matches(|c| c == ' '); + if self.input.starts_with('\n') { + let ret = &self.input[0..]; + self.input = &self.input["\n".len()..]; + return Some(ret); + } + if let Some(next_idx) = self.input.as_bytes().iter().position(|&c| c == b'\n') { + if next_idx <= self.width { + let ret = &self.input[..next_idx]; + self.input = &self.input[next_idx + 1..]; + return Some(ret); + } + } + let graphemes = UnicodeSegmentation::grapheme_indices(self.input, true) + .take(self.width) + .collect::>(); + if graphemes.len() == self.width { + // use grapheme indices and find position of " " graphemes + if let Some(next_idx) = graphemes.iter().rposition(|(_, g)| *g == " ") { + let next_idx = graphemes[next_idx].0; + let ret = &self.input[..next_idx]; + self.input = &self.input[next_idx + 1..]; + return Some(&self.input[..next_idx]); + } else { + let ret = &self.input[..self.width]; + self.input = &self.input[self.width..]; + return Some(ret); + } + } else { + let ret = self.input; + self.input = &self.input[self.input.len() - 1..]; + return Some(ret); + } + } +} + +pub fn word_break_string(mut s: &str, width: usize) -> Vec<&str> { + let iter = WordBreakIter { input: s, width }; + iter.collect() +} + //#[derive(PartialEq)] //enum Property { // CR,