mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-05 02:20:10 +00:00
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:
parent
2c9f730638
commit
8b34deab58
1 changed files with 42 additions and 16 deletions
|
@ -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"
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue