diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 9b12df60d9d1d3c6a67c6f302ab97847ed6c5ae6..93a4c372ec72e32ab1ffa68b14277dc8dfe98109 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -589,7 +589,7 @@ pub mod tests { .unwrap_or(10); let font_cache = cx.font_cache().clone(); - let tab_size = rng.gen_range(1..=4); + let mut tab_size = rng.gen_range(1..=4); let buffer_start_excerpt_header_height = rng.gen_range(1..=5); let excerpt_header_height = rng.gen_range(1..=5); let family_id = font_cache.load_family(&["Helvetica"]).unwrap(); @@ -607,7 +607,11 @@ pub mod tests { log::info!("tab size: {}", tab_size); log::info!("wrap width: {:?}", wrap_width); - cx.update(|cx| cx.set_global(Settings::test(cx))); + cx.update(|cx| { + let mut settings = Settings::test(cx); + settings.editor_overrides.tab_size = NonZeroU32::new(tab_size); + cx.set_global(settings) + }); let buffer = cx.update(|cx| { if rng.gen() { @@ -653,7 +657,18 @@ pub mod tests { log::info!("setting wrap width to {:?}", wrap_width); map.update(cx, |map, cx| map.set_wrap_width(wrap_width, cx)); } - 20..=44 => { + 20..=29 => { + let mut tab_sizes = vec![1, 2, 3, 4]; + tab_sizes.remove((tab_size - 1) as usize); + tab_size = *tab_sizes.choose(&mut rng).unwrap(); + log::info!("setting tab size to {:?}", tab_size); + cx.update(|cx| { + let mut settings = Settings::test(cx); + settings.editor_overrides.tab_size = NonZeroU32::new(tab_size); + cx.set_global(settings) + }); + } + 30..=44 => { map.update(cx, |map, cx| { if rng.gen() || blocks.is_empty() { let buffer = map.snapshot(cx).buffer_snapshot; diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 3ea3f63a575284b7168e564ef42856aa0a5a547c..4f718a91398816fd62de8e49be06a48c1c5724c5 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -16,6 +16,7 @@ impl TabMap { let snapshot = TabSnapshot { fold_snapshot: input, tab_size, + version: 0, }; (Self(Mutex::new(snapshot.clone())), snapshot) } @@ -27,56 +28,70 @@ impl TabMap { tab_size: NonZeroU32, ) -> (TabSnapshot, Vec) { let mut old_snapshot = self.0.lock(); - let max_offset = old_snapshot.fold_snapshot.len(); - let new_snapshot = TabSnapshot { + let mut new_snapshot = TabSnapshot { fold_snapshot, tab_size, + version: old_snapshot.version, }; + if old_snapshot.fold_snapshot.version != new_snapshot.fold_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()); - for fold_edit in &mut fold_edits { - let mut delta = 0; - for chunk in - old_snapshot - .fold_snapshot - .chunks(fold_edit.old.end..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; + + if old_snapshot.tab_size == new_snapshot.tab_size { + for fold_edit in &mut fold_edits { + let mut delta = 0; + for chunk in old_snapshot.fold_snapshot.chunks( + fold_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; + } + + break; } - break; + delta += chunk.text.len(); } - - delta += chunk.text.len(); } - } - let mut ix = 1; - while ix < fold_edits.len() { - let (prev_edits, next_edits) = fold_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); - } else { - ix += 1; + let mut ix = 1; + while ix < fold_edits.len() { + let (prev_edits, next_edits) = fold_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); + } 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 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); + 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), + }); + } + } else { + new_snapshot.version += 1; 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), + old: TabPoint::zero()..old_snapshot.max_point(), + new: TabPoint::zero()..new_snapshot.max_point(), }); } @@ -89,6 +104,7 @@ impl TabMap { pub struct TabSnapshot { pub fold_snapshot: FoldSnapshot, pub tab_size: NonZeroU32, + pub version: usize, } impl TabSnapshot { @@ -160,10 +176,6 @@ impl TabSnapshot { } } - pub fn version(&self) -> usize { - self.fold_snapshot.version - } - pub fn chunks<'a>( &'a self, range: Range, diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index 9584d1c14db55dc29f5cae7b32f77f47dcf9f94d..aa90f942dbfd8a71aec6591c76e9d59506d820ec 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -220,7 +220,7 @@ impl WrapMap { if !self.snapshot.interpolated { let mut to_remove_len = 0; for (tab_snapshot, _) in &self.pending_edits { - if tab_snapshot.version() <= self.snapshot.tab_snapshot.version() { + if tab_snapshot.version <= self.snapshot.tab_snapshot.version { to_remove_len += 1; } else { break; @@ -282,7 +282,7 @@ impl WrapMap { let was_interpolated = self.snapshot.interpolated; let mut to_remove_len = 0; for (tab_snapshot, edits) in &self.pending_edits { - if tab_snapshot.version() <= self.snapshot.tab_snapshot.version() { + if tab_snapshot.version <= self.snapshot.tab_snapshot.version { to_remove_len += 1; } else { let interpolated_edits = self.snapshot.interpolate(tab_snapshot.clone(), &edits);