editor: Fix unwrap_syntax_node panicking by not setting selections (#38329)
Fixes ZED-11T Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -477,7 +477,7 @@ impl TextThreadEditor {
|
||||
return;
|
||||
}
|
||||
|
||||
let selections = self.editor.read(cx).selections.disjoint_anchors();
|
||||
let selections = self.editor.read(cx).selections.disjoint_anchors_arc();
|
||||
let mut commands_by_range = HashMap::default();
|
||||
let workspace = self.workspace.clone();
|
||||
self.context.update(cx, |context, cx| {
|
||||
@@ -1823,7 +1823,7 @@ impl TextThreadEditor {
|
||||
|
||||
fn split(&mut self, _: &Split, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.context.update(cx, |context, cx| {
|
||||
let selections = self.editor.read(cx).selections.disjoint_anchors();
|
||||
let selections = self.editor.read(cx).selections.disjoint_anchors_arc();
|
||||
for selection in selections.as_ref() {
|
||||
let buffer = self.editor.read(cx).buffer().read(cx).snapshot(cx);
|
||||
let range = selection
|
||||
|
||||
+52
-38
@@ -2414,14 +2414,10 @@ impl Editor {
|
||||
pub fn is_range_selected(&mut self, range: &Range<Anchor>, cx: &mut Context<Self>) -> bool {
|
||||
if self
|
||||
.selections
|
||||
.pending
|
||||
.as_ref()
|
||||
.pending_anchor()
|
||||
.is_some_and(|pending_selection| {
|
||||
let snapshot = self.buffer().read(cx).snapshot(cx);
|
||||
pending_selection
|
||||
.selection
|
||||
.range()
|
||||
.includes(range, &snapshot)
|
||||
pending_selection.range().includes(range, &snapshot)
|
||||
})
|
||||
{
|
||||
return true;
|
||||
@@ -3054,7 +3050,7 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
let selection_anchors = self.selections.disjoint_anchors();
|
||||
let selection_anchors = self.selections.disjoint_anchors_arc();
|
||||
|
||||
if self.focus_handle.is_focused(window) && self.leader_id.is_none() {
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
@@ -3170,7 +3166,7 @@ impl Editor {
|
||||
self.blink_manager.update(cx, BlinkManager::pause_blinking);
|
||||
cx.emit(EditorEvent::SelectionsChanged { local });
|
||||
|
||||
let selections = &self.selections.disjoint;
|
||||
let selections = &self.selections.disjoint_anchors_arc();
|
||||
if selections.len() == 1 {
|
||||
cx.emit(SearchEvent::ActiveMatchChanged)
|
||||
}
|
||||
@@ -3282,14 +3278,14 @@ impl Editor {
|
||||
other: Entity<Editor>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> gpui::Subscription {
|
||||
let other_selections = other.read(cx).selections.disjoint.to_vec();
|
||||
let other_selections = other.read(cx).selections.disjoint_anchors().to_vec();
|
||||
self.selections.change_with(cx, |selections| {
|
||||
selections.select_anchors(other_selections);
|
||||
});
|
||||
|
||||
let other_subscription = cx.subscribe(&other, |this, other, other_evt, cx| {
|
||||
if let EditorEvent::SelectionsChanged { local: true } = other_evt {
|
||||
let other_selections = other.read(cx).selections.disjoint.to_vec();
|
||||
let other_selections = other.read(cx).selections.disjoint_anchors().to_vec();
|
||||
if other_selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
@@ -3301,7 +3297,7 @@ impl Editor {
|
||||
|
||||
let this_subscription = cx.subscribe_self::<EditorEvent>(move |this, this_evt, cx| {
|
||||
if let EditorEvent::SelectionsChanged { local: true } = this_evt {
|
||||
let these_selections = this.selections.disjoint.to_vec();
|
||||
let these_selections = this.selections.disjoint_anchors().to_vec();
|
||||
if these_selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
@@ -3339,7 +3335,7 @@ impl Editor {
|
||||
effects,
|
||||
old_cursor_position: self.selections.newest_anchor().head(),
|
||||
history_entry: SelectionHistoryEntry {
|
||||
selections: self.selections.disjoint_anchors(),
|
||||
selections: self.selections.disjoint_anchors_arc(),
|
||||
select_next_state: self.select_next_state.clone(),
|
||||
select_prev_state: self.select_prev_state.clone(),
|
||||
add_selections_state: self.add_selections_state.clone(),
|
||||
@@ -3499,6 +3495,7 @@ impl Editor {
|
||||
let mut pending_selection = self
|
||||
.selections
|
||||
.pending_anchor()
|
||||
.cloned()
|
||||
.expect("extend_selection not called with pending selection");
|
||||
if position >= tail {
|
||||
pending_selection.start = tail_anchor;
|
||||
@@ -3520,7 +3517,7 @@ impl Editor {
|
||||
};
|
||||
|
||||
self.change_selections(effects, window, cx, |s| {
|
||||
s.set_pending(pending_selection, pending_mode)
|
||||
s.set_pending(pending_selection.clone(), pending_mode)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3595,7 +3592,7 @@ impl Editor {
|
||||
Some(selected_points[0].id)
|
||||
} else {
|
||||
let clicked_point_already_selected =
|
||||
self.selections.disjoint.iter().find(|selection| {
|
||||
self.selections.disjoint_anchors().iter().find(|selection| {
|
||||
selection.start.to_point(buffer) == start.to_point(buffer)
|
||||
|| selection.end.to_point(buffer) == end.to_point(buffer)
|
||||
});
|
||||
@@ -3700,7 +3697,7 @@ impl Editor {
|
||||
|
||||
if self.columnar_selection_state.is_some() {
|
||||
self.select_columns(position, goal_column, &display_map, window, cx);
|
||||
} else if let Some(mut pending) = self.selections.pending_anchor() {
|
||||
} else if let Some(mut pending) = self.selections.pending_anchor().cloned() {
|
||||
let buffer = &display_map.buffer_snapshot;
|
||||
let head;
|
||||
let tail;
|
||||
@@ -3776,7 +3773,7 @@ impl Editor {
|
||||
}
|
||||
|
||||
self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
|
||||
s.set_pending(pending, mode);
|
||||
s.set_pending(pending.clone(), mode);
|
||||
});
|
||||
} else {
|
||||
log::error!("update_selection dispatched with no pending selection");
|
||||
@@ -3885,7 +3882,8 @@ impl Editor {
|
||||
};
|
||||
|
||||
pending_nonempty_selection
|
||||
|| (self.columnar_selection_state.is_some() && self.selections.disjoint.len() > 1)
|
||||
|| (self.columnar_selection_state.is_some()
|
||||
&& self.selections.disjoint_anchors().len() > 1)
|
||||
}
|
||||
|
||||
pub fn has_pending_selection(&self) -> bool {
|
||||
@@ -6065,7 +6063,7 @@ impl Editor {
|
||||
|
||||
editor.refresh_edit_prediction(true, false, window, cx);
|
||||
});
|
||||
self.invalidate_autoclose_regions(&self.selections.disjoint_anchors(), &snapshot);
|
||||
self.invalidate_autoclose_regions(&self.selections.disjoint_anchors_arc(), &snapshot);
|
||||
|
||||
let show_new_completions_on_confirm = completion
|
||||
.confirm
|
||||
@@ -7472,7 +7470,7 @@ impl Editor {
|
||||
s.select_anchor_ranges([last_edit_end..last_edit_end]);
|
||||
});
|
||||
|
||||
let selections = self.selections.disjoint_anchors();
|
||||
let selections = self.selections.disjoint_anchors_arc();
|
||||
if let Some(transaction_id_now) = self.buffer.read(cx).last_transaction_id(cx) {
|
||||
let has_new_transaction = transaction_id_prev != Some(transaction_id_now);
|
||||
if has_new_transaction {
|
||||
@@ -7717,7 +7715,7 @@ impl Editor {
|
||||
let Some(mode) = Self::columnar_selection_mode(modifiers, cx) else {
|
||||
return;
|
||||
};
|
||||
if self.selections.pending.is_none() {
|
||||
if self.selections.pending_anchor().is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10517,7 +10515,7 @@ impl Editor {
|
||||
|
||||
fn enable_wrap_selections_in_tag(&self, cx: &App) -> bool {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
for selection in self.selections.disjoint_anchors().iter() {
|
||||
for selection in self.selections.disjoint_anchors_arc().iter() {
|
||||
if snapshot
|
||||
.language_at(selection.start)
|
||||
.and_then(|lang| lang.config().wrap_characters.as_ref())
|
||||
@@ -10851,7 +10849,7 @@ impl Editor {
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let cursors = self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
let cursor_position: Point = selection.head().to_point(&snapshot.buffer_snapshot);
|
||||
@@ -14542,7 +14540,7 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<()> {
|
||||
let selections = self.selections.disjoint_anchors();
|
||||
let selections = self.selections.disjoint_anchors_arc();
|
||||
match selections.first() {
|
||||
Some(first) if selections.len() >= 2 => {
|
||||
self.change_selections(Default::default(), window, cx, |s| {
|
||||
@@ -14566,7 +14564,7 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Result<()> {
|
||||
let selections = self.selections.disjoint_anchors();
|
||||
let selections = self.selections.disjoint_anchors_arc();
|
||||
match selections.last() {
|
||||
Some(last) if selections.len() >= 2 => {
|
||||
self.change_selections(Default::default(), window, cx, |s| {
|
||||
@@ -15123,11 +15121,9 @@ impl Editor {
|
||||
let full_edits = selections
|
||||
.into_iter()
|
||||
.filter_map(|selection| {
|
||||
// Only requires two branches once if-let-chains stabilize (#53667)
|
||||
let child = if !selection.is_empty() {
|
||||
selection.range()
|
||||
} else if let Some((_, ancestor_range)) =
|
||||
buffer.syntax_ancestor(selection.start..selection.end)
|
||||
let child = if selection.is_empty()
|
||||
&& let Some((_, ancestor_range)) =
|
||||
buffer.syntax_ancestor(selection.start..selection.end)
|
||||
{
|
||||
match ancestor_range {
|
||||
MultiOrSingleBufferOffsetRange::Single(range) => range,
|
||||
@@ -15155,6 +15151,9 @@ impl Editor {
|
||||
Some((selection.id, parent, text))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
if full_edits.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
this.buffer.update(cx, |buffer, cx| {
|
||||
@@ -15663,7 +15662,7 @@ impl Editor {
|
||||
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selections = self.selections.disjoint_anchors();
|
||||
let selections = self.selections.disjoint_anchors_arc();
|
||||
|
||||
let lines = if lines == 0 {
|
||||
EditorSettings::get_global(cx).expand_excerpt_lines
|
||||
@@ -17122,7 +17121,7 @@ impl Editor {
|
||||
.transaction(transaction_id_prev)
|
||||
.map(|t| t.0.clone())
|
||||
})
|
||||
.unwrap_or_else(|| self.selections.disjoint_anchors());
|
||||
.unwrap_or_else(|| self.selections.disjoint_anchors_arc());
|
||||
|
||||
let mut timeout = cx.background_executor().timer(FORMAT_TIMEOUT).fuse();
|
||||
let format = project.update(cx, |project, cx| {
|
||||
@@ -17662,7 +17661,7 @@ impl Editor {
|
||||
.update(cx, |buffer, cx| buffer.start_transaction_at(now, cx))
|
||||
{
|
||||
self.selection_history
|
||||
.insert_transaction(tx_id, self.selections.disjoint_anchors());
|
||||
.insert_transaction(tx_id, self.selections.disjoint_anchors_arc());
|
||||
cx.emit(EditorEvent::TransactionBegun {
|
||||
transaction_id: tx_id,
|
||||
});
|
||||
@@ -17684,7 +17683,7 @@ impl Editor {
|
||||
if let Some((_, end_selections)) =
|
||||
self.selection_history.transaction_mut(transaction_id)
|
||||
{
|
||||
*end_selections = Some(self.selections.disjoint_anchors());
|
||||
*end_selections = Some(self.selections.disjoint_anchors_arc());
|
||||
} else {
|
||||
log::error!("unexpectedly ended a transaction that wasn't started by this editor");
|
||||
}
|
||||
@@ -18354,7 +18353,12 @@ impl Editor {
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let ranges: Vec<_> = self.selections.disjoint.iter().map(|s| s.range()).collect();
|
||||
let ranges: Vec<_> = self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect();
|
||||
self.toggle_diff_hunks_in_ranges(ranges, cx);
|
||||
}
|
||||
|
||||
@@ -18392,7 +18396,12 @@ impl Editor {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
let ranges: Vec<_> = self.selections.disjoint.iter().map(|s| s.range()).collect();
|
||||
let ranges: Vec<_> = self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect();
|
||||
let stage = self.has_stageable_diff_hunks_in_ranges(&ranges, &snapshot);
|
||||
self.stage_or_unstage_diff_hunks(stage, ranges, cx);
|
||||
}
|
||||
@@ -18556,7 +18565,12 @@ impl Editor {
|
||||
}
|
||||
|
||||
pub fn expand_selected_diff_hunks(&mut self, cx: &mut Context<Self>) {
|
||||
let ranges: Vec<_> = self.selections.disjoint.iter().map(|s| s.range()).collect();
|
||||
let ranges: Vec<_> = self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.map(|s| s.range())
|
||||
.collect();
|
||||
self.buffer
|
||||
.update(cx, |buffer, cx| buffer.expand_diff_hunks(ranges, cx))
|
||||
}
|
||||
@@ -21276,7 +21290,7 @@ impl Editor {
|
||||
buffer.finalize_last_transaction(cx);
|
||||
if self.leader_id.is_none() {
|
||||
buffer.set_active_selections(
|
||||
&self.selections.disjoint_anchors(),
|
||||
&self.selections.disjoint_anchors_arc(),
|
||||
self.selections.line_mode,
|
||||
self.cursor_shape,
|
||||
cx,
|
||||
@@ -23572,7 +23586,7 @@ impl EntityInputHandler for Editor {
|
||||
let marked_ranges = {
|
||||
let snapshot = this.buffer.read(cx).read(cx);
|
||||
this.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
selection.start.bias_left(&snapshot)..selection.end.bias_right(&snapshot)
|
||||
|
||||
@@ -1060,7 +1060,7 @@ impl EditorElement {
|
||||
);
|
||||
if mouse_down_time.elapsed() >= drag_and_drop_delay {
|
||||
let drop_cursor = Selection {
|
||||
id: post_inc(&mut editor.selections.next_selection_id),
|
||||
id: post_inc(&mut editor.selections.next_selection_id()),
|
||||
start: drop_anchor,
|
||||
end: drop_anchor,
|
||||
reversed: false,
|
||||
@@ -1547,9 +1547,13 @@ impl EditorElement {
|
||||
// Local cursors
|
||||
if !skip_local {
|
||||
let color = cx.theme().players().local().cursor;
|
||||
editor.selections.disjoint.iter().for_each(|selection| {
|
||||
add_cursor(selection.head(), color);
|
||||
});
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.for_each(|selection| {
|
||||
add_cursor(selection.head(), color);
|
||||
});
|
||||
if let Some(ref selection) = editor.selections.pending_anchor() {
|
||||
add_cursor(selection.head(), color);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ impl FollowableItem for Editor {
|
||||
} else if self.focus_handle.is_focused(window) {
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
buffer.set_active_selections(
|
||||
&self.selections.disjoint_anchors(),
|
||||
&self.selections.disjoint_anchors_arc(),
|
||||
self.selections.line_mode,
|
||||
self.cursor_shape,
|
||||
cx,
|
||||
@@ -231,7 +231,7 @@ impl FollowableItem for Editor {
|
||||
scroll_y: scroll_anchor.offset.y,
|
||||
selections: self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|s| serialize_selection(s, &snapshot))
|
||||
.collect(),
|
||||
@@ -310,7 +310,7 @@ impl FollowableItem for Editor {
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
update.selections = self
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|s| serialize_selection(s, &snapshot))
|
||||
.collect();
|
||||
@@ -1675,7 +1675,7 @@ impl SearchableItem for Editor {
|
||||
cx: &mut Context<Self>,
|
||||
) -> usize {
|
||||
let buffer = self.buffer().read(cx).snapshot(cx);
|
||||
let current_index_position = if self.selections.disjoint_anchors().len() == 1 {
|
||||
let current_index_position = if self.selections.disjoint_anchors_arc().len() == 1 {
|
||||
self.selections.newest_anchor().head()
|
||||
} else {
|
||||
matches[current_index].start
|
||||
|
||||
@@ -507,7 +507,7 @@ pub(crate) fn handle_from(
|
||||
|
||||
{
|
||||
let selections = this
|
||||
.read_with(cx, |this, _| this.selections.disjoint_anchors())
|
||||
.read_with(cx, |this, _| this.selections.disjoint_anchors_arc())
|
||||
.ok()?;
|
||||
for selection in selections.iter() {
|
||||
let Some(selection_buffer_offset_head) =
|
||||
|
||||
@@ -35,7 +35,7 @@ where
|
||||
let project = editor.project.clone()?;
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.filter_map(|selection| Some((selection.head(), selection.head().buffer_id?)))
|
||||
.unique_by(|(_, buffer_id)| *buffer_id)
|
||||
|
||||
@@ -130,12 +130,9 @@ fn display_ranges<'a>(
|
||||
display_map: &'a DisplaySnapshot,
|
||||
selections: &'a SelectionsCollection,
|
||||
) -> impl Iterator<Item = Range<DisplayPoint>> + 'a {
|
||||
let pending = selections
|
||||
.pending
|
||||
.as_ref()
|
||||
.map(|pending| &pending.selection);
|
||||
let pending = selections.pending_anchor();
|
||||
selections
|
||||
.disjoint
|
||||
.disjoint_anchors()
|
||||
.iter()
|
||||
.chain(pending)
|
||||
.map(move |s| s.start.to_display_point(display_map)..s.end.to_display_point(display_map))
|
||||
|
||||
@@ -319,7 +319,7 @@ fn cancel_flycheck_action(
|
||||
};
|
||||
let buffer_id = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.find_map(|selection| {
|
||||
let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?;
|
||||
@@ -344,7 +344,7 @@ fn run_flycheck_action(
|
||||
};
|
||||
let buffer_id = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.find_map(|selection| {
|
||||
let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?;
|
||||
@@ -369,7 +369,7 @@ fn clear_flycheck_action(
|
||||
};
|
||||
let buffer_id = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.find_map(|selection| {
|
||||
let buffer_id = selection.start.buffer_id.or(selection.end.buffer_id)?;
|
||||
|
||||
@@ -28,13 +28,13 @@ pub struct PendingSelection {
|
||||
pub struct SelectionsCollection {
|
||||
display_map: Entity<DisplayMap>,
|
||||
buffer: Entity<MultiBuffer>,
|
||||
pub next_selection_id: usize,
|
||||
next_selection_id: usize,
|
||||
pub line_mode: bool,
|
||||
/// The non-pending, non-overlapping selections.
|
||||
/// The [SelectionsCollection::pending] selection could possibly overlap these
|
||||
pub disjoint: Arc<[Selection<Anchor>]>,
|
||||
disjoint: Arc<[Selection<Anchor>]>,
|
||||
/// A pending selection, such as when the mouse is being dragged
|
||||
pub pending: Option<PendingSelection>,
|
||||
pending: Option<PendingSelection>,
|
||||
}
|
||||
|
||||
impl SelectionsCollection {
|
||||
@@ -84,20 +84,27 @@ impl SelectionsCollection {
|
||||
/// The non-pending, non-overlapping selections. There could be a pending selection that
|
||||
/// overlaps these if the mouse is being dragged, etc. This could also be empty if there is a
|
||||
/// pending selection. Returned as selections over Anchors.
|
||||
pub fn disjoint_anchors(&self) -> Arc<[Selection<Anchor>]> {
|
||||
pub fn disjoint_anchors_arc(&self) -> Arc<[Selection<Anchor>]> {
|
||||
self.disjoint.clone()
|
||||
}
|
||||
|
||||
/// The non-pending, non-overlapping selections. There could be a pending selection that
|
||||
/// overlaps these if the mouse is being dragged, etc. This could also be empty if there is a
|
||||
/// pending selection. Returned as selections over Anchors.
|
||||
pub fn disjoint_anchors(&self) -> &[Selection<Anchor>] {
|
||||
&self.disjoint
|
||||
}
|
||||
|
||||
pub fn disjoint_anchor_ranges(&self) -> impl Iterator<Item = Range<Anchor>> {
|
||||
// Mapping the Arc slice would borrow it, whereas indexing captures it.
|
||||
let disjoint = self.disjoint_anchors();
|
||||
let disjoint = self.disjoint_anchors_arc();
|
||||
(0..disjoint.len()).map(move |ix| disjoint[ix].range())
|
||||
}
|
||||
|
||||
/// Non-overlapping selections using anchors, including the pending selection.
|
||||
pub fn all_anchors(&self, cx: &mut App) -> Arc<[Selection<Anchor>]> {
|
||||
if self.pending.is_none() {
|
||||
self.disjoint_anchors()
|
||||
self.disjoint_anchors_arc()
|
||||
} else {
|
||||
let all_offset_selections = self.all::<usize>(cx);
|
||||
let buffer = self.buffer(cx);
|
||||
@@ -108,10 +115,12 @@ impl SelectionsCollection {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pending_anchor(&self) -> Option<Selection<Anchor>> {
|
||||
self.pending
|
||||
.as_ref()
|
||||
.map(|pending| pending.selection.clone())
|
||||
pub fn pending_anchor(&self) -> Option<&Selection<Anchor>> {
|
||||
self.pending.as_ref().map(|pending| &pending.selection)
|
||||
}
|
||||
|
||||
pub fn pending_anchor_mut(&mut self) -> Option<&mut Selection<Anchor>> {
|
||||
self.pending.as_mut().map(|pending| &mut pending.selection)
|
||||
}
|
||||
|
||||
pub fn pending<D: TextDimension + Ord + Sub<D, Output = D>>(
|
||||
@@ -120,7 +129,7 @@ impl SelectionsCollection {
|
||||
) -> Option<Selection<D>> {
|
||||
let map = self.display_map(cx);
|
||||
|
||||
resolve_selections(self.pending_anchor().as_ref(), &map).next()
|
||||
resolve_selections(self.pending_anchor(), &map).next()
|
||||
}
|
||||
|
||||
pub(crate) fn pending_mode(&self) -> Option<SelectMode> {
|
||||
@@ -234,8 +243,7 @@ impl SelectionsCollection {
|
||||
let map = self.display_map(cx);
|
||||
let disjoint_anchors = &self.disjoint;
|
||||
let mut disjoint = resolve_selections_display(disjoint_anchors.iter(), &map).peekable();
|
||||
let mut pending_opt =
|
||||
resolve_selections_display(self.pending_anchor().as_ref(), &map).next();
|
||||
let mut pending_opt = resolve_selections_display(self.pending_anchor(), &map).next();
|
||||
let selections = iter::from_fn(move || {
|
||||
if let Some(pending) = pending_opt.as_mut() {
|
||||
while let Some(next_selection) = disjoint.peek() {
|
||||
@@ -343,9 +351,9 @@ impl SelectionsCollection {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn display_ranges(&self, cx: &mut App) -> Vec<Range<DisplayPoint>> {
|
||||
let display_map = self.display_map(cx);
|
||||
self.disjoint_anchors()
|
||||
self.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.chain(self.pending_anchor().as_ref())
|
||||
.chain(self.pending_anchor())
|
||||
.map(|s| {
|
||||
if s.reversed {
|
||||
s.end.to_display_point(&display_map)..s.start.to_display_point(&display_map)
|
||||
@@ -412,6 +420,10 @@ impl SelectionsCollection {
|
||||
);
|
||||
(mutable_collection.selections_changed, result)
|
||||
}
|
||||
|
||||
pub fn next_selection_id(&self) -> usize {
|
||||
self.next_selection_id
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MutableSelectionsCollection<'a> {
|
||||
|
||||
@@ -396,7 +396,7 @@ impl EditorTestContext {
|
||||
let (multibuffer_snapshot, selections, excerpts) = self.update_editor(|editor, _, cx| {
|
||||
let multibuffer_snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||
|
||||
let selections = editor.selections.disjoint_anchors();
|
||||
let selections = editor.selections.disjoint_anchors_arc();
|
||||
let excerpts = multibuffer_snapshot
|
||||
.excerpts()
|
||||
.map(|(e_id, snapshot, range)| (e_id, snapshot.clone(), range))
|
||||
|
||||
@@ -416,7 +416,7 @@ impl Item for TextDiffView {
|
||||
pub fn selection_location_text(editor: &Editor, cx: &App) -> Option<String> {
|
||||
let buffer = editor.buffer().read(cx);
|
||||
let buffer_snapshot = buffer.snapshot(cx);
|
||||
let first_selection = editor.selections.disjoint.first()?;
|
||||
let first_selection = editor.selections.disjoint_anchors().first()?;
|
||||
|
||||
let selection_start = first_selection.start.to_point(&buffer_snapshot);
|
||||
let selection_end = first_selection.end.to_point(&buffer_snapshot);
|
||||
|
||||
@@ -463,7 +463,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
.collect();
|
||||
vim.switch_mode(Mode::Normal, true, window, cx);
|
||||
let initial_selections =
|
||||
vim.update_editor(cx, |_, editor, _| editor.selections.disjoint_anchors());
|
||||
vim.update_editor(cx, |_, editor, _| editor.selections.disjoint_anchors_arc());
|
||||
if let Some(range) = &action.range {
|
||||
let result = vim.update_editor(cx, |vim, editor, cx| {
|
||||
let range = range.buffer_range(vim, editor, window, cx)?;
|
||||
@@ -515,7 +515,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
|
||||
.buffer()
|
||||
.update(cx, |multi, cx| multi.last_transaction_id(cx))
|
||||
{
|
||||
let last_sel = editor.selections.disjoint_anchors();
|
||||
let last_sel = editor.selections.disjoint_anchors_arc();
|
||||
editor.modify_transaction_selection_history(tx_id, |old| {
|
||||
old.0 = first_sel;
|
||||
old.1 = Some(last_sel);
|
||||
|
||||
@@ -22,7 +22,7 @@ impl Vim {
|
||||
self.update_editor(cx, |vim, editor, cx| {
|
||||
let anchors = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|s| s.head())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -326,7 +326,7 @@ impl Vim {
|
||||
|
||||
let stable_anchors = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
let start = selection.start.bias_left(&display_map.buffer_snapshot);
|
||||
|
||||
@@ -1075,16 +1075,16 @@ impl Vim {
|
||||
}
|
||||
|
||||
let snapshot = s.display_map();
|
||||
if let Some(pending) = s.pending.as_mut()
|
||||
&& pending.selection.reversed
|
||||
if let Some(pending) = s.pending_anchor_mut()
|
||||
&& pending.reversed
|
||||
&& mode.is_visual()
|
||||
&& !last_mode.is_visual()
|
||||
{
|
||||
let mut end = pending.selection.end.to_point(&snapshot.buffer_snapshot);
|
||||
let mut end = pending.end.to_point(&snapshot.buffer_snapshot);
|
||||
end = snapshot
|
||||
.buffer_snapshot
|
||||
.clip_point(end + Point::new(0, 1), Bias::Right);
|
||||
pending.selection.end = snapshot.buffer_snapshot.anchor_before(end);
|
||||
pending.end = snapshot.buffer_snapshot.anchor_before(end);
|
||||
}
|
||||
|
||||
s.move_with(|map, selection| {
|
||||
@@ -1332,7 +1332,7 @@ impl Vim {
|
||||
self.update_editor(cx, |_, editor, _| {
|
||||
editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|selection| selection.tail()..selection.head())
|
||||
.collect()
|
||||
|
||||
@@ -748,7 +748,7 @@ impl Vim {
|
||||
// after the change
|
||||
let stable_anchors = editor
|
||||
.selections
|
||||
.disjoint_anchors()
|
||||
.disjoint_anchors_arc()
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
let start = selection.start.bias_left(&display_map.buffer_snapshot);
|
||||
|
||||
Reference in New Issue
Block a user