Use the new buffer subscription API to keep DisplayMap in sync

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-12-01 16:08:53 +01:00
parent 3b536f153f
commit 733e0cb21b
6 changed files with 34 additions and 103 deletions

View file

@ -10,11 +10,9 @@ use gpui::{
fonts::{FontId, HighlightStyle},
AppContext, Entity, ModelContext, ModelHandle,
};
use language::{Anchor, Buffer, Patch, Point, ToOffset, ToPoint};
use parking_lot::Mutex;
use language::{Anchor, Buffer, Point, Subscription as BufferSubscription, ToOffset, ToPoint};
use std::{
collections::{HashMap, HashSet},
mem,
ops::Range,
};
use sum_tree::Bias;
@ -29,11 +27,11 @@ pub trait ToDisplayPoint {
pub struct DisplayMap {
buffer: ModelHandle<Buffer>,
buffer_subscription: BufferSubscription,
fold_map: FoldMap,
tab_map: TabMap,
wrap_map: ModelHandle<WrapMap>,
block_map: BlockMap,
buffer_edits_since_sync: Mutex<Patch<usize>>,
}
impl Entity for DisplayMap {
@ -49,28 +47,26 @@ impl DisplayMap {
wrap_width: Option<f32>,
cx: &mut ModelContext<Self>,
) -> Self {
let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
let (fold_map, snapshot) = FoldMap::new(buffer.read(cx).snapshot());
let (tab_map, snapshot) = TabMap::new(snapshot, tab_size);
let (wrap_map, snapshot) = WrapMap::new(snapshot, font_id, font_size, wrap_width, cx);
let block_map = BlockMap::new(buffer.clone(), snapshot);
cx.observe(&wrap_map, |_, _, cx| cx.notify()).detach();
cx.subscribe(&buffer, Self::handle_buffer_event).detach();
DisplayMap {
buffer,
buffer_subscription,
fold_map,
tab_map,
wrap_map,
block_map,
buffer_edits_since_sync: Default::default(),
}
}
pub fn snapshot(&self, cx: &mut ModelContext<Self>) -> DisplayMapSnapshot {
let buffer_snapshot = self.buffer.read(cx).snapshot();
let (folds_snapshot, edits) = self.fold_map.read(
buffer_snapshot,
mem::take(&mut *self.buffer_edits_since_sync.lock()).into_inner(),
);
let edits = self.buffer_subscription.consume().into_inner();
let (folds_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits);
let (tabs_snapshot, edits) = self.tab_map.sync(folds_snapshot.clone(), edits);
let (wraps_snapshot, edits) = self
.wrap_map
@ -92,10 +88,8 @@ impl DisplayMap {
cx: &mut ModelContext<Self>,
) {
let snapshot = self.buffer.read(cx).snapshot();
let (mut fold_map, snapshot, edits) = self.fold_map.write(
snapshot,
mem::take(&mut *self.buffer_edits_since_sync.lock()).into_inner(),
);
let edits = self.buffer_subscription.consume().into_inner();
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
let (snapshot, edits) = self
.wrap_map
@ -115,10 +109,8 @@ impl DisplayMap {
cx: &mut ModelContext<Self>,
) {
let snapshot = self.buffer.read(cx).snapshot();
let (mut fold_map, snapshot, edits) = self.fold_map.write(
snapshot,
mem::take(&mut *self.buffer_edits_since_sync.lock()).into_inner(),
);
let edits = self.buffer_subscription.consume().into_inner();
let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
let (snapshot, edits) = self
.wrap_map
@ -142,10 +134,8 @@ impl DisplayMap {
T: Into<Rope> + Clone,
{
let snapshot = self.buffer.read(cx).snapshot();
let (snapshot, edits) = self.fold_map.read(
snapshot,
mem::take(&mut *self.buffer_edits_since_sync.lock()).into_inner(),
);
let edits = self.buffer_subscription.consume().into_inner();
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
let (snapshot, edits) = self
.wrap_map
@ -164,10 +154,8 @@ impl DisplayMap {
pub fn remove_blocks(&mut self, ids: HashSet<BlockId>, cx: &mut ModelContext<Self>) {
let snapshot = self.buffer.read(cx).snapshot();
let (snapshot, edits) = self.fold_map.read(
snapshot,
mem::take(&mut *self.buffer_edits_since_sync.lock()).into_inner(),
);
let edits = self.buffer_subscription.consume().into_inner();
let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits);
let (snapshot, edits) = self
.wrap_map
@ -190,21 +178,6 @@ impl DisplayMap {
pub fn is_rewrapping(&self, cx: &gpui::AppContext) -> bool {
self.wrap_map.read(cx).is_rewrapping()
}
fn handle_buffer_event(
&mut self,
_: ModelHandle<Buffer>,
event: &language::Event,
_: &mut ModelContext<Self>,
) {
match event {
language::Event::Edited(patch) => {
let mut edits_since_sync = self.buffer_edits_since_sync.lock();
*edits_since_sync = edits_since_sync.compose(patch);
}
_ => {}
}
}
}
pub struct DisplayMapSnapshot {