diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 537c4f8ee8973820971f359810d323c9c4f79215..7497e477b64236313ab62ad290c23b26efd47f8a 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -1,3 +1,4 @@ +mod block_map; mod fold_map; mod injection_map; mod tab_map; diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs new file mode 100644 index 0000000000000000000000000000000000000000..44355adc6927684c5e73c96e6838cb31880eb69d --- /dev/null +++ b/crates/editor/src/display_map/block_map.rs @@ -0,0 +1,142 @@ +use std::cmp; + +use super::wrap_map::{Edit as WrapEdit, Snapshot as WrapSnapshot}; +use buffer::Bias; +use parking_lot::Mutex; +use sum_tree::SumTree; + +struct BlockMap { + transforms: Mutex>, +} + +struct BlockMapWriter<'a>(&'a mut BlockMap); + +struct BlockSnapshot {} + +#[derive(Clone)] +struct Transform { + summary: TransformSummary, +} + +#[derive(Copy, Clone, Debug, Default)] +struct TransformSummary { + input_rows: u32, + output_rows: u32, +} + +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)] +struct InputRow(u32); + +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)] +struct OutputRow(u32); + +impl BlockMap { + fn new(wrap_snapshot: WrapSnapshot) -> Self { + Self { + transforms: Mutex::new(SumTree::from_item( + Transform::isomorphic(wrap_snapshot.max_point().row() + 1), + &(), + )), + } + } + + fn read(&self, wrap_snapshot: WrapSnapshot, edits: Vec) -> BlockSnapshot { + self.sync(wrap_snapshot, edits); + BlockSnapshot {} + } + + fn write(&mut self, wrap_snapshot: WrapSnapshot, edits: Vec) -> BlockMapWriter { + self.sync(wrap_snapshot, edits); + BlockMapWriter(self) + } + + fn sync(&self, wrap_snapshot: WrapSnapshot, edits: Vec) { + let transforms = self.transforms.lock(); + let mut new_transforms = SumTree::new(); + let mut cursor = transforms.cursor::(); + let mut edits = edits.into_iter().peekable(); + while let Some(mut edit) = edits.next() { + new_transforms.push_tree( + cursor.slice(&InputRow(edit.old.start), Bias::Left, &()), + &(), + ); + + let transform_start = cursor.start().0; + edit.new.start -= edit.old.start - transform_start; + edit.old.start = transform_start; + + loop { + if edit.old.end > cursor.start().0 { + cursor.seek(&InputRow(edit.old.end), Bias::Left, &()); + cursor.next(&()); + let transform_end = cursor.start().0; + edit.new.end += transform_end - edit.old.end; + edit.old.end = transform_end; + } + + if let Some(next_edit) = edits.peek() { + if edit.old.end >= next_edit.old.start { + edit.old.end = cmp::max(next_edit.old.end, edit.old.end); + edit.new.end += (edit.new.len() as i32 - edit.old.len() as i32) as u32; + edits.next(); + } else { + break; + } + } else { + break; + } + } + + // TODO: process injections + + let new_transforms_end = new_transforms.summary().input_rows; + if new_transforms_end < edit.new.end { + new_transforms.push( + Transform::isomorphic(edit.new.end - new_transforms_end), + &(), + ); + } + } + new_transforms.push_tree(cursor.suffix(&()), &()); + } +} + +impl Transform { + fn isomorphic(rows: u32) -> Self { + Self { + summary: TransformSummary { + input_rows: rows, + output_rows: rows, + }, + } + } +} + +impl sum_tree::Item for Transform { + type Summary = TransformSummary; + + fn summary(&self) -> Self::Summary { + self.summary + } +} + +impl sum_tree::Summary for TransformSummary { + type Context = (); + + fn add_summary(&mut self, summary: &Self, _: &()) { + self.input_rows += summary.input_rows; + self.output_rows += summary.output_rows; + } +} + +impl<'a> sum_tree::Dimension<'a, TransformSummary> for InputRow { + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { + self.0 += summary.input_rows; + } +} + +impl<'a> sum_tree::Dimension<'a, TransformSummary> for OutputRow { + fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { + self.0 += summary.output_rows; + } +} diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index a62c67dbce5b4d3654015f7d060645462b383b47..5991d060a0b48727d9b0a3a97751426a5d961b62 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -9,6 +9,8 @@ use smol::future::yield_now; use std::{collections::VecDeque, ops::Range, time::Duration}; use sum_tree::{Bias, Cursor, SumTree}; +pub type Edit = buffer::Edit; + pub struct WrapMap { snapshot: Snapshot, pending_edits: VecDeque<(TabSnapshot, Vec)>,