From fb3ef4bcf6fce862ce10be747fbf7d2d797bfbb7 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 5 May 2023 16:16:29 +0300 Subject: [PATCH] Fix wrapped line detection --- crates/editor/src/element.rs | 65 ++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 48dd33f3e909a65fe27447c08a43d908e7efea3a..326963a0a5ab76127a78c9280690a93b4c5b8c91 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1283,6 +1283,7 @@ impl EditorElement { fn layout_lines( &mut self, rows: Range, + line_number_layouts: &[Option], snapshot: &EditorSnapshot, cx: &ViewContext, ) -> Vec { @@ -1380,6 +1381,7 @@ impl EditorElement { cx.font_cache(), MAX_LINE_LEN, rows.len() as usize, + line_number_layouts, ) } } @@ -1725,6 +1727,7 @@ fn layout_highlighted_chunks<'a>( font_cache: &Arc, max_line_len: usize, max_line_count: usize, + line_number_layouts: &[Option], ) -> Vec { let mut layouts = Vec::with_capacity(max_line_count); let mut line = String::new(); @@ -1786,7 +1789,7 @@ fn layout_highlighted_chunks<'a>( // Line wrap pads its contents with fake whitespaces, // avoid printing them - let inside_wrapped_string = ix > 0; + let inside_wrapped_string = line_number_layouts[row].is_none(); if highlighted_chunk.is_tab { if non_whitespace_added || !inside_wrapped_string { invisibles.push(Invisible::Tab { @@ -2041,7 +2044,8 @@ impl Element for EditorElement { let scrollbar_row_range = scroll_position.y()..(scroll_position.y() + height_in_lines); let mut max_visible_line_width = 0.0; - let line_layouts = self.layout_lines(start_row..end_row, &snapshot, cx); + let line_layouts = + self.layout_lines(start_row..end_row, &line_number_layouts, &snapshot, cx); for line_with_invisibles in &line_layouts { if line_with_invisibles.line.width() > max_visible_line_width { max_visible_line_width = line_with_invisibles.line.width(); @@ -2851,43 +2855,32 @@ mod tests { } #[gpui::test] - fn test_invisible_drawing(cx: &mut TestAppContext) { + fn test_both_invisible_kinds_drawing(cx: &mut TestAppContext) { let tab_size = 4; - let initial_str = "\t\t\t\t\t\t\t\t| | a b c d "; - let (input_text, expected_invisibles) = { - let mut input_text = String::new(); - let mut expected_invisibles = Vec::new(); - let mut offset = 0; - - let mut push_char = |char_symbol| { - input_text.push(char_symbol); - let new_offset = match char_symbol { - '\t' => { - expected_invisibles.push(Invisible::Tab { - line_start_offset: offset, - }); - tab_size as usize - } - ' ' => { - expected_invisibles.push(Invisible::Whitespace { - line_offset: offset, - }); - 1 - } - _ => 1, - }; - offset += new_offset; - }; - - for input_char in initial_str.chars() { - push_char(input_char) - } - - (input_text, expected_invisibles) - }; + let input_text = "\t\t\t| | a b"; + let expected_invisibles = vec![ + Invisible::Tab { + line_start_offset: 0, + }, + Invisible::Tab { + line_start_offset: tab_size as usize, + }, + Invisible::Tab { + line_start_offset: tab_size as usize * 2, + }, + Invisible::Whitespace { + line_offset: tab_size as usize * 3 + 1, + }, + Invisible::Whitespace { + line_offset: tab_size as usize * 3 + 3, + }, + Invisible::Whitespace { + line_offset: tab_size as usize * 3 + 5, + }, + ]; assert_eq!( expected_invisibles.len(), - initial_str + input_text .chars() .filter(|initial_char| initial_char.is_whitespace()) .count()