Track selection changes in mutable selections collection
This commit is contained in:
parent
42cd2ae142
commit
8e7c6871db
3 changed files with 47 additions and 49 deletions
|
@ -1401,12 +1401,14 @@ impl Editor {
|
||||||
let old_cursor_position = self.selections.newest_anchor().head();
|
let old_cursor_position = self.selections.newest_anchor().head();
|
||||||
self.push_to_selection_history();
|
self.push_to_selection_history();
|
||||||
|
|
||||||
let result = self.selections.change_with(cx, change);
|
let (changed, result) = self.selections.change_with(cx, change);
|
||||||
|
|
||||||
|
if changed {
|
||||||
if let Some(autoscroll) = autoscroll {
|
if let Some(autoscroll) = autoscroll {
|
||||||
self.request_autoscroll(autoscroll, cx);
|
self.request_autoscroll(autoscroll, cx);
|
||||||
}
|
}
|
||||||
self.selections_did_change(true, &old_cursor_position, cx);
|
self.selections_did_change(true, &old_cursor_position, cx);
|
||||||
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -4691,6 +4693,7 @@ impl Editor {
|
||||||
// Position the selection in the rename editor so that it matches the current selection.
|
// Position the selection in the rename editor so that it matches the current selection.
|
||||||
this.show_local_selections = false;
|
this.show_local_selections = false;
|
||||||
let rename_editor = cx.add_view(|cx| {
|
let rename_editor = cx.add_view(|cx| {
|
||||||
|
println!("Rename editor created.");
|
||||||
let mut editor = Editor::single_line(None, cx);
|
let mut editor = Editor::single_line(None, cx);
|
||||||
if let Some(old_highlight_id) = old_highlight_id {
|
if let Some(old_highlight_id) = old_highlight_id {
|
||||||
editor.override_text_style =
|
editor.override_text_style =
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct SelectionLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectionLayout {
|
impl SelectionLayout {
|
||||||
fn from<T: ToPoint + ToDisplayPoint + Clone>(
|
fn new<T: ToPoint + ToDisplayPoint + Clone>(
|
||||||
selection: Selection<T>,
|
selection: Selection<T>,
|
||||||
line_mode: bool,
|
line_mode: bool,
|
||||||
map: &DisplaySnapshot,
|
map: &DisplaySnapshot,
|
||||||
|
@ -977,7 +977,7 @@ impl Element for EditorElement {
|
||||||
remote_selections
|
remote_selections
|
||||||
.entry(replica_id)
|
.entry(replica_id)
|
||||||
.or_insert(Vec::new())
|
.or_insert(Vec::new())
|
||||||
.push(SelectionLayout::from(selection, line_mode, &display_map));
|
.push(SelectionLayout::new(selection, line_mode, &display_map));
|
||||||
}
|
}
|
||||||
selections.extend(remote_selections);
|
selections.extend(remote_selections);
|
||||||
|
|
||||||
|
@ -1007,11 +1007,7 @@ impl Element for EditorElement {
|
||||||
local_selections
|
local_selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| {
|
.map(|selection| {
|
||||||
SelectionLayout::from(
|
SelectionLayout::new(selection, view.selections.line_mode, &display_map)
|
||||||
selection,
|
|
||||||
view.selections.line_mode,
|
|
||||||
&display_map,
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
));
|
));
|
||||||
|
|
|
@ -289,9 +289,10 @@ impl SelectionsCollection {
|
||||||
&mut self,
|
&mut self,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
change: impl FnOnce(&mut MutableSelectionsCollection) -> R,
|
change: impl FnOnce(&mut MutableSelectionsCollection) -> R,
|
||||||
) -> R {
|
) -> (bool, R) {
|
||||||
let mut mutable_collection = MutableSelectionsCollection {
|
let mut mutable_collection = MutableSelectionsCollection {
|
||||||
collection: self,
|
collection: self,
|
||||||
|
selections_changed: false,
|
||||||
cx,
|
cx,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,12 +301,13 @@ impl SelectionsCollection {
|
||||||
!mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(),
|
!mutable_collection.disjoint.is_empty() || mutable_collection.pending.is_some(),
|
||||||
"There must be at least one selection"
|
"There must be at least one selection"
|
||||||
);
|
);
|
||||||
result
|
(mutable_collection.selections_changed, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MutableSelectionsCollection<'a> {
|
pub struct MutableSelectionsCollection<'a> {
|
||||||
collection: &'a mut SelectionsCollection,
|
collection: &'a mut SelectionsCollection,
|
||||||
|
selections_changed: bool,
|
||||||
cx: &'a mut MutableAppContext,
|
cx: &'a mut MutableAppContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,16 +325,26 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self, selection_id: usize) {
|
pub fn delete(&mut self, selection_id: usize) {
|
||||||
|
let mut changed = false;
|
||||||
self.collection.disjoint = self
|
self.collection.disjoint = self
|
||||||
.disjoint
|
.disjoint
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|selection| selection.id != selection_id)
|
.filter(|selection| {
|
||||||
|
let found = selection.id == selection_id;
|
||||||
|
changed |= found;
|
||||||
|
!found
|
||||||
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
self.selections_changed |= changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_pending(&mut self) {
|
pub fn clear_pending(&mut self) {
|
||||||
|
if self.collection.pending.is_some() {
|
||||||
self.collection.pending = None;
|
self.collection.pending = None;
|
||||||
|
self.selections_changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pending_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
|
pub fn set_pending_range(&mut self, range: Range<Anchor>, mode: SelectMode) {
|
||||||
|
@ -345,11 +357,13 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
goal: SelectionGoal::None,
|
goal: SelectionGoal::None,
|
||||||
},
|
},
|
||||||
mode,
|
mode,
|
||||||
})
|
});
|
||||||
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
|
pub fn set_pending(&mut self, selection: Selection<Anchor>, mode: SelectMode) {
|
||||||
self.collection.pending = Some(PendingSelection { selection, mode });
|
self.collection.pending = Some(PendingSelection { selection, mode });
|
||||||
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_cancel(&mut self) -> bool {
|
pub fn try_cancel(&mut self) -> bool {
|
||||||
|
@ -357,12 +371,14 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
if self.disjoint.is_empty() {
|
if self.disjoint.is_empty() {
|
||||||
self.collection.disjoint = Arc::from([pending.selection]);
|
self.collection.disjoint = Arc::from([pending.selection]);
|
||||||
}
|
}
|
||||||
|
self.selections_changed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut oldest = self.oldest_anchor().clone();
|
let mut oldest = self.oldest_anchor().clone();
|
||||||
if self.count() > 1 {
|
if self.count() > 1 {
|
||||||
self.collection.disjoint = Arc::from([oldest]);
|
self.collection.disjoint = Arc::from([oldest]);
|
||||||
|
self.selections_changed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,27 +387,13 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
oldest.start = head.clone();
|
oldest.start = head.clone();
|
||||||
oldest.end = head;
|
oldest.end = head;
|
||||||
self.collection.disjoint = Arc::from([oldest]);
|
self.collection.disjoint = Arc::from([oldest]);
|
||||||
|
self.selections_changed = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_biases(&mut self) {
|
|
||||||
let buffer = self.buffer.read(self.cx).snapshot(self.cx);
|
|
||||||
self.collection.disjoint = self
|
|
||||||
.collection
|
|
||||||
.disjoint
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.map(|selection| reset_biases(selection, &buffer))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(pending) = self.collection.pending.as_mut() {
|
|
||||||
pending.selection = reset_biases(pending.selection.clone(), &buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_range<T>(&mut self, range: Range<T>)
|
pub fn insert_range<T>(&mut self, range: Range<T>)
|
||||||
where
|
where
|
||||||
T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
|
T: 'a + ToOffset + ToPoint + TextDimension + Ord + Sub<T, Output = T> + std::marker::Copy,
|
||||||
|
@ -453,6 +455,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
self.collection.pending = None;
|
self.collection.pending = None;
|
||||||
|
self.selections_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
|
pub fn select_anchors(&mut self, selections: Vec<Selection<Anchor>>) {
|
||||||
|
@ -551,19 +554,28 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
|
mut move_selection: impl FnMut(&DisplaySnapshot, &mut Selection<DisplayPoint>),
|
||||||
) {
|
) {
|
||||||
|
let mut changed = false;
|
||||||
let display_map = self.display_map();
|
let display_map = self.display_map();
|
||||||
let selections = self
|
let selections = self
|
||||||
.all::<Point>(self.cx)
|
.all::<Point>(self.cx)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| {
|
.map(|selection| {
|
||||||
let mut selection = selection.map(|point| point.to_display_point(&display_map));
|
let mut moved_selection =
|
||||||
move_selection(&display_map, &mut selection);
|
selection.map(|point| point.to_display_point(&display_map));
|
||||||
selection.map(|display_point| display_point.to_point(&display_map))
|
move_selection(&display_map, &mut moved_selection);
|
||||||
|
let moved_selection =
|
||||||
|
moved_selection.map(|display_point| display_point.to_point(&display_map));
|
||||||
|
if selection != moved_selection {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
moved_selection
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
if changed {
|
||||||
self.select(selections)
|
self.select(selections)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn move_heads_with(
|
pub fn move_heads_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -686,6 +698,7 @@ impl<'a> MutableSelectionsCollection<'a> {
|
||||||
pending.selection.end = end;
|
pending.selection.end = end;
|
||||||
}
|
}
|
||||||
self.collection.pending = pending;
|
self.collection.pending = pending;
|
||||||
|
self.selections_changed = true;
|
||||||
|
|
||||||
selections_with_lost_position
|
selections_with_lost_position
|
||||||
}
|
}
|
||||||
|
@ -730,17 +743,3 @@ fn resolve<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||||
) -> Selection<D> {
|
) -> Selection<D> {
|
||||||
selection.map(|p| p.summary::<D>(&buffer))
|
selection.map(|p| p.summary::<D>(&buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_biases(
|
|
||||||
mut selection: Selection<Anchor>,
|
|
||||||
buffer: &MultiBufferSnapshot,
|
|
||||||
) -> Selection<Anchor> {
|
|
||||||
let end_bias = if selection.end.to_offset(buffer) > selection.start.to_offset(buffer) {
|
|
||||||
Bias::Left
|
|
||||||
} else {
|
|
||||||
Bias::Right
|
|
||||||
};
|
|
||||||
selection.start = buffer.anchor_after(selection.start);
|
|
||||||
selection.end = buffer.anchor_at(selection.end, end_bias);
|
|
||||||
selection
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue