More messy progress towards selections in editors
This commit is contained in:
parent
0639c8331c
commit
4dd0752e80
11 changed files with 298 additions and 479 deletions
|
@ -1,10 +1,6 @@
|
|||
use crate::Anchor;
|
||||
use crate::{rope::TextDimension, BufferSnapshot, ToOffset, ToPoint};
|
||||
use std::{cmp::Ordering, ops::Range, sync::Arc};
|
||||
use sum_tree::Bias;
|
||||
|
||||
pub type SelectionSetId = clock::Lamport;
|
||||
pub type SelectionsVersion = usize;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum SelectionGoal {
|
||||
|
@ -22,20 +18,6 @@ pub struct Selection<T> {
|
|||
pub goal: SelectionGoal,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct SelectionSet {
|
||||
pub id: SelectionSetId,
|
||||
pub active: bool,
|
||||
pub selections: Arc<[Selection<Anchor>]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct SelectionState {
|
||||
pub id: usize,
|
||||
pub reversed: bool,
|
||||
pub goal: SelectionGoal,
|
||||
}
|
||||
|
||||
impl<T: Clone> Selection<T> {
|
||||
pub fn head(&self) -> T {
|
||||
if self.reversed {
|
||||
|
@ -90,78 +72,3 @@ impl Selection<Anchor> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SelectionSet {
|
||||
pub fn len(&self) -> usize {
|
||||
self.selections.len()
|
||||
}
|
||||
|
||||
pub fn selections<'a, D>(
|
||||
&'a self,
|
||||
snapshot: &'a BufferSnapshot,
|
||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
||||
where
|
||||
D: TextDimension,
|
||||
{
|
||||
let anchors = self
|
||||
.selections
|
||||
.iter()
|
||||
.flat_map(|selection| [&selection.start, &selection.end].into_iter());
|
||||
let mut positions = snapshot.summaries_for_anchors::<D, _>(anchors);
|
||||
self.selections.iter().map(move |selection| Selection {
|
||||
start: positions.next().unwrap(),
|
||||
end: positions.next().unwrap(),
|
||||
goal: selection.goal,
|
||||
reversed: selection.reversed,
|
||||
id: selection.id,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn intersecting_selections<'a, D, I>(
|
||||
&'a self,
|
||||
range: Range<(I, Bias)>,
|
||||
snapshot: &'a BufferSnapshot,
|
||||
) -> impl 'a + Iterator<Item = Selection<D>>
|
||||
where
|
||||
D: TextDimension,
|
||||
I: 'a + ToOffset,
|
||||
{
|
||||
let start = snapshot.anchor_at(range.start.0, range.start.1);
|
||||
let end = snapshot.anchor_at(range.end.0, range.end.1);
|
||||
let start_ix = match self
|
||||
.selections
|
||||
.binary_search_by(|probe| probe.end.cmp(&start, snapshot).unwrap())
|
||||
{
|
||||
Ok(ix) | Err(ix) => ix,
|
||||
};
|
||||
let end_ix = match self
|
||||
.selections
|
||||
.binary_search_by(|probe| probe.start.cmp(&end, snapshot).unwrap())
|
||||
{
|
||||
Ok(ix) | Err(ix) => ix,
|
||||
};
|
||||
self.selections[start_ix..end_ix]
|
||||
.iter()
|
||||
.map(|s| s.resolve(snapshot))
|
||||
}
|
||||
|
||||
pub fn oldest_selection<'a, D>(&'a self, snapshot: &'a BufferSnapshot) -> Option<Selection<D>>
|
||||
where
|
||||
D: TextDimension,
|
||||
{
|
||||
self.selections
|
||||
.iter()
|
||||
.min_by_key(|s| s.id)
|
||||
.map(|s| s.resolve(snapshot))
|
||||
}
|
||||
|
||||
pub fn newest_selection<'a, D>(&'a self, snapshot: &'a BufferSnapshot) -> Option<Selection<D>>
|
||||
where
|
||||
D: TextDimension,
|
||||
{
|
||||
self.selections
|
||||
.iter()
|
||||
.max_by_key(|s| s.id)
|
||||
.map(|s| s.resolve(snapshot))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ pub struct Buffer {
|
|||
snapshot: BufferSnapshot,
|
||||
last_edit: clock::Local,
|
||||
history: History,
|
||||
selection_sets: HashMap<SelectionSetId, SelectionSet>,
|
||||
deferred_ops: OperationQueue<Operation>,
|
||||
deferred_replicas: HashSet<ReplicaId>,
|
||||
replica_id: ReplicaId,
|
||||
|
@ -413,19 +412,6 @@ pub enum Operation {
|
|||
undo: UndoOperation,
|
||||
lamport_timestamp: clock::Lamport,
|
||||
},
|
||||
UpdateSelections {
|
||||
set_id: SelectionSetId,
|
||||
selections: Arc<[Selection<Anchor>]>,
|
||||
lamport_timestamp: clock::Lamport,
|
||||
},
|
||||
RemoveSelections {
|
||||
set_id: SelectionSetId,
|
||||
lamport_timestamp: clock::Lamport,
|
||||
},
|
||||
SetActiveSelections {
|
||||
set_id: Option<SelectionSetId>,
|
||||
lamport_timestamp: clock::Lamport,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -487,7 +473,6 @@ impl Buffer {
|
|||
},
|
||||
last_edit: clock::Local::default(),
|
||||
history,
|
||||
selection_sets: Default::default(),
|
||||
deferred_ops: OperationQueue::new(),
|
||||
deferred_replicas: HashSet::default(),
|
||||
replica_id,
|
||||
|
@ -514,6 +499,10 @@ impl Buffer {
|
|||
self.lamport_clock
|
||||
}
|
||||
|
||||
pub fn observe_lamport_timestamp(&mut self, timestamp: clock::Lamport) {
|
||||
self.lamport_clock.observe(timestamp);
|
||||
}
|
||||
|
||||
pub fn remote_id(&self) -> u64 {
|
||||
self.remote_id
|
||||
}
|
||||
|
@ -754,47 +743,6 @@ impl Buffer {
|
|||
self.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
}
|
||||
Operation::UpdateSelections {
|
||||
set_id,
|
||||
selections,
|
||||
lamport_timestamp,
|
||||
} => {
|
||||
if let Some(set) = self.selection_sets.get_mut(&set_id) {
|
||||
set.selections = selections;
|
||||
} else {
|
||||
self.selection_sets.insert(
|
||||
set_id,
|
||||
SelectionSet {
|
||||
id: set_id,
|
||||
selections,
|
||||
active: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
self.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
Operation::RemoveSelections {
|
||||
set_id,
|
||||
lamport_timestamp,
|
||||
} => {
|
||||
self.selection_sets.remove(&set_id);
|
||||
self.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
Operation::SetActiveSelections {
|
||||
set_id,
|
||||
lamport_timestamp,
|
||||
} => {
|
||||
for (id, set) in &mut self.selection_sets {
|
||||
if id.replica_id == lamport_timestamp.replica_id {
|
||||
if Some(*id) == set_id {
|
||||
set.active = true;
|
||||
} else {
|
||||
set.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.lamport_clock.observe(lamport_timestamp);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1107,13 +1055,6 @@ impl Buffer {
|
|||
match op {
|
||||
Operation::Edit(edit) => self.version.ge(&edit.version),
|
||||
Operation::Undo { undo, .. } => self.version.ge(&undo.version),
|
||||
Operation::UpdateSelections { selections, .. } => selections
|
||||
.iter()
|
||||
.all(|s| self.can_resolve(&s.start) && self.can_resolve(&s.end)),
|
||||
Operation::RemoveSelections { .. } => true,
|
||||
Operation::SetActiveSelections { set_id, .. } => {
|
||||
set_id.map_or(true, |set_id| self.selection_sets.contains_key(&set_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1151,11 +1092,6 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_peer(&mut self, replica_id: ReplicaId) {
|
||||
self.selection_sets
|
||||
.retain(|set_id, _| set_id.replica_id != replica_id)
|
||||
}
|
||||
|
||||
pub fn base_text(&self) -> &Arc<str> {
|
||||
&self.history.base_text
|
||||
}
|
||||
|
@ -2007,15 +1943,6 @@ impl operation_queue::Operation for Operation {
|
|||
Operation::Undo {
|
||||
lamport_timestamp, ..
|
||||
} => *lamport_timestamp,
|
||||
Operation::UpdateSelections {
|
||||
lamport_timestamp, ..
|
||||
} => *lamport_timestamp,
|
||||
Operation::RemoveSelections {
|
||||
lamport_timestamp, ..
|
||||
} => *lamport_timestamp,
|
||||
Operation::SetActiveSelections {
|
||||
lamport_timestamp, ..
|
||||
} => *lamport_timestamp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue