From 9c8732a3553163fe9a869a99a24afc7620d9a5e3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 21 Mar 2023 13:44:04 +0100 Subject: [PATCH] Integrate `SuggestionMap` into the rest of `DisplayMap` --- crates/editor/src/display_map.rs | 138 ++++++++++-------- crates/editor/src/display_map/block_map.rs | 61 +++++--- crates/editor/src/display_map/fold_map.rs | 10 -- .../editor/src/display_map/suggestion_map.rs | 59 +++----- crates/editor/src/display_map/tab_map.rs | 134 ++++++++++------- crates/editor/src/display_map/wrap_map.rs | 75 ++++++---- 6 files changed, 259 insertions(+), 218 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 777fa2e9f51566487149c217f7860a646a7639e5..30388291548d5a36d0da946c3abe9d4fe79d3c69 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -16,8 +16,9 @@ use gpui::{ use language::{OffsetUtf16, Point, Subscription as BufferSubscription}; use settings::Settings; use std::{any::TypeId, fmt::Debug, num::NonZeroU32, ops::Range, sync::Arc}; +use suggestion_map::SuggestionMap; use sum_tree::{Bias, TreeMap}; -use tab_map::TabMap; +use tab_map::{TabMap, TabSnapshot}; use wrap_map::WrapMap; pub use block_map::{ @@ -25,8 +26,6 @@ pub use block_map::{ BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock, }; -use self::tab_map::TabSnapshot; - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FoldStatus { Folded, @@ -43,6 +42,7 @@ pub struct DisplayMap { buffer: ModelHandle, buffer_subscription: BufferSubscription, fold_map: FoldMap, + suggestion_map: SuggestionMap, tab_map: TabMap, wrap_map: ModelHandle, block_map: BlockMap, @@ -68,6 +68,7 @@ impl DisplayMap { let tab_size = Self::tab_size(&buffer, cx); let (fold_map, snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx)); + let (suggestion_map, snapshot) = SuggestionMap::new(snapshot); let (tab_map, snapshot) = TabMap::new(snapshot, tab_size); let (wrap_map, snapshot) = WrapMap::new(snapshot, font_id, font_size, wrap_width, cx); let block_map = BlockMap::new(snapshot, buffer_header_height, excerpt_header_height); @@ -76,6 +77,7 @@ impl DisplayMap { buffer, buffer_subscription, fold_map, + suggestion_map, tab_map, wrap_map, block_map, @@ -87,21 +89,25 @@ impl DisplayMap { pub fn snapshot(&self, cx: &mut ModelContext) -> DisplaySnapshot { let buffer_snapshot = self.buffer.read(cx).snapshot(cx); let edits = self.buffer_subscription.consume().into_inner(); - let (folds_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits); + let (fold_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits); + let (suggestion_snapshot, edits) = self.suggestion_map.sync(fold_snapshot.clone(), edits); let tab_size = Self::tab_size(&self.buffer, cx); - let (tabs_snapshot, edits) = self.tab_map.sync(folds_snapshot.clone(), edits, tab_size); - let (wraps_snapshot, edits) = self + let (tab_snapshot, edits) = self + .tab_map + .sync(suggestion_snapshot.clone(), edits, tab_size); + let (wrap_snapshot, edits) = self .wrap_map - .update(cx, |map, cx| map.sync(tabs_snapshot.clone(), edits, cx)); - let blocks_snapshot = self.block_map.read(wraps_snapshot.clone(), edits); + .update(cx, |map, cx| map.sync(tab_snapshot.clone(), edits, cx)); + let block_snapshot = self.block_map.read(wrap_snapshot.clone(), edits); DisplaySnapshot { buffer_snapshot: self.buffer.read(cx).snapshot(cx), - folds_snapshot, - tabs_snapshot, - wraps_snapshot, - blocks_snapshot, + fold_snapshot, + suggestion_snapshot, + tab_snapshot, + wrap_snapshot, + block_snapshot, text_highlights: self.text_highlights.clone(), clip_at_line_ends: self.clip_at_line_ends, } @@ -125,12 +131,14 @@ impl DisplayMap { let edits = self.buffer_subscription.consume().into_inner(); let tab_size = Self::tab_size(&self.buffer, cx); let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map .update(cx, |map, cx| map.sync(snapshot, edits, cx)); self.block_map.read(snapshot, edits); let (snapshot, edits) = fold_map.fold(ranges); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map @@ -148,12 +156,14 @@ impl DisplayMap { let edits = self.buffer_subscription.consume().into_inner(); let tab_size = Self::tab_size(&self.buffer, cx); let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map .update(cx, |map, cx| map.sync(snapshot, edits, cx)); self.block_map.read(snapshot, edits); let (snapshot, edits) = fold_map.unfold(ranges, inclusive); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map @@ -170,6 +180,7 @@ impl DisplayMap { let edits = self.buffer_subscription.consume().into_inner(); let tab_size = Self::tab_size(&self.buffer, cx); let (snapshot, edits) = self.fold_map.read(snapshot, edits); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map @@ -187,6 +198,7 @@ impl DisplayMap { let edits = self.buffer_subscription.consume().into_inner(); let tab_size = Self::tab_size(&self.buffer, cx); let (snapshot, edits) = self.fold_map.read(snapshot, edits); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); let (snapshot, edits) = self .wrap_map @@ -249,10 +261,11 @@ impl DisplayMap { pub struct DisplaySnapshot { pub buffer_snapshot: MultiBufferSnapshot, - folds_snapshot: fold_map::FoldSnapshot, - tabs_snapshot: tab_map::TabSnapshot, - wraps_snapshot: wrap_map::WrapSnapshot, - blocks_snapshot: block_map::BlockSnapshot, + fold_snapshot: fold_map::FoldSnapshot, + suggestion_snapshot: suggestion_map::SuggestionSnapshot, + tab_snapshot: tab_map::TabSnapshot, + wrap_snapshot: wrap_map::WrapSnapshot, + block_snapshot: block_map::BlockSnapshot, text_highlights: TextHighlights, clip_at_line_ends: bool, } @@ -260,7 +273,7 @@ pub struct DisplaySnapshot { impl DisplaySnapshot { #[cfg(test)] pub fn fold_count(&self) -> usize { - self.folds_snapshot.fold_count() + self.fold_snapshot.fold_count() } pub fn is_empty(&self) -> bool { @@ -268,7 +281,7 @@ impl DisplaySnapshot { } pub fn buffer_rows(&self, start_row: u32) -> DisplayBufferRows { - self.blocks_snapshot.buffer_rows(start_row) + self.block_snapshot.buffer_rows(start_row) } pub fn max_buffer_row(&self) -> u32 { @@ -277,9 +290,9 @@ impl DisplaySnapshot { pub fn prev_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) { loop { - let mut fold_point = self.folds_snapshot.to_fold_point(point, Bias::Left); + let mut fold_point = self.fold_snapshot.to_fold_point(point, Bias::Left); *fold_point.column_mut() = 0; - point = fold_point.to_buffer_point(&self.folds_snapshot); + point = fold_point.to_buffer_point(&self.fold_snapshot); let mut display_point = self.point_to_display_point(point, Bias::Left); *display_point.column_mut() = 0; @@ -293,9 +306,9 @@ impl DisplaySnapshot { pub fn next_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) { loop { - let mut fold_point = self.folds_snapshot.to_fold_point(point, Bias::Right); - *fold_point.column_mut() = self.folds_snapshot.line_len(fold_point.row()); - point = fold_point.to_buffer_point(&self.folds_snapshot); + let mut fold_point = self.fold_snapshot.to_fold_point(point, Bias::Right); + *fold_point.column_mut() = self.fold_snapshot.line_len(fold_point.row()); + point = fold_point.to_buffer_point(&self.fold_snapshot); let mut display_point = self.point_to_display_point(point, Bias::Right); *display_point.column_mut() = self.line_len(display_point.row()); @@ -325,28 +338,30 @@ impl DisplaySnapshot { } fn point_to_display_point(&self, point: Point, bias: Bias) -> DisplayPoint { - let fold_point = self.folds_snapshot.to_fold_point(point, bias); - let tab_point = self.tabs_snapshot.to_tab_point(fold_point); - let wrap_point = self.wraps_snapshot.tab_point_to_wrap_point(tab_point); - let block_point = self.blocks_snapshot.to_block_point(wrap_point); + let fold_point = self.fold_snapshot.to_fold_point(point, bias); + let suggestion_point = self.suggestion_snapshot.to_suggestion_point(fold_point); + let tab_point = self.tab_snapshot.to_tab_point(suggestion_point); + let wrap_point = self.wrap_snapshot.tab_point_to_wrap_point(tab_point); + let block_point = self.block_snapshot.to_block_point(wrap_point); DisplayPoint(block_point) } fn display_point_to_point(&self, point: DisplayPoint, bias: Bias) -> Point { let block_point = point.0; - let wrap_point = self.blocks_snapshot.to_wrap_point(block_point); - let tab_point = self.wraps_snapshot.to_tab_point(wrap_point); - let fold_point = self.tabs_snapshot.to_fold_point(tab_point, bias).0; - fold_point.to_buffer_point(&self.folds_snapshot) + let wrap_point = self.block_snapshot.to_wrap_point(block_point); + let tab_point = self.wrap_snapshot.to_tab_point(wrap_point); + let suggestion_point = self.tab_snapshot.to_suggestion_point(tab_point, bias).0; + let fold_point = self.suggestion_snapshot.to_fold_point(suggestion_point); + fold_point.to_buffer_point(&self.fold_snapshot) } pub fn max_point(&self) -> DisplayPoint { - DisplayPoint(self.blocks_snapshot.max_point()) + DisplayPoint(self.block_snapshot.max_point()) } /// Returns text chunks starting at the given display row until the end of the file pub fn text_chunks(&self, display_row: u32) -> impl Iterator { - self.blocks_snapshot + self.block_snapshot .chunks(display_row..self.max_point().row() + 1, false, None) .map(|h| h.text) } @@ -354,7 +369,7 @@ impl DisplaySnapshot { /// Returns text chunks starting at the end of the given display row in reverse until the start of the file pub fn reverse_text_chunks(&self, display_row: u32) -> impl Iterator { (0..=display_row).into_iter().rev().flat_map(|row| { - self.blocks_snapshot + self.block_snapshot .chunks(row..row + 1, false, None) .map(|h| h.text) .collect::>() @@ -364,7 +379,7 @@ impl DisplaySnapshot { } pub fn chunks(&self, display_rows: Range, language_aware: bool) -> DisplayChunks<'_> { - self.blocks_snapshot + self.block_snapshot .chunks(display_rows, language_aware, Some(&self.text_highlights)) } @@ -372,7 +387,7 @@ impl DisplaySnapshot { &self, mut point: DisplayPoint, ) -> impl Iterator + '_ { - point = DisplayPoint(self.blocks_snapshot.clip_point(point.0, Bias::Left)); + point = DisplayPoint(self.block_snapshot.clip_point(point.0, Bias::Left)); self.text_chunks(point.row()) .flat_map(str::chars) .skip_while({ @@ -399,7 +414,7 @@ impl DisplaySnapshot { &self, mut point: DisplayPoint, ) -> impl Iterator + '_ { - point = DisplayPoint(self.blocks_snapshot.clip_point(point.0, Bias::Left)); + point = DisplayPoint(self.block_snapshot.clip_point(point.0, Bias::Left)); self.reverse_text_chunks(point.row()) .flat_map(|chunk| chunk.chars().rev()) .skip_while({ @@ -513,7 +528,7 @@ impl DisplaySnapshot { } pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint { - let mut clipped = self.blocks_snapshot.clip_point(point.0, bias); + let mut clipped = self.block_snapshot.clip_point(point.0, bias); if self.clip_at_line_ends { clipped = self.clip_at_line_end(DisplayPoint(clipped)).0 } @@ -524,7 +539,7 @@ impl DisplaySnapshot { let mut point = point.0; if point.column == self.line_len(point.row) { point.column = point.column.saturating_sub(1); - point = self.blocks_snapshot.clip_point(point, Bias::Left); + point = self.block_snapshot.clip_point(point, Bias::Left); } DisplayPoint(point) } @@ -533,34 +548,34 @@ impl DisplaySnapshot { where T: ToOffset, { - self.folds_snapshot.folds_in_range(range) + self.fold_snapshot.folds_in_range(range) } pub fn blocks_in_range( &self, rows: Range, ) -> impl Iterator { - self.blocks_snapshot.blocks_in_range(rows) + self.block_snapshot.blocks_in_range(rows) } pub fn intersects_fold(&self, offset: T) -> bool { - self.folds_snapshot.intersects_fold(offset) + self.fold_snapshot.intersects_fold(offset) } pub fn is_line_folded(&self, buffer_row: u32) -> bool { - self.folds_snapshot.is_line_folded(buffer_row) + self.fold_snapshot.is_line_folded(buffer_row) } pub fn is_block_line(&self, display_row: u32) -> bool { - self.blocks_snapshot.is_block_line(display_row) + self.block_snapshot.is_block_line(display_row) } pub fn soft_wrap_indent(&self, display_row: u32) -> Option { let wrap_row = self - .blocks_snapshot + .block_snapshot .to_wrap_point(BlockPoint::new(display_row, 0)) .row(); - self.wraps_snapshot.soft_wrap_indent(wrap_row) + self.wrap_snapshot.soft_wrap_indent(wrap_row) } pub fn text(&self) -> String { @@ -614,18 +629,18 @@ impl DisplaySnapshot { } }), buffer.line_len(buffer_row) as usize, // Never collapse - self.tabs_snapshot.tab_size, + self.tab_snapshot.tab_size, ); (indent_size as u32, is_blank) } pub fn line_len(&self, row: u32) -> u32 { - self.blocks_snapshot.line_len(row) + self.block_snapshot.line_len(row) } pub fn longest_row(&self) -> u32 { - self.blocks_snapshot.longest_row() + self.block_snapshot.longest_row() } pub fn fold_for_line(self: &Self, buffer_row: u32) -> Option { @@ -742,10 +757,11 @@ impl DisplayPoint { } pub fn to_offset(self, map: &DisplaySnapshot, bias: Bias) -> usize { - let unblocked_point = map.blocks_snapshot.to_wrap_point(self.0); - let unwrapped_point = map.wraps_snapshot.to_tab_point(unblocked_point); - let unexpanded_point = map.tabs_snapshot.to_fold_point(unwrapped_point, bias).0; - unexpanded_point.to_buffer_offset(&map.folds_snapshot) + let wrap_point = map.block_snapshot.to_wrap_point(self.0); + let tab_point = map.wrap_snapshot.to_tab_point(wrap_point); + let suggestion_point = map.tab_snapshot.to_suggestion_point(tab_point, bias).0; + let fold_point = map.suggestion_snapshot.to_fold_point(suggestion_point); + fold_point.to_buffer_offset(&map.fold_snapshot) } } @@ -868,10 +884,10 @@ pub mod tests { let snapshot = map.update(cx, |map, cx| map.snapshot(cx)); log::info!("buffer text: {:?}", snapshot.buffer_snapshot.text()); - log::info!("fold text: {:?}", snapshot.folds_snapshot.text()); - log::info!("tab text: {:?}", snapshot.tabs_snapshot.text()); - log::info!("wrap text: {:?}", snapshot.wraps_snapshot.text()); - log::info!("block text: {:?}", snapshot.blocks_snapshot.text()); + log::info!("fold text: {:?}", snapshot.fold_snapshot.text()); + log::info!("tab text: {:?}", snapshot.tab_snapshot.text()); + log::info!("wrap text: {:?}", snapshot.wrap_snapshot.text()); + log::info!("block text: {:?}", snapshot.block_snapshot.text()); log::info!("display text: {:?}", snapshot.text()); for _i in 0..operations { @@ -976,10 +992,10 @@ pub mod tests { let snapshot = map.update(cx, |map, cx| map.snapshot(cx)); fold_count = snapshot.fold_count(); log::info!("buffer text: {:?}", snapshot.buffer_snapshot.text()); - log::info!("fold text: {:?}", snapshot.folds_snapshot.text()); - log::info!("tab text: {:?}", snapshot.tabs_snapshot.text()); - log::info!("wrap text: {:?}", snapshot.wraps_snapshot.text()); - log::info!("block text: {:?}", snapshot.blocks_snapshot.text()); + log::info!("fold text: {:?}", snapshot.fold_snapshot.text()); + log::info!("tab text: {:?}", snapshot.tab_snapshot.text()); + log::info!("wrap text: {:?}", snapshot.wrap_snapshot.text()); + log::info!("block text: {:?}", snapshot.block_snapshot.text()); log::info!("display text: {:?}", snapshot.text()); // Line boundaries diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index fffe20bb219970028b6aa8ef08b2fe677a8b1c1e..adea668179555db73e28cb99a45396a350aedf0d 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -989,6 +989,7 @@ fn offset_for_row(s: &str, target: u32) -> (u32, usize) { #[cfg(test)] mod tests { use super::*; + use crate::display_map::suggestion_map::SuggestionMap; use crate::display_map::{fold_map::FoldMap, tab_map::TabMap, wrap_map::WrapMap}; use crate::multi_buffer::MultiBuffer; use gpui::{elements::Empty, Element}; @@ -1029,9 +1030,10 @@ mod tests { let buffer = MultiBuffer::build_simple(text, cx); let buffer_snapshot = buffer.read(cx).snapshot(cx); let subscription = buffer.update(cx, |buffer, _| buffer.subscribe()); - let (fold_map, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot, 1.try_into().unwrap()); - let (wrap_map, wraps_snapshot) = WrapMap::new(tabs_snapshot, font_id, 14.0, None, cx); + let (fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone()); + let (suggestion_map, suggestion_snapshot) = SuggestionMap::new(fold_snapshot); + let (tab_map, tab_snapshot) = TabMap::new(suggestion_snapshot, 1.try_into().unwrap()); + let (wrap_map, wraps_snapshot) = WrapMap::new(tab_snapshot, font_id, 14.0, None, cx); let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1); let mut writer = block_map.write(wraps_snapshot.clone(), Default::default()); @@ -1173,12 +1175,14 @@ mod tests { buffer.snapshot(cx) }); - let (folds_snapshot, fold_edits) = + let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot, subscription.consume().into_inner()); - let (tabs_snapshot, tab_edits) = - tab_map.sync(folds_snapshot, fold_edits, 4.try_into().unwrap()); + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); + let (tab_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, 4.try_into().unwrap()); let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| { - wrap_map.sync(tabs_snapshot, tab_edits, cx) + wrap_map.sync(tab_snapshot, tab_edits, cx) }); let snapshot = block_map.read(wraps_snapshot, wrap_edits); assert_eq!(snapshot.text(), "aaa\n\nb!!!\n\n\nbb\nccc\nddd\n\n\n"); @@ -1201,9 +1205,10 @@ mod tests { let buffer = MultiBuffer::build_simple(text, cx); let buffer_snapshot = buffer.read(cx).snapshot(cx); - let (_, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (_, tabs_snapshot) = TabMap::new(folds_snapshot, 1.try_into().unwrap()); - let (_, wraps_snapshot) = WrapMap::new(tabs_snapshot, font_id, 14.0, Some(60.), cx); + let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone()); + let (_, suggestion_snapshot) = SuggestionMap::new(fold_snapshot); + let (_, tab_snapshot) = TabMap::new(suggestion_snapshot, 1.try_into().unwrap()); + let (_, wraps_snapshot) = WrapMap::new(tab_snapshot, font_id, 14.0, Some(60.), cx); let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1); let mut writer = block_map.write(wraps_snapshot.clone(), Default::default()); @@ -1272,10 +1277,11 @@ mod tests { }; let mut buffer_snapshot = buffer.read(cx).snapshot(cx); - let (fold_map, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot, tab_size); + let (fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone()); + let (suggestion_map, suggestion_snapshot) = SuggestionMap::new(fold_snapshot); + let (tab_map, tab_snapshot) = TabMap::new(suggestion_snapshot, tab_size); let (wrap_map, wraps_snapshot) = - WrapMap::new(tabs_snapshot, font_id, font_size, wrap_width, cx); + WrapMap::new(tab_snapshot, font_id, font_size, wrap_width, cx); let mut block_map = BlockMap::new( wraps_snapshot, buffer_start_header_height, @@ -1326,12 +1332,14 @@ mod tests { }) .collect::>(); - let (folds_snapshot, fold_edits) = + let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), vec![]); - let (tabs_snapshot, tab_edits) = - tab_map.sync(folds_snapshot, fold_edits, tab_size); + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); + let (tab_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| { - wrap_map.sync(tabs_snapshot, tab_edits, cx) + wrap_map.sync(tab_snapshot, tab_edits, cx) }); let mut block_map = block_map.write(wraps_snapshot, wrap_edits); let block_ids = block_map.insert(block_properties.clone()); @@ -1349,12 +1357,14 @@ mod tests { }) .collect(); - let (folds_snapshot, fold_edits) = + let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), vec![]); - let (tabs_snapshot, tab_edits) = - tab_map.sync(folds_snapshot, fold_edits, tab_size); + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); + let (tab_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| { - wrap_map.sync(tabs_snapshot, tab_edits, cx) + wrap_map.sync(tab_snapshot, tab_edits, cx) }); let mut block_map = block_map.write(wraps_snapshot, wrap_edits); block_map.remove(block_ids_to_remove); @@ -1371,10 +1381,13 @@ mod tests { } } - let (folds_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits); - let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits, tab_size); + let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits); + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); + let (tab_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| { - wrap_map.sync(tabs_snapshot, tab_edits, cx) + wrap_map.sync(tab_snapshot, tab_edits, cx) }); let blocks_snapshot = block_map.read(wraps_snapshot.clone(), wrap_edits); assert_eq!( diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index 4e624c824ce2b3cbe66720313419ddade6f010da..fa1de81e0da042827002c9638232926afb79ca03 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -29,10 +29,6 @@ impl FoldPoint { self.0.row } - pub fn column(self) -> u32 { - self.0.column - } - pub fn row_mut(&mut self) -> &mut u32 { &mut self.0.row } @@ -655,12 +651,6 @@ impl FoldSnapshot { false } - pub fn chars_at(&self, start: FoldPoint) -> impl '_ + Iterator { - let start = start.to_offset(self); - self.chunks(start..self.len(), false, None) - .flat_map(|chunk| chunk.text.chars()) - } - pub fn chunks<'a>( &'a self, range: Range, diff --git a/crates/editor/src/display_map/suggestion_map.rs b/crates/editor/src/display_map/suggestion_map.rs index 499a9fa35483048730f9d01dcdc14a7e05fc56a9..3e8014724850bccf3c17553a12838a574cf59446 100644 --- a/crates/editor/src/display_map/suggestion_map.rs +++ b/crates/editor/src/display_map/suggestion_map.rs @@ -43,6 +43,10 @@ impl AddAssign for SuggestionOffset { pub struct SuggestionPoint(pub Point); impl SuggestionPoint { + pub fn new(row: u32, column: u32) -> Self { + Self(Point::new(row, column)) + } + pub fn row(self) -> u32 { self.0.row } @@ -173,8 +177,8 @@ impl SuggestionMap { #[derive(Clone)] pub struct SuggestionSnapshot { - fold_snapshot: FoldSnapshot, - suggestion: Option>, + pub fold_snapshot: FoldSnapshot, + pub suggestion: Option>, pub version: usize, } @@ -320,32 +324,6 @@ impl SuggestionSnapshot { } } - pub fn line_len(&self, row: u32) -> u32 { - if let Some(suggestion) = self.suggestion.as_ref() { - let suggestion_lines = suggestion.text.max_point(); - let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0; - let suggestion_end = suggestion_start + suggestion_lines; - - if row < suggestion_start.row { - self.fold_snapshot.line_len(row) - } else if row > suggestion_end.row { - self.fold_snapshot.line_len(row - suggestion_lines.row) - } else { - let mut len = suggestion.text.line_len(row - suggestion_start.row); - if row == suggestion_start.row { - len += suggestion_start.column; - } - if row == suggestion_end.row { - len += - self.fold_snapshot.line_len(suggestion_start.row) - suggestion_start.column; - } - len - } - } else { - self.fold_snapshot.line_len(row) - } - } - pub fn text_summary_for_range(&self, range: Range) -> TextSummary { if let Some(suggestion) = self.suggestion.as_ref() { let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0; @@ -400,7 +378,7 @@ impl SuggestionSnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - ) -> Chunks<'a> { + ) -> SuggestionChunks<'a> { if let Some(suggestion) = self.suggestion.as_ref() { let suggestion_range = suggestion.position.0..suggestion.position.0 + suggestion.text.len(); @@ -439,14 +417,14 @@ impl SuggestionSnapshot { None }; - Chunks { + SuggestionChunks { prefix_chunks, suggestion_chunks, suffix_chunks, highlight_style: suggestion.highlight_style, } } else { - Chunks { + SuggestionChunks { prefix_chunks: Some(self.fold_snapshot.chunks( FoldOffset(range.start.0)..FoldOffset(range.end.0), language_aware, @@ -495,14 +473,14 @@ impl SuggestionSnapshot { } } -pub struct Chunks<'a> { +pub struct SuggestionChunks<'a> { prefix_chunks: Option>, suggestion_chunks: Option>, suffix_chunks: Option>, highlight_style: HighlightStyle, } -impl<'a> Iterator for Chunks<'a> { +impl<'a> Iterator for SuggestionChunks<'a> { type Item = Chunk<'a>; fn next(&mut self) -> Option { @@ -540,6 +518,7 @@ impl<'a> Iterator for Chunks<'a> { } } +#[derive(Clone)] pub struct SuggestionBufferRows<'a> { current_row: u32, suggestion_row_start: u32, @@ -741,14 +720,6 @@ mod tests { assert_eq!(expected_text.max_point(), suggestion_snapshot.max_point().0); assert_eq!(expected_text.len(), suggestion_snapshot.len().0); - for row in 0..=suggestion_snapshot.max_point().row() { - assert_eq!( - suggestion_snapshot.line_len(row), - expected_text.line_len(row), - "incorrect line len for row {}", - row - ); - } let mut suggestion_point = SuggestionPoint::default(); let mut suggestion_offset = SuggestionOffset::default(); @@ -827,7 +798,10 @@ mod tests { } impl SuggestionMap { - fn randomly_mutate(&self, rng: &mut impl Rng) -> (SuggestionSnapshot, Vec) { + pub fn randomly_mutate( + &self, + rng: &mut impl Rng, + ) -> (SuggestionSnapshot, Vec) { let fold_snapshot = self.0.lock().fold_snapshot.clone(); let new_suggestion = if rng.gen_bool(0.3) { None @@ -838,6 +812,7 @@ mod tests { position: index, text: util::RandomCharIter::new(rng) .take(len) + .filter(|ch| *ch != '\r') .collect::() .as_str() .into(), diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 5a5aae6135055e3d54041ae07c2774439f51fa80..45c92ea7b84ec0809213a6dc80238030d4bd1d79 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -1,5 +1,5 @@ use super::{ - fold_map::{self, FoldEdit, FoldPoint, FoldSnapshot}, + suggestion_map::{self, SuggestionChunks, SuggestionEdit, SuggestionPoint, SuggestionSnapshot}, TextHighlights, }; use crate::MultiBufferSnapshot; @@ -11,9 +11,9 @@ use sum_tree::Bias; pub struct TabMap(Mutex); impl TabMap { - pub fn new(input: FoldSnapshot, tab_size: NonZeroU32) -> (Self, TabSnapshot) { + pub fn new(input: SuggestionSnapshot, tab_size: NonZeroU32) -> (Self, TabSnapshot) { let snapshot = TabSnapshot { - fold_snapshot: input, + suggestion_snapshot: input, tab_size, version: 0, }; @@ -22,37 +22,37 @@ impl TabMap { pub fn sync( &self, - fold_snapshot: FoldSnapshot, - mut fold_edits: Vec, + suggestion_snapshot: SuggestionSnapshot, + mut suggestion_edits: Vec, tab_size: NonZeroU32, ) -> (TabSnapshot, Vec) { let mut old_snapshot = self.0.lock(); let mut new_snapshot = TabSnapshot { - fold_snapshot, + suggestion_snapshot, tab_size, version: old_snapshot.version, }; - if old_snapshot.fold_snapshot.version != new_snapshot.fold_snapshot.version { + if old_snapshot.suggestion_snapshot.version != new_snapshot.suggestion_snapshot.version { new_snapshot.version += 1; } - let old_max_offset = old_snapshot.fold_snapshot.len(); - let mut tab_edits = Vec::with_capacity(fold_edits.len()); + let old_max_offset = old_snapshot.suggestion_snapshot.len(); + let mut tab_edits = Vec::with_capacity(suggestion_edits.len()); if old_snapshot.tab_size == new_snapshot.tab_size { - for fold_edit in &mut fold_edits { + for suggestion_edit in &mut suggestion_edits { let mut delta = 0; - for chunk in old_snapshot.fold_snapshot.chunks( - fold_edit.old.end..old_max_offset, + for chunk in old_snapshot.suggestion_snapshot.chunks( + suggestion_edit.old.end..old_max_offset, false, None, ) { let patterns: &[_] = &['\t', '\n']; if let Some(ix) = chunk.text.find(patterns) { if &chunk.text[ix..ix + 1] == "\t" { - fold_edit.old.end.0 += delta + ix + 1; - fold_edit.new.end.0 += delta + ix + 1; + suggestion_edit.old.end.0 += delta + ix + 1; + suggestion_edit.new.end.0 += delta + ix + 1; } break; @@ -63,24 +63,32 @@ impl TabMap { } let mut ix = 1; - while ix < fold_edits.len() { - let (prev_edits, next_edits) = fold_edits.split_at_mut(ix); + while ix < suggestion_edits.len() { + let (prev_edits, next_edits) = suggestion_edits.split_at_mut(ix); let prev_edit = prev_edits.last_mut().unwrap(); let edit = &next_edits[0]; if prev_edit.old.end >= edit.old.start { prev_edit.old.end = edit.old.end; prev_edit.new.end = edit.new.end; - fold_edits.remove(ix); + suggestion_edits.remove(ix); } else { ix += 1; } } - for fold_edit in fold_edits { - let old_start = fold_edit.old.start.to_point(&old_snapshot.fold_snapshot); - let old_end = fold_edit.old.end.to_point(&old_snapshot.fold_snapshot); - let new_start = fold_edit.new.start.to_point(&new_snapshot.fold_snapshot); - let new_end = fold_edit.new.end.to_point(&new_snapshot.fold_snapshot); + for suggestion_edit in suggestion_edits { + let old_start = old_snapshot + .suggestion_snapshot + .to_point(suggestion_edit.old.start); + let old_end = old_snapshot + .suggestion_snapshot + .to_point(suggestion_edit.old.end); + let new_start = new_snapshot + .suggestion_snapshot + .to_point(suggestion_edit.new.start); + let new_end = new_snapshot + .suggestion_snapshot + .to_point(suggestion_edit.new.end); tab_edits.push(TabEdit { old: old_snapshot.to_tab_point(old_start)..old_snapshot.to_tab_point(old_end), new: new_snapshot.to_tab_point(new_start)..new_snapshot.to_tab_point(new_end), @@ -101,14 +109,14 @@ impl TabMap { #[derive(Clone)] pub struct TabSnapshot { - pub fold_snapshot: FoldSnapshot, + pub suggestion_snapshot: SuggestionSnapshot, pub tab_size: NonZeroU32, pub version: usize, } impl TabSnapshot { pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot { - self.fold_snapshot.buffer_snapshot() + self.suggestion_snapshot.buffer_snapshot() } pub fn line_len(&self, row: u32) -> u32 { @@ -132,10 +140,10 @@ impl TabSnapshot { } pub fn text_summary_for_range(&self, range: Range) -> TextSummary { - let input_start = self.to_fold_point(range.start, Bias::Left).0; - let input_end = self.to_fold_point(range.end, Bias::Right).0; + let input_start = self.to_suggestion_point(range.start, Bias::Left).0; + let input_end = self.to_suggestion_point(range.end, Bias::Right).0; let input_summary = self - .fold_snapshot + .suggestion_snapshot .text_summary_for_range(input_start..input_end); let mut first_line_chars = 0; @@ -182,12 +190,11 @@ impl TabSnapshot { text_highlights: Option<&'a TextHighlights>, ) -> TabChunks<'a> { let (input_start, expanded_char_column, to_next_stop) = - self.to_fold_point(range.start, Bias::Left); - let input_start = input_start.to_offset(&self.fold_snapshot); + self.to_suggestion_point(range.start, Bias::Left); + let input_start = self.suggestion_snapshot.to_offset(input_start); let input_end = self - .to_fold_point(range.end, Bias::Right) - .0 - .to_offset(&self.fold_snapshot); + .suggestion_snapshot + .to_offset(self.to_suggestion_point(range.end, Bias::Right).0); let to_next_stop = if range.start.0 + Point::new(0, to_next_stop as u32) > range.end.0 { (range.end.column() - range.start.column()) as usize } else { @@ -195,7 +202,7 @@ impl TabSnapshot { }; TabChunks { - fold_chunks: self.fold_snapshot.chunks( + suggestion_chunks: self.suggestion_snapshot.chunks( input_start..input_end, language_aware, text_highlights, @@ -212,8 +219,8 @@ impl TabSnapshot { } } - pub fn buffer_rows(&self, row: u32) -> fold_map::FoldBufferRows { - self.fold_snapshot.buffer_rows(row) + pub fn buffer_rows(&self, row: u32) -> suggestion_map::SuggestionBufferRows { + self.suggestion_snapshot.buffer_rows(row) } #[cfg(test)] @@ -224,42 +231,55 @@ impl TabSnapshot { } pub fn max_point(&self) -> TabPoint { - self.to_tab_point(self.fold_snapshot.max_point()) + self.to_tab_point(self.suggestion_snapshot.max_point()) } pub fn clip_point(&self, point: TabPoint, bias: Bias) -> TabPoint { self.to_tab_point( - self.fold_snapshot - .clip_point(self.to_fold_point(point, bias).0, bias), + self.suggestion_snapshot + .clip_point(self.to_suggestion_point(point, bias).0, bias), ) } - pub fn to_tab_point(&self, input: FoldPoint) -> TabPoint { - let chars = self.fold_snapshot.chars_at(FoldPoint::new(input.row(), 0)); + pub fn to_tab_point(&self, input: SuggestionPoint) -> TabPoint { + let chars = self + .suggestion_snapshot + .chars_at(SuggestionPoint::new(input.row(), 0)); let expanded = Self::expand_tabs(chars, input.column() as usize, self.tab_size); TabPoint::new(input.row(), expanded as u32) } - pub fn to_fold_point(&self, output: TabPoint, bias: Bias) -> (FoldPoint, usize, usize) { - let chars = self.fold_snapshot.chars_at(FoldPoint::new(output.row(), 0)); + pub fn to_suggestion_point( + &self, + output: TabPoint, + bias: Bias, + ) -> (SuggestionPoint, usize, usize) { + let chars = self + .suggestion_snapshot + .chars_at(SuggestionPoint::new(output.row(), 0)); let expanded = output.column() as usize; let (collapsed, expanded_char_column, to_next_stop) = Self::collapse_tabs(chars, expanded, bias, self.tab_size); ( - FoldPoint::new(output.row(), collapsed as u32), + SuggestionPoint::new(output.row(), collapsed as u32), expanded_char_column, to_next_stop, ) } pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint { - self.to_tab_point(self.fold_snapshot.to_fold_point(point, bias)) + let fold_point = self + .suggestion_snapshot + .fold_snapshot + .to_fold_point(point, bias); + let suggestion_point = self.suggestion_snapshot.to_suggestion_point(fold_point); + self.to_tab_point(suggestion_point) } pub fn to_point(&self, point: TabPoint, bias: Bias) -> Point { - self.to_fold_point(point, bias) - .0 - .to_buffer_point(&self.fold_snapshot) + let suggestion_point = self.to_suggestion_point(point, bias).0; + let fold_point = self.suggestion_snapshot.to_fold_point(suggestion_point); + fold_point.to_buffer_point(&self.suggestion_snapshot.fold_snapshot) } pub fn expand_tabs( @@ -412,7 +432,7 @@ impl<'a> std::ops::AddAssign<&'a Self> for TextSummary { const SPACES: &str = " "; pub struct TabChunks<'a> { - fold_chunks: fold_map::FoldChunks<'a>, + suggestion_chunks: SuggestionChunks<'a>, chunk: Chunk<'a>, column: usize, output_position: Point, @@ -426,7 +446,7 @@ impl<'a> Iterator for TabChunks<'a> { fn next(&mut self) -> Option { if self.chunk.text.is_empty() { - if let Some(chunk) = self.fold_chunks.next() { + if let Some(chunk) = self.suggestion_chunks.next() { self.chunk = chunk; if self.skip_leading_tab { self.chunk.text = &self.chunk.text[1..]; @@ -482,7 +502,10 @@ impl<'a> Iterator for TabChunks<'a> { #[cfg(test)] mod tests { use super::*; - use crate::{display_map::fold_map::FoldMap, MultiBuffer}; + use crate::{ + display_map::{fold_map::FoldMap, suggestion_map::SuggestionMap}, + MultiBuffer, + }; use rand::{prelude::StdRng, Rng}; #[test] @@ -518,10 +541,13 @@ mod tests { let (mut fold_map, _) = FoldMap::new(buffer_snapshot.clone()); fold_map.randomly_mutate(&mut rng); - let (folds_snapshot, _) = fold_map.read(buffer_snapshot, vec![]); - log::info!("FoldMap text: {:?}", folds_snapshot.text()); + let (fold_snapshot, _) = fold_map.read(buffer_snapshot, vec![]); + log::info!("FoldMap text: {:?}", fold_snapshot.text()); + let (suggestion_map, _) = SuggestionMap::new(fold_snapshot); + let (suggestion_snapshot, _) = suggestion_map.randomly_mutate(&mut rng); + log::info!("SuggestionMap text: {:?}", suggestion_snapshot.text()); - let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); + let (_, tabs_snapshot) = TabMap::new(suggestion_snapshot.clone(), tab_size); let text = text::Rope::from(tabs_snapshot.text().as_str()); log::info!( "TabMap text (tab size: {}): {:?}", @@ -557,7 +583,7 @@ mod tests { ); let mut actual_summary = tabs_snapshot.text_summary_for_range(start..end); - if tab_size.get() > 1 && folds_snapshot.text().contains('\t') { + if tab_size.get() > 1 && suggestion_snapshot.text().contains('\t') { actual_summary.longest_row = expected_summary.longest_row; actual_summary.longest_row_chars = expected_summary.longest_row_chars; } diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index 0d5fb878e583a0269d33b8742e8c18733d19a8fb..f0d10ad42339eb37a7e6ae292ee675c4990e8ad8 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -1,5 +1,5 @@ use super::{ - fold_map, + suggestion_map::SuggestionBufferRows, tab_map::{self, TabEdit, TabPoint, TabSnapshot}, TextHighlights, }; @@ -64,7 +64,7 @@ pub struct WrapChunks<'a> { #[derive(Clone)] pub struct WrapBufferRows<'a> { - input_buffer_rows: fold_map::FoldBufferRows<'a>, + input_buffer_rows: SuggestionBufferRows<'a>, input_buffer_row: Option, output_row: u32, soft_wrapped: bool, @@ -755,16 +755,24 @@ impl WrapSnapshot { let text = language::Rope::from(self.text().as_str()); let input_buffer_rows = self.buffer_snapshot().buffer_rows(0).collect::>(); let mut expected_buffer_rows = Vec::new(); - let mut prev_tab_row = 0; + let mut prev_fold_row = 0; for display_row in 0..=self.max_point().row() { let tab_point = self.to_tab_point(WrapPoint::new(display_row, 0)); - if tab_point.row() == prev_tab_row && display_row != 0 { + let suggestion_point = self + .tab_snapshot + .to_suggestion_point(tab_point, Bias::Left) + .0; + let fold_point = self + .tab_snapshot + .suggestion_snapshot + .to_fold_point(suggestion_point); + if fold_point.row() == prev_fold_row && display_row != 0 { expected_buffer_rows.push(None); } else { - let fold_point = self.tab_snapshot.to_fold_point(tab_point, Bias::Left).0; - let buffer_point = fold_point.to_buffer_point(&self.tab_snapshot.fold_snapshot); + let buffer_point = fold_point + .to_buffer_point(&self.tab_snapshot.suggestion_snapshot.fold_snapshot); expected_buffer_rows.push(input_buffer_rows[buffer_point.row as usize]); - prev_tab_row = tab_point.row(); + prev_fold_row = fold_point.row(); } assert_eq!(self.line_len(display_row), text.line_len(display_row)); @@ -1026,7 +1034,7 @@ fn consolidate_wrap_edits(edits: &mut Vec) { mod tests { use super::*; use crate::{ - display_map::{fold_map::FoldMap, tab_map::TabMap}, + display_map::{fold_map::FoldMap, suggestion_map::SuggestionMap, tab_map::TabMap}, MultiBuffer, }; use gpui::test::observe; @@ -1076,14 +1084,13 @@ mod tests { } }); let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); - let (mut fold_map, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); - log::info!("Unwrapped text (no folds): {:?}", buffer_snapshot.text()); - log::info!( - "Unwrapped text (unexpanded tabs): {:?}", - folds_snapshot.text() - ); - log::info!("Unwrapped text (expanded tabs): {:?}", tabs_snapshot.text()); + log::info!("Buffer text: {:?}", buffer_snapshot.text()); + let (mut fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone()); + log::info!("FoldMap text: {:?}", fold_snapshot.text()); + let (suggestion_map, suggestion_snapshot) = SuggestionMap::new(fold_snapshot.clone()); + log::info!("SuggestionMap text: {:?}", suggestion_snapshot.text()); + let (tab_map, tabs_snapshot) = TabMap::new(suggestion_snapshot.clone(), tab_size); + log::info!("TabMap text: {:?}", tabs_snapshot.text()); let mut line_wrapper = LineWrapper::new(font_id, font_size, font_system); let unwrapped_text = tabs_snapshot.text(); @@ -1126,9 +1133,11 @@ mod tests { wrap_map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx)); } 20..=39 => { - for (folds_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) { + for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) { + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); let (tabs_snapshot, tab_edits) = - tab_map.sync(folds_snapshot, fold_edits, tab_size); + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); let (mut snapshot, wrap_edits) = wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); snapshot.check_invariants(); @@ -1136,6 +1145,17 @@ mod tests { edits.push((snapshot, wrap_edits)); } } + 40..=59 => { + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.randomly_mutate(&mut rng); + let (tabs_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); + let (mut snapshot, wrap_edits) = + wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx)); + snapshot.check_invariants(); + snapshot.verify_chunks(&mut rng); + edits.push((snapshot, wrap_edits)); + } _ => { buffer.update(cx, |buffer, cx| { let subscription = buffer.subscribe(); @@ -1147,14 +1167,15 @@ mod tests { } } - log::info!("Unwrapped text (no folds): {:?}", buffer_snapshot.text()); - let (folds_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits); - log::info!( - "Unwrapped text (unexpanded tabs): {:?}", - folds_snapshot.text() - ); - let (tabs_snapshot, tab_edits) = tab_map.sync(folds_snapshot, fold_edits, tab_size); - log::info!("Unwrapped text (expanded tabs): {:?}", tabs_snapshot.text()); + log::info!("Buffer text: {:?}", buffer_snapshot.text()); + let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits); + log::info!("FoldMap text: {:?}", fold_snapshot.text()); + let (suggestion_snapshot, suggestion_edits) = + suggestion_map.sync(fold_snapshot, fold_edits); + log::info!("SuggestionMap text: {:?}", suggestion_snapshot.text()); + let (tabs_snapshot, tab_edits) = + tab_map.sync(suggestion_snapshot, suggestion_edits, tab_size); + log::info!("TabMap text: {:?}", tabs_snapshot.text()); let unwrapped_text = tabs_snapshot.text(); let expected_text = wrap_text(&unwrapped_text, wrap_width, &mut line_wrapper); @@ -1201,7 +1222,7 @@ mod tests { if tab_size.get() == 1 || !wrapped_snapshot .tab_snapshot - .fold_snapshot + .suggestion_snapshot .text() .contains('\t') {