1use crate::{
2 editor::{display_map::FoldMap, Buffer, TextSummary},
3 sum_tree::{self, SumTree},
4 time,
5};
6use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
7use parking_lot::Mutex;
8use postage::{
9 mpsc,
10 prelude::{Sink, Stream},
11 watch,
12};
13
14#[derive(Clone)]
15struct Snapshot {
16 transforms: SumTree<Transform>,
17 version: time::Global,
18}
19
20struct State {
21 snapshot: Snapshot,
22 interpolated_version: time::Global,
23}
24
25struct WrapMap {
26 buffer: ModelHandle<Buffer>,
27 fold_map: FoldMap,
28 state: Mutex<State>,
29 background_snapshots: watch::Receiver<Snapshot>,
30 _background_task: Task<()>,
31}
32
33impl Entity for WrapMap {
34 type Event = ();
35}
36
37impl WrapMap {
38 fn new(buffer_handle: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self {
39 let buffer = buffer_handle.read(cx).clone();
40 let version = buffer.version();
41 let snapshot = Snapshot {
42 transforms: SumTree::from_item(
43 Transform {
44 summary: TransformSummary {
45 buffer: buffer.text_summary(),
46 display: buffer.text_summary(),
47 },
48 display_text: None,
49 },
50 &(),
51 ),
52 version: version.clone(),
53 };
54 let (background_snapshots_tx, background_snapshots_rx) =
55 watch::channel_with(snapshot.clone());
56 let (buffers_tx, buffers_rx) = mpsc::channel(32);
57 cx.observe(&buffer_handle, move |_, buffer, cx| {
58 let mut buffers_tx = buffers_tx.clone();
59 let buffer = buffer.read(cx).clone();
60 cx.spawn_weak(|_, _| async move {
61 let _ = buffers_tx.send(buffer).await;
62 })
63 .detach();
64 });
65 let background_task = cx.background().spawn(async move {
66 let mut wrapper = BackgroundWrapper::new(buffers_rx, background_snapshots_tx);
67 wrapper.run(buffer).await;
68 });
69
70 Self {
71 buffer: buffer_handle.clone(),
72 fold_map: FoldMap::new(buffer_handle, cx.as_ref()),
73 state: Mutex::new(State {
74 snapshot,
75 interpolated_version: version,
76 }),
77 background_snapshots: background_snapshots_rx,
78 _background_task: background_task,
79 }
80 }
81}
82
83struct BackgroundWrapper {
84 buffers_rx: mpsc::Receiver<Buffer>,
85 snapshots_tx: watch::Sender<Snapshot>,
86 snapshot: Snapshot,
87}
88
89impl BackgroundWrapper {
90 fn new(buffers_rx: mpsc::Receiver<Buffer>, snapshots_tx: watch::Sender<Snapshot>) -> Self {
91 Self {
92 buffers_rx,
93 snapshots_tx,
94 snapshot: Snapshot {
95 transforms: Default::default(),
96 version: Default::default(),
97 },
98 }
99 }
100
101 async fn run(&mut self, buffer: Buffer) {
102 if !self.sync(buffer).await {
103 return;
104 }
105
106 while let Some(buffer) = self.buffers_rx.recv().await {
107 if !self.sync(buffer).await {
108 break;
109 }
110 }
111 }
112
113 async fn sync(&mut self, buffer: Buffer) -> bool {
114 self.snapshots_tx.send(self.snapshot.clone()).await.is_ok()
115 }
116}
117
118#[derive(Clone, Debug, Default, Eq, PartialEq)]
119struct Transform {
120 summary: TransformSummary,
121 display_text: Option<&'static str>,
122}
123
124impl sum_tree::Item for Transform {
125 type Summary = TransformSummary;
126
127 fn summary(&self) -> Self::Summary {
128 self.summary.clone()
129 }
130}
131
132#[derive(Clone, Debug, Default, Eq, PartialEq)]
133struct TransformSummary {
134 display: TextSummary,
135 buffer: TextSummary,
136}
137
138impl sum_tree::Summary for TransformSummary {
139 type Context = ();
140
141 fn add_summary(&mut self, other: &Self, _: &()) {
142 self.buffer += &other.buffer;
143 self.display += &other.display;
144 }
145}
146
147impl<'a> sum_tree::Dimension<'a, TransformSummary> for TransformSummary {
148 fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
149 sum_tree::Summary::add_summary(self, summary, &());
150 }
151}