From a5edc14e3a53e59d48ac7a08c61c0be83c85d658 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 14 Jul 2021 18:43:48 +0200 Subject: [PATCH] WIP: Start on `WrapMap` --- zed/src/editor/display_map.rs | 1 + zed/src/editor/display_map/fold_map.rs | 5 +- zed/src/editor/display_map/wrap_map.rs | 151 +++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 zed/src/editor/display_map/wrap_map.rs diff --git a/zed/src/editor/display_map.rs b/zed/src/editor/display_map.rs index c8c5ea64a0873cc1b303525ef211d7421b71769a..ed7aa808942430af1b97397f3f8f47acb96c6d8a 100644 --- a/zed/src/editor/display_map.rs +++ b/zed/src/editor/display_map.rs @@ -1,4 +1,5 @@ mod fold_map; +mod wrap_map; use crate::settings::StyleId; diff --git a/zed/src/editor/display_map/fold_map.rs b/zed/src/editor/display_map/fold_map.rs index 227553a1b6f7c1550703eef3aa480f38cdcbfaa3..1024dc545e37ef0aeac3e602e7178c8a79f2424d 100644 --- a/zed/src/editor/display_map/fold_map.rs +++ b/zed/src/editor/display_map/fold_map.rs @@ -27,15 +27,14 @@ pub struct FoldMap { impl FoldMap { pub fn new(buffer_handle: ModelHandle, 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, }, diff --git a/zed/src/editor/display_map/wrap_map.rs b/zed/src/editor/display_map/wrap_map.rs new file mode 100644 index 0000000000000000000000000000000000000000..a863d0cb240d8597c6ab0d5dc58b0774ebda4c5e --- /dev/null +++ b/zed/src/editor/display_map/wrap_map.rs @@ -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, + version: time::Global, +} + +struct State { + snapshot: Snapshot, + interpolated_version: time::Global, +} + +struct WrapMap { + buffer: ModelHandle, + fold_map: FoldMap, + state: Mutex, + background_snapshots: watch::Receiver, + _background_task: Task<()>, +} + +impl Entity for WrapMap { + type Event = (); +} + +impl WrapMap { + fn new(buffer_handle: ModelHandle, cx: &mut ModelContext) -> 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, + snapshots_tx: watch::Sender, + snapshot: Snapshot, +} + +impl BackgroundWrapper { + fn new(buffers_rx: mpsc::Receiver, snapshots_tx: watch::Sender) -> 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, &()); + } +}