diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index c8be2379c2..93e43f876c 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -833,10 +833,7 @@ impl<'a> Iterator for BlockChunks<'a> { return Some(Chunk { text: unsafe { std::str::from_utf8_unchecked(&NEWLINES[..line_count as usize]) }, - syntax_highlight_id: None, - highlight_style: None, - diagnostic_severity: None, - is_unnecessary: false, + ..Default::default() }); } diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index b8802e3c90..bd3cd1a620 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -1065,13 +1065,11 @@ impl<'a> Iterator for FoldChunks<'a> { self.output_offset += output_text.len(); return Some(Chunk { text: output_text, - syntax_highlight_id: None, highlight_style: self.ellipses_color.map(|color| HighlightStyle { color: Some(color), ..Default::default() }), - diagnostic_severity: None, - is_unnecessary: false, + ..Default::default() }); } diff --git a/crates/editor/src/display_map/suggestion_map.rs b/crates/editor/src/display_map/suggestion_map.rs index 7be377a69b..f48efc76f4 100644 --- a/crates/editor/src/display_map/suggestion_map.rs +++ b/crates/editor/src/display_map/suggestion_map.rs @@ -531,10 +531,8 @@ impl<'a> Iterator for SuggestionChunks<'a> { if let Some(chunk) = chunks.next() { return Some(Chunk { text: chunk, - syntax_highlight_id: None, highlight_style: self.highlight_style, - diagnostic_severity: None, - is_unnecessary: false, + ..Default::default() }); } else { self.suggestion_chunks = None; diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 2932994670..d97ba4f40b 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -268,6 +268,7 @@ impl TabSnapshot { tab_size: self.tab_size, chunk: Chunk { text: &SPACES[0..(to_next_stop as usize)], + is_tab: true, ..Default::default() }, inside_leading_tab: to_next_stop > 0, @@ -545,6 +546,7 @@ impl<'a> Iterator for TabChunks<'a> { self.output_position = next_output_position; return Some(Chunk { text: &SPACES[..len as usize], + is_tab: true, ..self.chunk }); } @@ -654,6 +656,56 @@ mod tests { assert_eq!(tab_snapshot.text(), input); } + #[gpui::test] + fn test_marking_tabs(cx: &mut gpui::AppContext) { + let input = "\t \thello"; + + let buffer = MultiBuffer::build_simple(&input, cx); + let buffer_snapshot = buffer.read(cx).snapshot(cx); + let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone()); + let (_, suggestion_snapshot) = SuggestionMap::new(fold_snapshot); + let (_, tab_snapshot) = TabMap::new(suggestion_snapshot, 4.try_into().unwrap()); + + assert_eq!( + chunks(&tab_snapshot, TabPoint::zero()), + vec![ + (" ".to_string(), true), + (" ".to_string(), false), + (" ".to_string(), true), + ("hello".to_string(), false), + ] + ); + assert_eq!( + chunks(&tab_snapshot, TabPoint::new(0, 2)), + vec![ + (" ".to_string(), true), + (" ".to_string(), false), + (" ".to_string(), true), + ("hello".to_string(), false), + ] + ); + + fn chunks(snapshot: &TabSnapshot, start: TabPoint) -> Vec<(String, bool)> { + let mut chunks = Vec::new(); + let mut was_tab = false; + let mut text = String::new(); + for chunk in snapshot.chunks(start..snapshot.max_point(), false, None, None) { + if chunk.is_tab != was_tab { + if !text.is_empty() { + chunks.push((mem::take(&mut text), was_tab)); + } + was_tab = chunk.is_tab; + } + text.push_str(chunk.text); + } + + if !text.is_empty() { + chunks.push((text, was_tab)); + } + chunks + } + } + #[gpui::test(iterations = 100)] fn test_random_tabs(cx: &mut gpui::AppContext, mut rng: StdRng) { let tab_size = NonZeroU32::new(rng.gen_range(1..=4)).unwrap(); diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 039012a95f..43766192eb 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -311,6 +311,7 @@ pub struct Chunk<'a> { pub highlight_style: Option, pub diagnostic_severity: Option, pub is_unnecessary: bool, + pub is_tab: bool, } pub struct Diff { @@ -2840,9 +2841,9 @@ impl<'a> Iterator for BufferChunks<'a> { Some(Chunk { text: slice, syntax_highlight_id: highlight_id, - highlight_style: None, diagnostic_severity: self.current_diagnostic_severity(), is_unnecessary: self.current_code_is_unnecessary(), + ..Default::default() }) } else { None