Start tracking diffs in ScriptingSession
(#26463)
The diff is not exposed yet, but we'll take care of that next. Release Notes: - N/A
This commit is contained in:
parent
036c123488
commit
30afba50a9
5 changed files with 207 additions and 64 deletions
|
@ -37,7 +37,7 @@ use std::{
|
|||
};
|
||||
pub use subscription::*;
|
||||
pub use sum_tree::Bias;
|
||||
use sum_tree::{FilterCursor, SumTree, TreeMap};
|
||||
use sum_tree::{FilterCursor, SumTree, TreeMap, TreeSet};
|
||||
use undo_map::UndoMap;
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
@ -110,6 +110,7 @@ pub struct BufferSnapshot {
|
|||
undo_map: UndoMap,
|
||||
fragments: SumTree<Fragment>,
|
||||
insertions: SumTree<InsertionFragment>,
|
||||
insertion_slices: TreeSet<InsertionSlice>,
|
||||
pub version: clock::Global,
|
||||
}
|
||||
|
||||
|
@ -137,25 +138,50 @@ impl HistoryEntry {
|
|||
struct History {
|
||||
base_text: Rope,
|
||||
operations: TreeMap<clock::Lamport, Operation>,
|
||||
insertion_slices: HashMap<clock::Lamport, Vec<InsertionSlice>>,
|
||||
undo_stack: Vec<HistoryEntry>,
|
||||
redo_stack: Vec<HistoryEntry>,
|
||||
transaction_depth: usize,
|
||||
group_interval: Duration,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
struct InsertionSlice {
|
||||
edit_id: clock::Lamport,
|
||||
insertion_id: clock::Lamport,
|
||||
range: Range<usize>,
|
||||
}
|
||||
|
||||
impl Ord for InsertionSlice {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.edit_id
|
||||
.cmp(&other.edit_id)
|
||||
.then_with(|| self.insertion_id.cmp(&other.insertion_id))
|
||||
.then_with(|| self.range.start.cmp(&other.range.start))
|
||||
.then_with(|| self.range.end.cmp(&other.range.end))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for InsertionSlice {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl InsertionSlice {
|
||||
fn from_fragment(edit_id: clock::Lamport, fragment: &Fragment) -> Self {
|
||||
Self {
|
||||
edit_id,
|
||||
insertion_id: fragment.timestamp,
|
||||
range: fragment.insertion_offset..fragment.insertion_offset + fragment.len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl History {
|
||||
pub fn new(base_text: Rope) -> Self {
|
||||
Self {
|
||||
base_text,
|
||||
operations: Default::default(),
|
||||
insertion_slices: Default::default(),
|
||||
undo_stack: Vec::new(),
|
||||
redo_stack: Vec::new(),
|
||||
transaction_depth: 0,
|
||||
|
@ -696,6 +722,7 @@ impl Buffer {
|
|||
insertions,
|
||||
version,
|
||||
undo_map: Default::default(),
|
||||
insertion_slices: Default::default(),
|
||||
},
|
||||
history,
|
||||
deferred_ops: OperationQueue::new(),
|
||||
|
@ -857,7 +884,7 @@ impl Buffer {
|
|||
old: fragment_start..fragment_start,
|
||||
new: new_start..new_start + new_text.len(),
|
||||
});
|
||||
insertion_slices.push(fragment.insertion_slice());
|
||||
insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
|
||||
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
||||
new_ropes.push_str(new_text.as_ref());
|
||||
new_fragments.push(fragment, &None);
|
||||
|
@ -886,7 +913,8 @@ impl Buffer {
|
|||
old: fragment_start..intersection_end,
|
||||
new: new_start..new_start,
|
||||
});
|
||||
insertion_slices.push(intersection.insertion_slice());
|
||||
insertion_slices
|
||||
.push(InsertionSlice::from_fragment(timestamp, &intersection));
|
||||
}
|
||||
new_insertions.push(InsertionFragment::insert_new(&intersection));
|
||||
new_ropes.push_fragment(&intersection, fragment.visible);
|
||||
|
@ -929,9 +957,7 @@ impl Buffer {
|
|||
self.snapshot.visible_text = visible_text;
|
||||
self.snapshot.deleted_text = deleted_text;
|
||||
self.subscriptions.publish_mut(&edits_patch);
|
||||
self.history
|
||||
.insertion_slices
|
||||
.insert(timestamp, insertion_slices);
|
||||
self.snapshot.insertion_slices.extend(insertion_slices);
|
||||
edit_op
|
||||
}
|
||||
|
||||
|
@ -1107,7 +1133,7 @@ impl Buffer {
|
|||
old: old_start..old_start,
|
||||
new: new_start..new_start + new_text.len(),
|
||||
});
|
||||
insertion_slices.push(fragment.insertion_slice());
|
||||
insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
|
||||
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
||||
new_ropes.push_str(new_text);
|
||||
new_fragments.push(fragment, &None);
|
||||
|
@ -1129,7 +1155,7 @@ impl Buffer {
|
|||
Locator::between(&new_fragments.summary().max_id, &intersection.id);
|
||||
intersection.deletions.insert(timestamp);
|
||||
intersection.visible = false;
|
||||
insertion_slices.push(intersection.insertion_slice());
|
||||
insertion_slices.push(InsertionSlice::from_fragment(timestamp, &intersection));
|
||||
}
|
||||
if intersection.len > 0 {
|
||||
if fragment.visible && !intersection.visible {
|
||||
|
@ -1177,9 +1203,7 @@ impl Buffer {
|
|||
self.snapshot.visible_text = visible_text;
|
||||
self.snapshot.deleted_text = deleted_text;
|
||||
self.snapshot.insertions.edit(new_insertions, &());
|
||||
self.history
|
||||
.insertion_slices
|
||||
.insert(timestamp, insertion_slices);
|
||||
self.snapshot.insertion_slices.extend(insertion_slices);
|
||||
self.subscriptions.publish_mut(&edits_patch)
|
||||
}
|
||||
|
||||
|
@ -1190,9 +1214,17 @@ impl Buffer {
|
|||
// Get all of the insertion slices changed by the given edits.
|
||||
let mut insertion_slices = Vec::new();
|
||||
for edit_id in edit_ids {
|
||||
if let Some(slices) = self.history.insertion_slices.get(edit_id) {
|
||||
insertion_slices.extend_from_slice(slices)
|
||||
}
|
||||
let insertion_slice = InsertionSlice {
|
||||
edit_id: *edit_id,
|
||||
insertion_id: clock::Lamport::default(),
|
||||
range: 0..0,
|
||||
};
|
||||
let slices = self
|
||||
.snapshot
|
||||
.insertion_slices
|
||||
.iter_from(&insertion_slice)
|
||||
.take_while(|slice| slice.edit_id == *edit_id);
|
||||
insertion_slices.extend(slices)
|
||||
}
|
||||
insertion_slices
|
||||
.sort_unstable_by_key(|s| (s.insertion_id, s.range.start, Reverse(s.range.end)));
|
||||
|
@ -2639,13 +2671,6 @@ impl<D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator for Ed
|
|||
}
|
||||
|
||||
impl Fragment {
|
||||
fn insertion_slice(&self) -> InsertionSlice {
|
||||
InsertionSlice {
|
||||
insertion_id: self.timestamp,
|
||||
range: self.insertion_offset..self.insertion_offset + self.len,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_visible(&self, undos: &UndoMap) -> bool {
|
||||
!undos.is_undone(self.timestamp) && self.deletions.iter().all(|d| undos.is_undone(*d))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue