From 8b34deab5895e5f60599f9164f48ed332dbfe2ae Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 15 Jul 2021 15:08:18 -0600 Subject: [PATCH] Try to return edits from FoldMap::apply_edits The goal is to describe how the fold map changed. Hopefully this is correct. Co-Authored-By: Max Brunsfeld --- zed/src/editor/display_map/fold_map.rs | 58 +++++++++++++++++++------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/zed/src/editor/display_map/fold_map.rs b/zed/src/editor/display_map/fold_map.rs index 49c8d5308a..1fa13f8aa4 100644 --- a/zed/src/editor/display_map/fold_map.rs +++ b/zed/src/editor/display_map/fold_map.rs @@ -10,7 +10,7 @@ use crate::{ util::Bias, }; use gpui::{AppContext, ModelHandle}; -use parking_lot::{Mutex, MutexGuard}; +use parking_lot::Mutex; use std::{ cmp::{self, Ordering}, iter, @@ -45,8 +45,9 @@ impl FoldMap { } pub fn snapshot(&self, cx: &AppContext) -> FoldMapSnapshot { + self.sync(cx); FoldMapSnapshot { - transforms: self.sync(cx).clone(), + transforms: self.transforms.lock().clone(), folds: self.folds.clone(), buffer: self.buffer.read(cx).snapshot(), } @@ -57,7 +58,7 @@ impl FoldMap { ranges: impl IntoIterator>, cx: &AppContext, ) { - let _ = self.sync(cx); + self.sync(cx); let mut edits = Vec::new(); let mut folds = Vec::new(); @@ -100,7 +101,7 @@ impl FoldMap { ranges: impl IntoIterator>, cx: &AppContext, ) { - let _ = self.sync(cx); + self.sync(cx); let buffer = self.buffer.read(cx).snapshot(); let snapshot = self.snapshot(cx); @@ -143,29 +144,31 @@ impl FoldMap { self.apply_edits(edits, cx); } - fn sync(&self, cx: &AppContext) -> MutexGuard> { + fn sync(&self, cx: &AppContext) -> Vec { let buffer = self.buffer.read(cx); let mut edits = buffer .edits_since(self.last_sync.lock().clone()) .map(Into::into) .peekable(); - if edits.peek().is_some() { - self.apply_edits(edits, cx); - } + let edits = if edits.peek().is_some() { + self.apply_edits(edits, cx) + } else { + Vec::new() + }; *self.last_sync.lock() = buffer.version(); - self.transforms.lock() + edits } - fn apply_edits(&self, edits: impl IntoIterator, cx: &AppContext) { + fn apply_edits(&self, edits: Vec, cx: &AppContext) -> Vec { let buffer = self.buffer.read(cx).snapshot(); - let mut edits = edits.into_iter().peekable(); + let mut edits_iter = edits.iter().cloned().peekable(); let mut new_transforms = SumTree::new(); let mut transforms = self.transforms.lock(); let mut cursor = transforms.cursor::(); cursor.seek(&0, Bias::Right, &()); - while let Some(mut edit) = edits.next() { + while let Some(mut edit) = edits_iter.next() { new_transforms.push_tree(cursor.slice(&edit.old_bytes.start, Bias::Left, &()), &()); edit.new_bytes.start -= edit.old_bytes.start - cursor.seek_start(); edit.old_bytes.start = *cursor.seek_start(); @@ -177,12 +180,12 @@ impl FoldMap { loop { edit.old_bytes.end = *cursor.seek_start(); - if let Some(next_edit) = edits.peek() { + if let Some(next_edit) = edits_iter.peek() { if next_edit.old_bytes.start > edit.old_bytes.end { break; } - let next_edit = edits.next().unwrap(); + let next_edit = edits_iter.next().unwrap(); delta += next_edit.delta(); if next_edit.old_bytes.end >= edit.old_bytes.end { @@ -304,7 +307,29 @@ impl FoldMap { } drop(cursor); + + { + let mut old_transforms = transforms.cursor::(); + let mut new_transforms = new_transforms.cursor::(); + for edit in &mut edits { + old_transforms.seek_forward(&edit.old_bytes.start, Bias::Right, &()); + edit.old_bytes.start = old_transforms.sum_start().0 + + (edit.old_bytes.start - old_transforms.seek_start()); + old_transforms.seek_forward(&edit.old_bytes.end, Bias::Right, &()); + edit.old_bytes.end = old_transforms.sum_start().0 + + (edit.old_bytes.end - old_transforms.seek_start()); + new_transforms.seek_forward(&edit.new_bytes.start, Bias::Right, &()); + edit.new_bytes.start = new_transforms.sum_start().0 + + (edit.new_bytes.start - new_transforms.seek_start()); + new_transforms.seek_forward(&edit.new_bytes.end, Bias::Right, &()); + edit.new_bytes.end = new_transforms.sum_start().0 + + (edit.new_bytes.end - new_transforms.seek_start()); + } + } + *transforms = new_transforms; + + edits } } @@ -839,6 +864,7 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { } } +#[derive(Clone)] struct Edit { old_bytes: Range, new_bytes: Range, @@ -1275,10 +1301,10 @@ mod tests { } fn check_invariants(&self, cx: &AppContext) { - let transforms = self.sync(cx); + self.sync(cx); let buffer = self.buffer.read(cx); assert_eq!( - transforms.summary().buffer.bytes, + self.transforms.lock().summary().buffer.bytes, buffer.len(), "transform tree does not match buffer's length" );