zed/src/editor/display_map.rs 🔗
@@ -1,4 +1,5 @@
mod fold_map;
+mod wrap_map;
use crate::settings::StyleId;
Antonio Scandurra created
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(-)
@@ -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, &());
+ }
+}