This commit is contained in:
Nathan Sobo 2021-07-20 17:22:03 -06:00
parent 07e97e6cad
commit b513df3844

View file

@ -2,12 +2,12 @@ use super::tab_map::{
self, Edit as InputEdit, OutputPoint as InputPoint, Snapshot as InputSnapshot, TextSummary,
};
use crate::{
editor::Point,
editor::{Editor, Point},
sum_tree::{self, Cursor, SumTree},
util::Bias,
Settings,
};
use gpui::{AppContext, FontCache, FontSystem, Task};
use gpui::{AppContext, FontCache, FontSystem, Task, ViewContext};
use parking_lot::Mutex;
use postage::{
prelude::{Sink, Stream},
@ -212,7 +212,7 @@ struct State {
pub struct WrapMap {
state: Mutex<State>,
edits_tx: channel::Sender<(InputSnapshot, Vec<InputEdit>)>,
background_changes_tx: channel::Sender<Change>,
background_snapshot: watch::Receiver<Snapshot>,
_background_task: Task<()>,
}
@ -222,7 +222,7 @@ impl WrapMap {
input: InputSnapshot,
settings: Settings,
wrap_width: Option<f32>,
cx: &AppContext,
cx: &mut ViewContext<Editor>,
) -> Self {
let font_cache = cx.font_cache().clone();
let font_system = cx.platform().fonts();
@ -244,36 +244,46 @@ impl WrapMap {
snapshot,
pending_edits: VecDeque::new(),
}),
edits_tx,
background_changes_tx: edits_tx,
background_snapshot: background_snapshot_rx,
_background_task: background_task,
}
}
pub fn sync(&self, input: InputSnapshot, edits: Vec<InputEdit>, cx: &AppContext) -> Snapshot {
self.edits_tx
.try_send((input.clone(), edits.clone()))
.unwrap();
let mut snapshot = self.state.lock().snapshot.clone();
let mut background_snapshot = self.background_snapshot.clone();
cx.background().block_on(Duration::from_millis(5), async {
loop {
snapshot = background_snapshot.recv().await.unwrap();
if snapshot.input.version() == input.version() {
break;
let mut snapshot = self.background_snapshot.borrow().clone();
if !edits.is_empty() {
self.background_changes_tx
.try_send(Change::Input {
snapshot: input.clone(),
edits: edits.clone(),
})
.unwrap();
cx.background().block_on(Duration::from_millis(5), async {
loop {
snapshot = background_snapshot.recv().await.unwrap();
if snapshot.input.version() == input.version() {
break;
}
}
}
});
});
}
let mut state = &mut *self.state.lock();
state.snapshot = snapshot;
state.pending_edits.push_back((input, edits));
while state.pending_edits.front().map_or(false, |(input, _)| {
input.version() <= state.snapshot.input.version()
}) {
state.pending_edits.pop_front();
while let Some((pending_input, _)) = state.pending_edits.front() {
if pending_input.version() <= state.snapshot.input.version() {
state.pending_edits.pop_front();
} else {
break;
}
}
for (input, edits) in &state.pending_edits {
state.snapshot.interpolate(input.clone(), &edits);
}
@ -281,7 +291,9 @@ impl WrapMap {
}
pub fn set_wrap_width(&self, width: Option<f32>) {
todo!()
self.background_changes_tx
.try_send(Change::Width(width))
.unwrap();
}
}
@ -293,12 +305,12 @@ struct BackgroundWrapper {
snapshot: Snapshot,
}
enum WrapChange {
InputChange {
enum Change {
Input {
snapshot: InputSnapshot,
edits: Vec<tab_map::Edit>,
},
WidthChange(Option<f32>),
Width(Option<f32>),
}
impl BackgroundWrapper {
@ -320,21 +332,36 @@ impl BackgroundWrapper {
async fn run(
&mut self,
snapshot: InputSnapshot,
edits_rx: channel::Receiver<WrapChange>,
input: InputSnapshot,
edits_rx: channel::Receiver<Change>,
mut snapshot_tx: watch::Sender<Snapshot>,
) {
let edit = InputEdit {
old_lines: Default::default()..snapshot.max_point(),
new_lines: Default::default()..snapshot.max_point(),
old_lines: Default::default()..input.max_point(),
new_lines: Default::default()..input.max_point(),
};
self.sync(snapshot, vec![edit]);
self.sync(input, vec![edit]);
if snapshot_tx.send(self.snapshot.clone()).await.is_err() {
return;
}
while let Ok((snapshot, edits)) = edits_rx.recv().await {
self.sync(snapshot, edits);
while let Ok(change) = edits_rx.recv().await {
match change {
Change::Input { snapshot, edits } => self.sync(snapshot, edits),
Change::Width(wrap_width) => {
if self.wrap_width == wrap_width {
continue;
} else {
self.wrap_width = wrap_width;
let input = self.snapshot.input.clone();
let edit = InputEdit {
old_lines: Default::default()..input.max_point(),
new_lines: Default::default()..input.max_point(),
};
self.sync(input, vec![edit])
}
}
};
if snapshot_tx.send(self.snapshot.clone()).await.is_err() {
break;
}