WIP: Start on WrapMap
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
mod fold_map;
|
||||
mod wrap_map;
|
||||
|
||||
use crate::settings::StyleId;
|
||||
|
||||
|
||||
@@ -27,15 +27,14 @@ pub struct FoldMap {
|
||||
impl FoldMap {
|
||||
pub fn new(buffer_handle: ModelHandle<Buffer>, cx: &AppContext) -> Self {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let text_summary = buffer.text_summary();
|
||||
Self {
|
||||
buffer: buffer_handle,
|
||||
folds: Default::default(),
|
||||
transforms: Mutex::new(SumTree::from_item(
|
||||
Transform {
|
||||
summary: TransformSummary {
|
||||
buffer: text_summary.clone(),
|
||||
display: text_summary,
|
||||
buffer: buffer.text_summary(),
|
||||
display: buffer.text_summary(),
|
||||
},
|
||||
display_text: None,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
use crate::{
|
||||
editor::{display_map::FoldMap, Buffer, TextSummary},
|
||||
sum_tree::{self, SumTree},
|
||||
time,
|
||||
};
|
||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
|
||||
use parking_lot::Mutex;
|
||||
use postage::{
|
||||
mpsc,
|
||||
prelude::{Sink, Stream},
|
||||
watch,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Snapshot {
|
||||
transforms: SumTree<Transform>,
|
||||
version: time::Global,
|
||||
}
|
||||
|
||||
struct State {
|
||||
snapshot: Snapshot,
|
||||
interpolated_version: time::Global,
|
||||
}
|
||||
|
||||
struct WrapMap {
|
||||
buffer: ModelHandle<Buffer>,
|
||||
fold_map: FoldMap,
|
||||
state: Mutex<State>,
|
||||
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();
|
||||
let snapshot = Snapshot {
|
||||
transforms: SumTree::from_item(
|
||||
Transform {
|
||||
summary: TransformSummary {
|
||||
buffer: buffer.text_summary(),
|
||||
display: buffer.text_summary(),
|
||||
},
|
||||
display_text: None,
|
||||
},
|
||||
&(),
|
||||
),
|
||||
version: version.clone(),
|
||||
};
|
||||
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();
|
||||
let buffer = buffer.read(cx).clone();
|
||||
cx.spawn_weak(|_, _| async move {
|
||||
let _ = buffers_tx.send(buffer).await;
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
let background_task = cx.background().spawn(async move {
|
||||
let mut wrapper = BackgroundWrapper::new(buffers_rx, background_snapshots_tx);
|
||||
wrapper.run(buffer).await;
|
||||
});
|
||||
|
||||
Self {
|
||||
buffer: buffer_handle.clone(),
|
||||
fold_map: FoldMap::new(buffer_handle, cx.as_ref()),
|
||||
state: Mutex::new(State {
|
||||
snapshot,
|
||||
interpolated_version: version,
|
||||
}),
|
||||
background_snapshots: background_snapshots_rx,
|
||||
_background_task: background_task,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BackgroundWrapper {
|
||||
buffers_rx: mpsc::Receiver<Buffer>,
|
||||
snapshots_tx: watch::Sender<Snapshot>,
|
||||
snapshot: Snapshot,
|
||||
}
|
||||
|
||||
impl BackgroundWrapper {
|
||||
fn new(buffers_rx: mpsc::Receiver<Buffer>, snapshots_tx: watch::Sender<Snapshot>) -> Self {
|
||||
Self {
|
||||
buffers_rx,
|
||||
snapshots_tx,
|
||||
snapshot: Snapshot {
|
||||
transforms: Default::default(),
|
||||
version: Default::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async fn run(&mut self, buffer: Buffer) {
|
||||
if !self.sync(buffer).await {
|
||||
return;
|
||||
}
|
||||
|
||||
while let Some(buffer) = self.buffers_rx.recv().await {
|
||||
if !self.sync(buffer).await {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn sync(&mut self, buffer: Buffer) -> bool {
|
||||
self.snapshots_tx.send(self.snapshot.clone()).await.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
struct Transform {
|
||||
summary: TransformSummary,
|
||||
display_text: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl sum_tree::Item for Transform {
|
||||
type Summary = TransformSummary;
|
||||
|
||||
fn summary(&self) -> Self::Summary {
|
||||
self.summary.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
struct TransformSummary {
|
||||
display: TextSummary,
|
||||
buffer: TextSummary,
|
||||
}
|
||||
|
||||
impl sum_tree::Summary for TransformSummary {
|
||||
type Context = ();
|
||||
|
||||
fn add_summary(&mut self, other: &Self, _: &()) {
|
||||
self.buffer += &other.buffer;
|
||||
self.display += &other.display;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::Dimension<'a, TransformSummary> for TransformSummary {
|
||||
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
|
||||
sum_tree::Summary::add_summary(self, summary, &());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user