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 <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo 2021-07-15 15:08:18 -06:00
parent 2c9f730638
commit 8b34deab58

View file

@ -10,7 +10,7 @@ use crate::{
util::Bias, util::Bias,
}; };
use gpui::{AppContext, ModelHandle}; use gpui::{AppContext, ModelHandle};
use parking_lot::{Mutex, MutexGuard}; use parking_lot::Mutex;
use std::{ use std::{
cmp::{self, Ordering}, cmp::{self, Ordering},
iter, iter,
@ -45,8 +45,9 @@ impl FoldMap {
} }
pub fn snapshot(&self, cx: &AppContext) -> FoldMapSnapshot { pub fn snapshot(&self, cx: &AppContext) -> FoldMapSnapshot {
self.sync(cx);
FoldMapSnapshot { FoldMapSnapshot {
transforms: self.sync(cx).clone(), transforms: self.transforms.lock().clone(),
folds: self.folds.clone(), folds: self.folds.clone(),
buffer: self.buffer.read(cx).snapshot(), buffer: self.buffer.read(cx).snapshot(),
} }
@ -57,7 +58,7 @@ impl FoldMap {
ranges: impl IntoIterator<Item = Range<T>>, ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext, cx: &AppContext,
) { ) {
let _ = self.sync(cx); self.sync(cx);
let mut edits = Vec::new(); let mut edits = Vec::new();
let mut folds = Vec::new(); let mut folds = Vec::new();
@ -100,7 +101,7 @@ impl FoldMap {
ranges: impl IntoIterator<Item = Range<T>>, ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext, cx: &AppContext,
) { ) {
let _ = self.sync(cx); self.sync(cx);
let buffer = self.buffer.read(cx).snapshot(); let buffer = self.buffer.read(cx).snapshot();
let snapshot = self.snapshot(cx); let snapshot = self.snapshot(cx);
@ -143,29 +144,31 @@ impl FoldMap {
self.apply_edits(edits, cx); self.apply_edits(edits, cx);
} }
fn sync(&self, cx: &AppContext) -> MutexGuard<SumTree<Transform>> { fn sync(&self, cx: &AppContext) -> Vec<Edit> {
let buffer = self.buffer.read(cx); let buffer = self.buffer.read(cx);
let mut edits = buffer let mut edits = buffer
.edits_since(self.last_sync.lock().clone()) .edits_since(self.last_sync.lock().clone())
.map(Into::into) .map(Into::into)
.peekable(); .peekable();
if edits.peek().is_some() { let edits = if edits.peek().is_some() {
self.apply_edits(edits, cx); self.apply_edits(edits, cx)
} } else {
Vec::new()
};
*self.last_sync.lock() = buffer.version(); *self.last_sync.lock() = buffer.version();
self.transforms.lock() edits
} }
fn apply_edits(&self, edits: impl IntoIterator<Item = Edit>, cx: &AppContext) { fn apply_edits(&self, edits: Vec<Edit>, cx: &AppContext) -> Vec<Edit> {
let buffer = self.buffer.read(cx).snapshot(); 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 new_transforms = SumTree::new();
let mut transforms = self.transforms.lock(); let mut transforms = self.transforms.lock();
let mut cursor = transforms.cursor::<usize, ()>(); let mut cursor = transforms.cursor::<usize, ()>();
cursor.seek(&0, Bias::Right, &()); 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, &()), &()); new_transforms.push_tree(cursor.slice(&edit.old_bytes.start, Bias::Left, &()), &());
edit.new_bytes.start -= edit.old_bytes.start - cursor.seek_start(); edit.new_bytes.start -= edit.old_bytes.start - cursor.seek_start();
edit.old_bytes.start = *cursor.seek_start(); edit.old_bytes.start = *cursor.seek_start();
@ -177,12 +180,12 @@ impl FoldMap {
loop { loop {
edit.old_bytes.end = *cursor.seek_start(); 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 { if next_edit.old_bytes.start > edit.old_bytes.end {
break; break;
} }
let next_edit = edits.next().unwrap(); let next_edit = edits_iter.next().unwrap();
delta += next_edit.delta(); delta += next_edit.delta();
if next_edit.old_bytes.end >= edit.old_bytes.end { if next_edit.old_bytes.end >= edit.old_bytes.end {
@ -304,7 +307,29 @@ impl FoldMap {
} }
drop(cursor); drop(cursor);
{
let mut old_transforms = transforms.cursor::<usize, DisplayOffset>();
let mut new_transforms = new_transforms.cursor::<usize, DisplayOffset>();
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; *transforms = new_transforms;
edits
} }
} }
@ -839,6 +864,7 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize {
} }
} }
#[derive(Clone)]
struct Edit { struct Edit {
old_bytes: Range<usize>, old_bytes: Range<usize>,
new_bytes: Range<usize>, new_bytes: Range<usize>,
@ -1275,10 +1301,10 @@ mod tests {
} }
fn check_invariants(&self, cx: &AppContext) { fn check_invariants(&self, cx: &AppContext) {
let transforms = self.sync(cx); self.sync(cx);
let buffer = self.buffer.read(cx); let buffer = self.buffer.read(cx);
assert_eq!( assert_eq!(
transforms.summary().buffer.bytes, self.transforms.lock().summary().buffer.bytes,
buffer.len(), buffer.len(),
"transform tree does not match buffer's length" "transform tree does not match buffer's length"
); );