Make writing/reading FoldMap explicit so that we can retrieve edits

This commit is contained in:
Antonio Scandurra
2021-07-16 13:49:38 +02:00
parent 23b55d88d9
commit 831b620e51
4 changed files with 243 additions and 203 deletions
+13
View File
@@ -1930,6 +1930,19 @@ pub struct Snapshot {
query_cursor: QueryCursorHandle,
}
impl Clone for Snapshot {
fn clone(&self) -> Self {
Self {
visible_text: self.visible_text.clone(),
fragments: self.fragments.clone(),
version: self.version.clone(),
tree: self.tree.clone(),
language: self.language.clone(),
query_cursor: QueryCursorHandle::new(),
}
}
}
impl Snapshot {
pub fn len(&self) -> usize {
self.visible_text.len()
+17 -9
View File
@@ -1,31 +1,37 @@
mod fold_map;
mod wrap_map;
use crate::settings::StyleId;
use super::{buffer, Anchor, Bias, Buffer, Point, ToOffset, ToPoint};
use crate::settings::StyleId;
pub use fold_map::BufferRows;
use fold_map::{FoldMap, FoldMapSnapshot};
use fold_map::FoldMap;
use gpui::{AppContext, ModelHandle};
use std::{mem, ops::Range};
use wrap_map::WrapMap;
pub struct DisplayMap {
buffer: ModelHandle<Buffer>,
fold_map: FoldMap,
wrap_map: WrapMap,
tab_size: usize,
}
impl DisplayMap {
pub fn new(buffer: ModelHandle<Buffer>, tab_size: usize, cx: &AppContext) -> Self {
let fold_map = FoldMap::new(buffer.clone(), cx);
let (snapshot, edits) = fold_map.read(cx);
assert_eq!(edits.len(), 0);
let wrap_map = WrapMap::new(snapshot, cx);
DisplayMap {
buffer: buffer.clone(),
fold_map: FoldMap::new(buffer, cx),
buffer,
fold_map,
wrap_map,
tab_size,
}
}
pub fn snapshot(&self, cx: &AppContext) -> DisplayMapSnapshot {
let (folds_snapshot, edits) = self.fold_map.snapshot(cx);
let (folds_snapshot, edits) = self.fold_map.read(cx);
DisplayMapSnapshot {
buffer_snapshot: self.buffer.read(cx).snapshot(),
folds_snapshot,
@@ -38,7 +44,8 @@ impl DisplayMap {
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) {
self.fold_map.fold(ranges, cx)
let (mut fold_map, snapshot, edits) = self.fold_map.write(cx);
let edits = fold_map.fold(ranges, cx);
}
pub fn unfold<T: ToOffset>(
@@ -46,13 +53,14 @@ impl DisplayMap {
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) {
self.fold_map.unfold(ranges, cx)
let (mut fold_map, snapshot, edits) = self.fold_map.write(cx);
let edits = fold_map.unfold(ranges, cx);
}
}
pub struct DisplayMapSnapshot {
buffer_snapshot: buffer::Snapshot,
folds_snapshot: FoldMapSnapshot,
folds_snapshot: fold_map::Snapshot,
tab_size: usize,
}
+161 -134
View File
@@ -15,13 +15,119 @@ use std::{
cmp::{self, Ordering},
iter,
ops::Range,
sync::atomic::{AtomicUsize, Ordering::SeqCst},
};
pub struct FoldMapWriter<'a>(&'a mut FoldMap);
impl<'a> FoldMapWriter<'a> {
pub fn fold<T: ToOffset>(
&mut self,
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) -> Vec<Edit> {
let mut edits = Vec::new();
let mut folds = Vec::new();
let buffer = self.0.buffer.read(cx).snapshot();
for range in ranges.into_iter() {
let range = range.start.to_offset(&buffer)..range.end.to_offset(&buffer);
if range.start != range.end {
let fold = Fold(buffer.anchor_after(range.start)..buffer.anchor_before(range.end));
folds.push(fold);
edits.push(Edit {
old_bytes: range.clone(),
new_bytes: range.clone(),
});
}
}
folds.sort_unstable_by(|a, b| sum_tree::SeekDimension::cmp(a, b, &buffer));
self.0.folds = {
let mut new_tree = SumTree::new();
let mut cursor = self.0.folds.cursor::<_, ()>();
for fold in folds {
new_tree.push_tree(cursor.slice(&fold, Bias::Right, &buffer), &buffer);
new_tree.push(fold, &buffer);
}
new_tree.push_tree(cursor.suffix(&buffer), &buffer);
new_tree
};
self.consolidate_edits(&mut edits);
self.0.apply_edits(edits, cx)
}
pub fn unfold<T: ToOffset>(
&mut self,
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) -> Vec<Edit> {
let mut edits = Vec::new();
let mut fold_ixs_to_delete = Vec::new();
let buffer = self.0.buffer.read(cx).snapshot();
for range in ranges.into_iter() {
// Remove intersecting folds and add their ranges to edits that are passed to apply_edits.
let mut folds_cursor = intersecting_folds(&buffer, &self.0.folds, range);
while let Some(fold) = folds_cursor.item() {
let offset_range = fold.0.start.to_offset(&buffer)..fold.0.end.to_offset(&buffer);
edits.push(Edit {
old_bytes: offset_range.clone(),
new_bytes: offset_range,
});
fold_ixs_to_delete.push(*folds_cursor.start());
folds_cursor.next(&buffer);
}
}
fold_ixs_to_delete.sort_unstable();
fold_ixs_to_delete.dedup();
self.0.folds = {
let mut cursor = self.0.folds.cursor::<_, ()>();
let mut folds = SumTree::new();
for fold_ix in fold_ixs_to_delete {
folds.push_tree(cursor.slice(&fold_ix, Bias::Right, &buffer), &buffer);
cursor.next(&buffer);
}
folds.push_tree(cursor.suffix(&buffer), &buffer);
folds
};
self.consolidate_edits(&mut edits);
self.0.apply_edits(edits, cx)
}
fn consolidate_edits(&self, edits: &mut Vec<Edit>) {
edits.sort_unstable_by(|a, b| {
a.old_bytes
.start
.cmp(&b.old_bytes.start)
.then_with(|| b.old_bytes.end.cmp(&a.old_bytes.end))
});
let mut i = 0;
while i < edits.len() {
let range = edits[i].old_bytes.clone();
if i > 0 {
if edits[i - 1].old_bytes.end >= range.start {
edits[i - 1].old_bytes.end = edits[i - 1].old_bytes.end.max(range.end);
edits[i - 1].new_bytes.end = edits[i - 1].new_bytes.end.max(range.end);
edits.remove(i);
continue;
}
}
i += 1;
}
}
}
pub struct FoldMap {
buffer: ModelHandle<Buffer>,
transforms: Mutex<SumTree<Transform>>,
folds: SumTree<Fold>,
last_sync: Mutex<time::Global>,
version: AtomicUsize,
}
impl FoldMap {
@@ -41,101 +147,26 @@ impl FoldMap {
&(),
)),
last_sync: Mutex::new(buffer.version()),
version: AtomicUsize::new(0),
}
}
pub fn snapshot(&self, cx: &AppContext) -> (FoldMapSnapshot, Vec<Edit>) {
pub fn read(&self, cx: &AppContext) -> (Snapshot, Vec<Edit>) {
let edits = self.sync(cx);
let snapshot = FoldMapSnapshot {
let snapshot = Snapshot {
transforms: self.transforms.lock().clone(),
folds: self.folds.clone(),
buffer: self.buffer.read(cx).snapshot(),
version: self.version.load(SeqCst),
};
(snapshot, edits)
}
pub fn fold<T: ToOffset>(
&mut self,
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) {
let edits = self.sync(cx);
let mut fold_edits = Vec::new();
let mut folds = Vec::new();
let buffer = self.buffer.read(cx).snapshot();
for range in ranges.into_iter() {
let range = range.start.to_offset(&buffer)..range.end.to_offset(&buffer);
if range.start != range.end {
let fold = Fold(buffer.anchor_after(range.start)..buffer.anchor_before(range.end));
folds.push(fold);
fold_edits.push(Edit {
old_bytes: range.clone(),
new_bytes: range.clone(),
});
}
}
folds.sort_unstable_by(|a, b| sum_tree::SeekDimension::cmp(a, b, &buffer));
self.folds = {
let mut new_tree = SumTree::new();
let mut cursor = self.folds.cursor::<_, ()>();
for fold in folds {
new_tree.push_tree(cursor.slice(&fold, Bias::Right, &buffer), &buffer);
new_tree.push(fold, &buffer);
}
new_tree.push_tree(cursor.suffix(&buffer), &buffer);
new_tree
};
self.consolidate_edits(&mut fold_edits);
self.apply_edits(fold_edits, cx);
pub fn write(&mut self, cx: &AppContext) -> (FoldMapWriter, Snapshot, Vec<Edit>) {
let (snapshot, edits) = self.read(cx);
(FoldMapWriter(self), snapshot, edits)
}
pub fn unfold<T: ToOffset>(
&mut self,
ranges: impl IntoIterator<Item = Range<T>>,
cx: &AppContext,
) {
let edits = self.sync(cx);
let mut fold_edits = Vec::new();
let mut fold_ixs_to_delete = Vec::new();
let buffer = self.buffer.read(cx).snapshot();
for range in ranges.into_iter() {
// Remove intersecting folds and add their ranges to edits that are passed to apply_edits.
let mut folds_cursor = intersecting_folds(&buffer, &self.folds, range);
while let Some(fold) = folds_cursor.item() {
let offset_range = fold.0.start.to_offset(&buffer)..fold.0.end.to_offset(&buffer);
fold_edits.push(Edit {
old_bytes: offset_range.clone(),
new_bytes: offset_range,
});
fold_ixs_to_delete.push(*folds_cursor.start());
folds_cursor.next(&buffer);
}
}
fold_ixs_to_delete.sort_unstable();
fold_ixs_to_delete.dedup();
self.folds = {
let mut cursor = self.folds.cursor::<_, ()>();
let mut folds = SumTree::new();
for fold_ix in fold_ixs_to_delete {
folds.push_tree(cursor.slice(&fold_ix, Bias::Right, &buffer), &buffer);
cursor.next(&buffer);
}
folds.push_tree(cursor.suffix(&buffer), &buffer);
folds
};
self.consolidate_edits(&mut fold_edits);
self.apply_edits(fold_edits, cx);
}
#[must_use]
fn sync(&self, cx: &AppContext) -> Vec<Edit> {
let buffer = self.buffer.read(cx);
let edits = buffer
@@ -325,45 +356,29 @@ impl FoldMap {
}
*transforms = new_transforms;
self.version.fetch_add(1, SeqCst);
edits
}
fn consolidate_edits(&self, edits: &mut Vec<Edit>) {
edits.sort_unstable_by(|a, b| {
a.old_bytes
.start
.cmp(&b.old_bytes.start)
.then_with(|| b.old_bytes.end.cmp(&a.old_bytes.end))
});
let mut i = 0;
while i < edits.len() {
let range = edits[i].old_bytes.clone();
if i > 0 {
if edits[i - 1].old_bytes.end >= range.start {
edits[i - 1].old_bytes.end = edits[i - 1].old_bytes.end.max(range.end);
edits[i - 1].new_bytes.end = edits[i - 1].new_bytes.end.max(range.end);
edits.remove(i);
continue;
}
}
i += 1;
}
}
}
pub struct FoldMapSnapshot {
#[derive(Clone)]
pub struct Snapshot {
transforms: SumTree<Transform>,
folds: SumTree<Fold>,
buffer: buffer::Snapshot,
pub version: usize,
}
impl FoldMapSnapshot {
impl Snapshot {
#[cfg(test)]
pub fn text(&self) -> String {
self.chunks_at(DisplayOffset(0)).collect()
}
pub fn text_summary(&self) -> TextSummary {
self.transforms.summary().display
}
pub fn len(&self) -> usize {
self.transforms.summary().display.bytes
}
@@ -928,14 +943,15 @@ mod tests {
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(5, 6), cx));
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
map.fold(
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(
vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(2, 4)..Point::new(4, 1),
],
cx.as_ref(),
);
let (snapshot2, edits) = map.snapshot(cx.as_ref());
let (snapshot2, edits) = map.read(cx.as_ref());
assert_eq!(snapshot2.text(), "aa…cc…eeeee");
assert_eq!(
edits,
@@ -961,7 +977,7 @@ mod tests {
cx,
);
});
let (snapshot3, edits) = map.snapshot(cx.as_ref());
let (snapshot3, edits) = map.read(cx.as_ref());
assert_eq!(snapshot3.text(), "123a…c123c…eeeee");
assert_eq!(
edits,
@@ -980,11 +996,12 @@ mod tests {
buffer.update(cx, |buffer, cx| {
buffer.edit(vec![Point::new(2, 6)..Point::new(4, 3)], "456", cx)
});
let (snapshot4, _) = map.snapshot(cx.as_ref());
let (snapshot4, _) = map.read(cx.as_ref());
assert_eq!(snapshot4.text(), "123a…c123456eee");
map.unfold(Some(Point::new(0, 4)..Point::new(0, 5)), cx.as_ref());
let (snapshot5, _) = map.snapshot(cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.unfold(Some(Point::new(0, 4)..Point::new(0, 5)), cx.as_ref());
let (snapshot5, _) = map.read(cx.as_ref());
assert_eq!(snapshot5.text(), "123aaaaa\nbbbbbb\nccc123456eee");
}
@@ -995,21 +1012,24 @@ mod tests {
{
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
map.fold(vec![5..8], cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(vec![5..8], cx.as_ref());
map.check_invariants(cx.as_ref());
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "abcde…ijkl");
// Create an fold adjacent to the start of the first fold.
map.fold(vec![0..1, 2..5], cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(vec![0..1, 2..5], cx.as_ref());
map.check_invariants(cx.as_ref());
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "…b…ijkl");
// Create an fold adjacent to the end of the first fold.
map.fold(vec![11..11, 8..10], cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(vec![11..11, 8..10], cx.as_ref());
map.check_invariants(cx.as_ref());
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "…b…kl");
}
@@ -1017,9 +1037,10 @@ mod tests {
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
// Create two adjacent folds.
map.fold(vec![0..2, 2..5], cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(vec![0..2, 2..5], cx.as_ref());
map.check_invariants(cx.as_ref());
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "…fghijkl");
// Edit within one of the folds.
@@ -1029,7 +1050,7 @@ mod tests {
buffer.edits_since(version).collect::<Vec<_>>()
});
map.check_invariants(cx.as_ref());
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "12345…fghijkl");
}
}
@@ -1038,7 +1059,8 @@ mod tests {
fn test_overlapping_folds(cx: &mut gpui::MutableAppContext) {
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(5, 6), cx));
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
map.fold(
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(
vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(0, 4)..Point::new(1, 0),
@@ -1047,7 +1069,7 @@ mod tests {
],
cx.as_ref(),
);
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "aa…eeeee");
}
@@ -1056,20 +1078,21 @@ mod tests {
let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(5, 6), cx));
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
map.fold(
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(
vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(3, 1)..Point::new(4, 1),
],
cx.as_ref(),
);
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "aa…cccc\nd…eeeee");
buffer.update(cx, |buffer, cx| {
buffer.edit(Some(Point::new(2, 2)..Point::new(3, 1)), "", cx)
});
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "aa…eeeee");
}
@@ -1079,7 +1102,8 @@ mod tests {
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
let buffer = buffer.read(cx);
map.fold(
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(
vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(0, 4)..Point::new(1, 0),
@@ -1088,7 +1112,7 @@ mod tests {
],
cx.as_ref(),
);
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
let fold_ranges = snapshot
.folds_in_range(Point::new(1, 0)..Point::new(1, 3))
.map(|fold| fold.start.to_point(buffer)..fold.end.to_point(buffer))
@@ -1146,7 +1170,8 @@ mod tests {
to_fold.push(start..end);
}
log::info!("folding {:?}", to_fold);
map.fold(to_fold, cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(to_fold, cx.as_ref());
}
35..=59 if !map.folds.is_empty() => {
let buffer = buffer.read(cx);
@@ -1157,7 +1182,8 @@ mod tests {
to_unfold.push(start..end);
}
log::info!("unfolding {:?}", to_unfold);
map.unfold(to_unfold, cx.as_ref());
let (mut writer, _, _) = map.write(cx.as_ref());
writer.unfold(to_unfold, cx.as_ref());
}
_ => {
let edits = buffer.update(cx, |buffer, cx| {
@@ -1186,7 +1212,7 @@ mod tests {
expected_buffer_rows.extend((0..=next_row).rev());
expected_buffer_rows.reverse();
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), expected_text);
for (display_row, line) in expected_text.lines().enumerate() {
@@ -1306,7 +1332,8 @@ mod tests {
let mut map = FoldMap::new(buffer.clone(), cx.as_ref());
map.fold(
let (mut writer, _, _) = map.write(cx.as_ref());
writer.fold(
vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(3, 1)..Point::new(4, 1),
@@ -1314,7 +1341,7 @@ mod tests {
cx.as_ref(),
);
let (snapshot, _) = map.snapshot(cx.as_ref());
let (snapshot, _) = map.read(cx.as_ref());
assert_eq!(snapshot.text(), "aa…cccc\nd…eeeee\nffffff\n");
assert_eq!(snapshot.buffer_rows(0).collect::<Vec<_>>(), [0, 3, 5, 6]);
assert_eq!(snapshot.buffer_rows(3).collect::<Vec<_>>(), [6]);
+52 -60
View File
@@ -1,97 +1,85 @@
use crate::{
editor::{display_map::FoldMap, Buffer, Point, TextSummary},
editor::{display_map::fold_map, Point, TextSummary},
sum_tree::{self, SumTree},
time,
util::Bias,
};
use gpui::{Entity, ModelContext, ModelHandle, Task};
use gpui::{AppContext, Task};
use parking_lot::Mutex;
use postage::{
mpsc,
prelude::{Sink, Stream},
watch,
};
use postage::{prelude::Sink, watch};
use smol::channel;
#[derive(Clone)]
struct Snapshot {
pub struct Snapshot {
transforms: SumTree<Transform>,
version: time::Global,
version: usize,
}
struct State {
snapshot: Snapshot,
interpolated_version: time::Global,
interpolated_version: usize,
}
struct WrapMap {
buffer: ModelHandle<Buffer>,
fold_map: FoldMap,
pub struct WrapMap {
state: Mutex<State>,
edits_tx: channel::Sender<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
background_snapshots: watch::Receiver<Snapshot>,
_background_task: Task<()>,
}
impl Entity for WrapMap {
type Event = ();
}
impl WrapMap {
fn new(buffer_handle: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self {
let buffer = buffer_handle.read(cx).clone();
let version = buffer.version();
pub fn new(folds_snapshot: fold_map::Snapshot, cx: &AppContext) -> Self {
let snapshot = Snapshot {
transforms: SumTree::from_item(
Transform {
summary: TransformSummary {
buffer: buffer.text_summary(),
display: buffer.text_summary(),
folded: folds_snapshot.text_summary(),
wrapped: folds_snapshot.text_summary(),
},
display_text: None,
},
&(),
),
version: version.clone(),
version: folds_snapshot.version,
};
let (background_snapshots_tx, background_snapshots_rx) =
watch::channel_with(snapshot.clone());
let (buffers_tx, buffers_rx) = mpsc::channel(32);
cx.observe(&buffer_handle, move |_, buffer, cx| {
let mut buffers_tx = buffers_tx.clone();
// TODO: replace cloning buffers with sending `Buffer::snapshot`.
let buffer = buffer.read(cx).clone();
cx.spawn_weak(|_, _| async move {
let _ = buffers_tx.send(buffer).await;
})
.detach();
});
let (edits_tx, edits_rx) = channel::unbounded();
let background_task = cx.background().spawn(async move {
let mut wrapper = BackgroundWrapper::new(buffers_rx, background_snapshots_tx);
wrapper.run(buffer).await;
let mut wrapper = BackgroundWrapper::new(edits_rx, background_snapshots_tx);
wrapper.run(folds_snapshot).await;
});
Self {
buffer: buffer_handle.clone(),
fold_map: FoldMap::new(buffer_handle, cx.as_ref()),
state: Mutex::new(State {
interpolated_version: snapshot.version,
snapshot,
interpolated_version: version,
}),
edits_tx,
background_snapshots: background_snapshots_rx,
_background_task: background_task,
}
}
pub fn read(&self, folds_snapshot: fold_map::Snapshot, edits: Vec<fold_map::Edit>) -> Snapshot {
// TODO: interpolate
self.edits_tx.try_send((folds_snapshot, edits)).unwrap();
self.state.lock().snapshot.clone()
}
}
struct BackgroundWrapper {
buffers_rx: mpsc::Receiver<Buffer>,
edits_rx: channel::Receiver<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
snapshots_tx: watch::Sender<Snapshot>,
snapshot: Snapshot,
}
impl BackgroundWrapper {
fn new(buffers_rx: mpsc::Receiver<Buffer>, snapshots_tx: watch::Sender<Snapshot>) -> Self {
fn new(
edits_rx: channel::Receiver<(fold_map::Snapshot, Vec<fold_map::Edit>)>,
snapshots_tx: watch::Sender<Snapshot>,
) -> Self {
Self {
buffers_rx,
edits_rx,
snapshots_tx,
snapshot: Snapshot {
transforms: Default::default(),
@@ -100,32 +88,36 @@ impl BackgroundWrapper {
}
}
async fn run(&mut self, buffer: Buffer) {
if !self.sync(buffer).await {
async fn run(&mut self, snapshot: fold_map::Snapshot) {
let edit = fold_map::Edit {
old_bytes: 0..0,
new_bytes: 0..snapshot.len(),
};
if !self.sync(snapshot, vec![edit]).await {
return;
}
while let Some(buffer) = self.buffers_rx.recv().await {
if !self.sync(buffer).await {
while let Ok((snapshot, edits)) = self.edits_rx.recv().await {
if !self.sync(snapshot, edits).await {
break;
}
}
}
async fn sync(&mut self, buffer: Buffer) -> bool {
async fn sync(&mut self, snapshot: fold_map::Snapshot, edits: Vec<fold_map::Edit>) -> bool {
let mut new_transforms = SumTree::new();
{
let mut old_cursor = self.snapshot.transforms.cursor::<Point, ()>();
for edit in buffer.edits_since(self.snapshot.version.clone()) {
new_transforms.push_tree(
old_cursor.slice(&Point::new(edit.old_lines.start.row, 0), Bias::Left, &()),
&(),
);
}
// let mut old_cursor = self.snapshot.transforms.cursor::<Point, ()>();
// for edit in buffer.edits_since(self.snapshot.version.clone()) {
// new_transforms.push_tree(
// old_cursor.slice(&Point::new(edit.old_lines.start.row, 0), Bias::Left, &()),
// &(),
// );
// }
}
self.snapshot.transforms = new_transforms;
self.snapshot.version = buffer.version();
self.snapshot.version = snapshot.version;
self.snapshots_tx.send(self.snapshot.clone()).await.is_ok()
}
}
@@ -146,21 +138,21 @@ impl sum_tree::Item for Transform {
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct TransformSummary {
display: TextSummary,
buffer: TextSummary,
folded: TextSummary,
wrapped: TextSummary,
}
impl sum_tree::Summary for TransformSummary {
type Context = ();
fn add_summary(&mut self, other: &Self, _: &()) {
self.buffer += &other.buffer;
self.display += &other.display;
self.folded += &other.folded;
self.wrapped += &other.wrapped;
}
}
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.buffer.lines;
*self += &summary.folded.lines;
}
}