diff --git a/zed/src/editor/display_map/line_wrapper.rs b/zed/src/editor/display_map/line_wrapper.rs index 79c69b5d1303d17d06905fd57a90288d2ffdf9d4..ca43e1a2b67fbe7cf316033d9b570df1a5fa317f 100644 --- a/zed/src/editor/display_map/line_wrapper.rs +++ b/zed/src/editor/display_map/line_wrapper.rs @@ -36,37 +36,42 @@ impl LineWrapper { .wrap_line(line, self.font_id, self.font_size, wrap_width) } - pub fn wrap_line(&self, line: &str, wrap_width: f32) -> Vec { + pub fn wrap_line<'a>( + &'a self, + line: &'a str, + wrap_width: f32, + ) -> impl Iterator + 'a { let mut width = 0.0; - let mut boundaries = Vec::new(); - let mut last_boundary_ix = 0; - let mut last_boundary_width = 0.0; + let mut last_candidate_ix = 0; + let mut last_candidate_width = 0.0; + let mut last_wrap_ix = 0; let mut prev_c = '\0'; - for (ix, c) in line.char_indices() { - if c == '\n' { - break; - } - - if self.is_boundary(prev_c, c) { - last_boundary_ix = ix; - last_boundary_width = width; - } + let char_indices = line.char_indices(); + char_indices.filter_map(move |(ix, c)| { + if c != '\n' { + if self.is_boundary(prev_c, c) { + last_candidate_ix = ix; + last_candidate_width = width; + } - let char_width = self.width_for_char(c); - width += char_width; - if width > wrap_width && ix > *boundaries.last().unwrap_or(&0) { - if last_boundary_ix > 0 { - boundaries.push(last_boundary_ix); - width -= last_boundary_width; - last_boundary_ix = 0; - } else { - boundaries.push(ix); - width = char_width; + let char_width = self.width_for_char(c); + width += char_width; + if width > wrap_width && ix > last_wrap_ix { + if last_candidate_ix > 0 { + last_wrap_ix = last_candidate_ix; + width -= last_candidate_width; + last_candidate_ix = 0; + } else { + last_wrap_ix = ix; + width = char_width; + } + return Some(last_wrap_ix); } + prev_c = c; } - prev_c = c; - } - boundaries + + None + }) } fn is_boundary(&self, prev: char, next: char) -> bool { @@ -132,7 +137,9 @@ mod tests { &[7, 12, 18], ); assert_eq!( - wrapper.wrap_line("aa bbb cccc ddddd eeee", 72.0), + wrapper + .wrap_line("aa bbb cccc ddddd eeee", 72.0) + .collect::>(), &[7, 12, 18], ); @@ -141,7 +148,9 @@ mod tests { &[4, 11, 18], ); assert_eq!( - wrapper.wrap_line("aaa aaaaaaaaaaaaaaaaaa", 72.0), + wrapper + .wrap_line("aaa aaaaaaaaaaaaaaaaaa", 72.0) + .collect::>(), &[4, 11, 18], ); }