Reduce display_map snapshot creation (#39354)

Re-applies https://github.com/zed-industries/zed/pull/30840

This PR re-applies the initial
[PR](https://github.com/zed-industries/zed/pull/30840). As it was closed
because it was hard to land, because of the many conflicts. This PR
re-applies the changes for it.

In several cases we were creating multiple display_map
snapshots within the same root-level function call.
Creating a display_map snapshot is quite slow, and in some
cases we were creating the snapshot multiple times.

Release Notes:

- N/A
This commit is contained in:
Remco Smits
2025-10-17 21:56:57 +02:00
committed by GitHub
parent ef5b8c6fed
commit 7e97fcaacb
60 changed files with 853 additions and 426 deletions
+183 -106
View File
@@ -2323,21 +2323,22 @@ impl Editor {
}
EditorEvent::Edited { .. } => {
if !vim_enabled(cx) {
let (map, selections) = editor.selections.all_adjusted_display(cx);
let display_map = editor.display_snapshot(cx);
let selections = editor.selections.all_adjusted_display(&display_map);
let pop_state = editor
.change_list
.last()
.map(|previous| {
previous.len() == selections.len()
&& previous.iter().enumerate().all(|(ix, p)| {
p.to_display_point(&map).row()
p.to_display_point(&display_map).row()
== selections[ix].head().row()
})
})
.unwrap_or(false);
let new_positions = selections
.into_iter()
.map(|s| map.display_point_to_anchor(s.head(), Bias::Left))
.map(|s| display_map.display_point_to_anchor(s.head(), Bias::Left))
.collect();
editor
.change_list
@@ -2408,6 +2409,10 @@ impl Editor {
editor
}
pub fn display_snapshot(&self, cx: &mut App) -> DisplaySnapshot {
self.selections.display_map(cx)
}
pub fn deploy_mouse_context_menu(
&mut self,
position: gpui::Point<Pixels>,
@@ -2443,7 +2448,7 @@ impl Editor {
}
self.selections
.disjoint_in_range::<usize>(range.clone(), cx)
.disjoint_in_range::<usize>(range.clone(), &self.display_snapshot(cx))
.into_iter()
.any(|selection| {
// This is needed to cover a corner case, if we just check for an existing
@@ -3039,7 +3044,7 @@ impl Editor {
// Copy selections to primary selection buffer
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
if local {
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
let buffer_handle = self.buffer.read(cx).read(cx);
let mut text = String::new();
@@ -3491,7 +3496,7 @@ impl Editor {
cx: &mut Context<Self>,
) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let tail = self.selections.newest::<usize>(cx).tail();
let tail = self.selections.newest::<usize>(&display_map).tail();
let click_count = click_count.max(match self.selections.select_mode() {
SelectMode::Character => 1,
SelectMode::Word(_) => 2,
@@ -3610,7 +3615,7 @@ impl Editor {
let point_to_delete: Option<usize> = {
let selected_points: Vec<Selection<Point>> =
self.selections.disjoint_in_range(start..end, cx);
self.selections.disjoint_in_range(start..end, &display_map);
if !add || click_count > 1 {
None
@@ -3686,7 +3691,7 @@ impl Editor {
);
};
let tail = self.selections.newest::<Point>(cx).tail();
let tail = self.selections.newest::<Point>(&display_map).tail();
let selection_anchor = display_map.buffer_snapshot().anchor_before(tail);
self.columnar_selection_state = match mode {
ColumnarMode::FromMouse => Some(ColumnarSelectionState::FromMouse {
@@ -3813,7 +3818,7 @@ impl Editor {
fn end_selection(&mut self, window: &mut Window, cx: &mut Context<Self>) {
self.columnar_selection_state.take();
if let Some(pending_mode) = self.selections.pending_mode() {
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
s.select(selections);
s.clear_pending();
@@ -3902,9 +3907,9 @@ impl Editor {
cx.notify();
}
pub fn has_non_empty_selection(&self, cx: &mut App) -> bool {
pub fn has_non_empty_selection(&self, snapshot: &DisplaySnapshot) -> bool {
self.selections
.all_adjusted(cx)
.all_adjusted(snapshot)
.iter()
.any(|selection| !selection.is_empty())
}
@@ -4053,7 +4058,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let selections = self.selections.all_adjusted(cx);
let selections = self.selections.all_adjusted(&self.display_snapshot(cx));
let mut bracket_inserted = false;
let mut edits = Vec::new();
let mut linked_edits = HashMap::<_, Vec<_>>::default();
@@ -4403,7 +4408,7 @@ impl Editor {
let trigger_in_words =
this.show_edit_predictions_in_menu() || !had_active_edit_prediction;
if this.hard_wrap.is_some() {
let latest: Range<Point> = this.selections.newest(cx).range();
let latest: Range<Point> = this.selections.newest(&map).range();
if latest.is_empty()
&& this
.buffer()
@@ -4479,7 +4484,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
self.transact(window, cx, |this, window, cx| {
let (edits_with_flags, selection_info): (Vec<_>, Vec<_>) = {
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
let multi_buffer = this.buffer.read(cx);
let buffer = multi_buffer.snapshot(cx);
selections
@@ -4771,7 +4776,12 @@ impl Editor {
let mut edits = Vec::new();
let mut rows = Vec::new();
for (rows_inserted, selection) in self.selections.all_adjusted(cx).into_iter().enumerate() {
for (rows_inserted, selection) in self
.selections
.all_adjusted(&self.display_snapshot(cx))
.into_iter()
.enumerate()
{
let cursor = selection.head();
let row = cursor.row;
@@ -4831,7 +4841,7 @@ impl Editor {
let mut rows = Vec::new();
let mut rows_inserted = 0;
for selection in self.selections.all_adjusted(cx) {
for selection in self.selections.all_adjusted(&self.display_snapshot(cx)) {
let cursor = selection.head();
let row = cursor.row;
@@ -4903,7 +4913,7 @@ impl Editor {
let text: Arc<str> = text.into();
self.transact(window, cx, |this, window, cx| {
let old_selections = this.selections.all_adjusted(cx);
let old_selections = this.selections.all_adjusted(&this.display_snapshot(cx));
let selection_anchors = this.buffer.update(cx, |buffer, cx| {
let anchors = {
let snapshot = buffer.read(cx);
@@ -5013,7 +5023,7 @@ impl Editor {
/// If any empty selections is touching the start of its innermost containing autoclose
/// region, expand it to select the brackets.
fn select_autoclose_pair(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
let buffer = self.buffer.read(cx).read(cx);
let new_selections = self
.selections_with_autoclose_regions(selections, &buffer)
@@ -6010,7 +6020,7 @@ impl Editor {
let prefix = &old_text[..old_text.len().saturating_sub(lookahead)];
let suffix = &old_text[lookbehind.min(old_text.len())..];
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
let mut ranges = Vec::new();
let mut linked_edits = HashMap::<_, Vec<_>>::default();
@@ -6162,7 +6172,10 @@ impl Editor {
Some(CodeActionSource::Indicator(row)) | Some(CodeActionSource::RunMenu(row)) => {
DisplayPoint::new(*row, 0).to_point(&snapshot)
}
_ => self.selections.newest::<Point>(cx).head(),
_ => self
.selections
.newest::<Point>(&snapshot.display_snapshot)
.head(),
};
let Some((buffer, buffer_row)) = snapshot
.buffer_snapshot()
@@ -6624,7 +6637,9 @@ impl Editor {
if newest_selection.head().diff_base_anchor.is_some() {
return None;
}
let newest_selection_adjusted = this.selections.newest_adjusted(cx);
let display_snapshot = this.display_snapshot(cx);
let newest_selection_adjusted =
this.selections.newest_adjusted(&display_snapshot);
let buffer = this.buffer.read(cx);
let (start_buffer, start) =
@@ -6699,7 +6714,10 @@ impl Editor {
pub fn blame_hover(&mut self, _: &BlameHover, window: &mut Window, cx: &mut Context<Self>) {
let snapshot = self.snapshot(window, cx);
let cursor = self.selections.newest::<Point>(cx).head();
let cursor = self
.selections
.newest::<Point>(&snapshot.display_snapshot)
.head();
let Some((buffer, point, _)) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)
else {
return;
@@ -7572,7 +7590,10 @@ impl Editor {
// Find an insertion that starts at the cursor position.
let snapshot = self.buffer.read(cx).snapshot(cx);
let cursor_offset = self.selections.newest::<usize>(cx).head();
let cursor_offset = self
.selections
.newest::<usize>(&self.display_snapshot(cx))
.head();
let insertion = edits.iter().find_map(|(range, text)| {
let range = range.to_offset(&snapshot);
if range.is_empty() && range.start == cursor_offset {
@@ -8528,7 +8549,11 @@ impl Editor {
&mut self,
cx: &mut Context<Self>,
) -> Option<(Entity<Buffer>, u32, Arc<RunnableTasks>)> {
let cursor_row = self.selections.newest_adjusted(cx).head().row;
let cursor_row = self
.selections
.newest_adjusted(&self.display_snapshot(cx))
.head()
.row;
let ((buffer_id, row), tasks) = self
.tasks
@@ -8545,7 +8570,10 @@ impl Editor {
cx: &mut Context<Self>,
) -> Option<(Entity<Buffer>, u32, Arc<RunnableTasks>)> {
let snapshot = self.buffer.read(cx).snapshot(cx);
let offset = self.selections.newest::<usize>(cx).head();
let offset = self
.selections
.newest::<usize>(&self.display_snapshot(cx))
.head();
let excerpt = snapshot.excerpt_containing(offset..offset)?;
let buffer_id = excerpt.buffer().remote_id();
@@ -9862,8 +9890,7 @@ impl Editor {
// Check whether the just-entered snippet ends with an auto-closable bracket.
if self.autoclose_regions.is_empty() {
let snapshot = self.buffer.read(cx).snapshot(cx);
let mut all_selections = self.selections.all::<Point>(cx);
for selection in &mut all_selections {
for selection in &mut self.selections.all::<Point>(&self.display_snapshot(cx)) {
let selection_head = selection.head();
let Some(scope) = snapshot.language_scope_at(selection_head) else {
continue;
@@ -10001,9 +10028,12 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
self.transact(window, cx, |this, window, cx| {
this.select_autoclose_pair(window, cx);
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut linked_ranges = HashMap::<_, Vec<_>>::default();
if !this.linked_edit_ranges.is_empty() {
let selections = this.selections.all::<MultiBufferPoint>(cx);
let selections = this.selections.all::<MultiBufferPoint>(&display_map);
let snapshot = this.buffer.read(cx).snapshot(cx);
for selection in selections.iter() {
@@ -10022,8 +10052,7 @@ impl Editor {
}
}
let mut selections = this.selections.all::<MultiBufferPoint>(cx);
let display_map = this.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut selections = this.selections.all::<MultiBufferPoint>(&display_map);
for selection in &mut selections {
if selection.is_empty() {
let old_head = selection.head();
@@ -10138,7 +10167,7 @@ impl Editor {
return;
}
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let mut selections = self.selections.all_adjusted(cx);
let mut selections = self.selections.all_adjusted(&self.display_snapshot(cx));
let buffer = self.buffer.read(cx);
let snapshot = buffer.snapshot(cx);
let rows_iter = selections.iter().map(|s| s.head().row);
@@ -10254,7 +10283,7 @@ impl Editor {
}
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let mut selections = self.selections.all::<Point>(cx);
let mut selections = self.selections.all::<Point>(&self.display_snapshot(cx));
let mut prev_edited_row = 0;
let mut row_delta = 0;
let mut edits = Vec::new();
@@ -10363,7 +10392,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut deletion_ranges = Vec::new();
let mut last_outdent = None;
{
@@ -10424,7 +10453,7 @@ impl Editor {
cx,
);
});
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
});
}
@@ -10441,7 +10470,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let selections = self
.selections
.all::<usize>(cx)
.all::<usize>(&self.display_snapshot(cx))
.into_iter()
.map(|s| s.range());
@@ -10449,7 +10478,7 @@ impl Editor {
this.buffer.update(cx, |buffer, cx| {
buffer.autoindent_ranges(selections, cx);
});
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
});
}
@@ -10457,7 +10486,7 @@ impl Editor {
pub fn delete_line(&mut self, _: &DeleteLine, window: &mut Window, cx: &mut Context<Self>) {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut new_cursors = Vec::new();
let mut edit_ranges = Vec::new();
@@ -10551,7 +10580,7 @@ impl Editor {
return;
}
let mut row_ranges = Vec::<Range<MultiBufferRow>>::new();
for selection in self.selections.all::<Point>(cx) {
for selection in self.selections.all::<Point>(&self.display_snapshot(cx)) {
let start = MultiBufferRow(selection.start.row);
// Treat single line selections as if they include the next line. Otherwise this action
// would do nothing for single line selections individual cursors.
@@ -10694,7 +10723,11 @@ impl Editor {
let mut edits = Vec::new();
let mut boundaries = Vec::new();
for selection in self.selections.all::<Point>(cx).iter() {
for selection in self
.selections
.all::<Point>(&self.display_snapshot(cx))
.iter()
{
let Some(wrap_config) = snapshot
.language_at(selection.start)
.and_then(|lang| lang.config().wrap_characters.clone())
@@ -10764,7 +10797,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let mut buffer_ids = HashSet::default();
let snapshot = self.buffer().read(cx).snapshot(cx);
for selection in self.selections.all::<usize>(cx) {
for selection in self.selections.all::<usize>(&self.display_snapshot(cx)) {
buffer_ids.extend(snapshot.buffer_ids_for_range(selection.range()))
}
@@ -10781,7 +10814,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let selections = self
.selections
.all(cx)
.all(&self.display_snapshot(cx))
.into_iter()
.map(|s| s.range())
.collect();
@@ -11189,7 +11222,7 @@ impl Editor {
let mut edits = Vec::new();
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut selections = selections.iter().peekable();
let mut contiguous_row_selections = Vec::new();
let mut new_selections = Vec::new();
@@ -11591,7 +11624,7 @@ impl Editor {
let mut edits = Vec::new();
let mut selection_adjustment = 0i32;
for selection in self.selections.all_adjusted(cx) {
for selection in self.selections.all_adjusted(&self.display_snapshot(cx)) {
let selection_is_empty = selection.is_empty();
let (start, end) = if selection_is_empty {
@@ -11683,7 +11716,7 @@ impl Editor {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = display_map.buffer_snapshot();
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut edits = Vec::new();
let mut selections_iter = selections.iter().peekable();
@@ -11791,7 +11824,7 @@ impl Editor {
let mut unfold_ranges = Vec::new();
let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut selections = selections.iter().peekable();
let mut contiguous_row_selections = Vec::new();
let mut new_selections = Vec::new();
@@ -11902,7 +11935,7 @@ impl Editor {
let mut unfold_ranges = Vec::new();
let mut refold_creases = Vec::new();
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let mut selections = selections.iter().peekable();
let mut contiguous_row_selections = Vec::new();
let mut new_selections = Vec::new();
@@ -12035,7 +12068,7 @@ impl Editor {
});
this.buffer
.update(cx, |buffer, cx| buffer.edit(edits, None, cx));
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
this.change_selections(Default::default(), window, cx, |s| {
s.select(selections);
});
@@ -12054,7 +12087,7 @@ impl Editor {
pub fn rewrap_impl(&mut self, options: RewrapOptions, cx: &mut Context<Self>) {
let buffer = self.buffer.read(cx).snapshot(cx);
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&self.display_snapshot(cx));
#[derive(Clone, Debug, PartialEq)]
enum CommentFormat {
@@ -12430,7 +12463,7 @@ impl Editor {
) -> ClipboardItem {
let mut text = String::new();
let buffer = self.buffer.read(cx).snapshot(cx);
let mut selections = self.selections.all::<Point>(cx);
let mut selections = self.selections.all::<Point>(&self.display_snapshot(cx));
let mut clipboard_selections = Vec::with_capacity(selections.len());
{
let max_point = buffer.max_point();
@@ -12526,7 +12559,7 @@ impl Editor {
}
fn do_copy(&self, strip_leading_indents: bool, cx: &mut Context<Self>) {
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&self.display_snapshot(cx));
let buffer = self.buffer.read(cx).read(cx);
let mut text = String::new();
@@ -12637,8 +12670,9 @@ impl Editor {
self.transact(window, cx, |this, window, cx| {
let had_active_edit_prediction = this.has_active_edit_prediction();
let old_selections = this.selections.all::<usize>(cx);
let cursor_offset = this.selections.last::<usize>(cx).head();
let display_map = this.display_snapshot(cx);
let old_selections = this.selections.all::<usize>(&display_map);
let cursor_offset = this.selections.last::<usize>(&display_map).head();
if let Some(mut clipboard_selections) = clipboard_selections {
let all_selections_were_entire_line =
@@ -12719,7 +12753,7 @@ impl Editor {
);
});
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
} else {
let url = url::Url::parse(&clipboard_text).ok();
@@ -12784,7 +12818,7 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
if selections.is_empty() {
log::warn!("There should always be at least one selection in Zed. This is a bug.");
@@ -14047,7 +14081,7 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let mut selection = self.selections.last::<Point>(cx);
let mut selection = self.selections.last::<Point>(&self.display_snapshot(cx));
selection.set_head(Point::zero(), SelectionGoal::None);
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
self.change_selections(Default::default(), window, cx, |s| {
@@ -14126,7 +14160,7 @@ impl Editor {
pub fn select_to_end(&mut self, _: &SelectToEnd, window: &mut Window, cx: &mut Context<Self>) {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let buffer = self.buffer.read(cx).snapshot(cx);
let mut selection = self.selections.first::<usize>(cx);
let mut selection = self.selections.first::<usize>(&self.display_snapshot(cx));
selection.set_head(buffer.len(), SelectionGoal::None);
self.change_selections(Default::default(), window, cx, |s| {
s.select(vec![selection]);
@@ -14144,7 +14178,7 @@ impl Editor {
pub fn select_line(&mut self, _: &SelectLine, window: &mut Window, cx: &mut Context<Self>) {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let mut selections = self.selections.all::<Point>(cx);
let mut selections = self.selections.all::<Point>(&display_map);
let max_point = display_map.buffer_snapshot().max_point();
for selection in &mut selections {
let rows = selection.spanned_rows(true, &display_map);
@@ -14165,7 +14199,7 @@ impl Editor {
) {
let selections = self
.selections
.all::<Point>(cx)
.all::<Point>(&self.display_snapshot(cx))
.into_iter()
.map(|selection| selection.start..selection.end)
.collect::<Vec<_>>();
@@ -14244,7 +14278,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let all_selections = self.selections.all::<Point>(cx);
let all_selections = self.selections.all::<Point>(&display_map);
let text_layout_details = self.text_layout_details(window);
let (mut columnar_selections, new_selections_to_columnarize) = {
@@ -14378,7 +14412,7 @@ impl Editor {
let final_selection_ids: HashSet<_> = self
.selections
.all::<Point>(cx)
.all::<Point>(&display_map)
.iter()
.map(|s| s.id)
.collect();
@@ -14436,7 +14470,7 @@ impl Editor {
cx: &mut Context<Self>,
) -> Result<()> {
let buffer = display_map.buffer_snapshot();
let mut selections = self.selections.all::<usize>(cx);
let mut selections = self.selections.all::<usize>(&display_map);
if let Some(mut select_next_state) = self.select_next_state.take() {
let query = &select_next_state.query;
if !select_next_state.done {
@@ -14610,7 +14644,7 @@ impl Editor {
let mut new_selections = Vec::new();
let reversed = self.selections.oldest::<usize>(cx).reversed;
let reversed = self.selections.oldest::<usize>(&display_map).reversed;
let buffer = display_map.buffer_snapshot();
let query_matches = select_next_state
.query
@@ -14674,7 +14708,7 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = display_map.buffer_snapshot();
let mut selections = self.selections.all::<usize>(cx);
let mut selections = self.selections.all::<usize>(&display_map);
if let Some(mut select_prev_state) = self.select_prev_state.take() {
let query = &select_prev_state.query;
if !select_prev_state.done {
@@ -14862,7 +14896,9 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
let text_layout_details = &self.text_layout_details(window);
self.transact(window, cx, |this, window, cx| {
let mut selections = this.selections.all::<MultiBufferPoint>(cx);
let mut selections = this
.selections
.all::<MultiBufferPoint>(&this.display_snapshot(cx));
let mut edits = Vec::new();
let mut selection_edit_ranges = Vec::new();
let mut last_toggled_row = None;
@@ -15093,7 +15129,7 @@ impl Editor {
// Adjust selections so that they end before any comment suffixes that
// were inserted.
let mut suffixes_inserted = suffixes_inserted.into_iter().peekable();
let mut selections = this.selections.all::<Point>(cx);
let mut selections = this.selections.all::<Point>(&this.display_snapshot(cx));
let snapshot = this.buffer.read(cx).read(cx);
for selection in &mut selections {
while let Some((row, suffix_len)) = suffixes_inserted.peek().copied() {
@@ -15119,7 +15155,7 @@ impl Editor {
drop(snapshot);
this.change_selections(Default::default(), window, cx, |s| s.select(selections));
let selections = this.selections.all::<Point>(cx);
let selections = this.selections.all::<Point>(&this.display_snapshot(cx));
let selections_on_single_row = selections.windows(2).all(|selections| {
selections[0].start.row == selections[1].start.row
&& selections[0].end.row == selections[1].end.row
@@ -15163,7 +15199,10 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let buffer = self.buffer.read(cx).snapshot(cx);
let old_selections = self.selections.all::<usize>(cx).into_boxed_slice();
let old_selections = self
.selections
.all::<usize>(&self.display_snapshot(cx))
.into_boxed_slice();
fn update_selection(
selection: &Selection<usize>,
@@ -15218,7 +15257,10 @@ impl Editor {
let Some(visible_row_count) = self.visible_row_count() else {
return;
};
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
let old_selections: Box<[_]> = self
.selections
.all::<usize>(&self.display_snapshot(cx))
.into();
if old_selections.is_empty() {
return;
}
@@ -15376,7 +15418,7 @@ impl Editor {
let buffer = self.buffer.read(cx).snapshot(cx);
let selections = self
.selections
.all::<usize>(cx)
.all::<usize>(&self.display_snapshot(cx))
.into_iter()
// subtracting the offset requires sorting
.sorted_by_key(|i| i.start);
@@ -15448,7 +15490,10 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
let old_selections: Box<[_]> = self
.selections
.all::<usize>(&self.display_snapshot(cx))
.into();
if old_selections.is_empty() {
return;
}
@@ -15497,7 +15542,10 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let old_selections: Box<[_]> = self.selections.all::<usize>(cx).into();
let old_selections: Box<[_]> = self
.selections
.all::<usize>(&self.display_snapshot(cx))
.into();
if old_selections.is_empty() {
return;
}
@@ -16046,7 +16094,7 @@ impl Editor {
cx: &mut Context<Self>,
) {
let buffer = self.buffer.read(cx).snapshot(cx);
let selection = self.selections.newest::<usize>(cx);
let selection = self.selections.newest::<usize>(&self.display_snapshot(cx));
let mut active_group_id = None;
if let ActiveDiagnostic::Group(active_group) = &self.active_diagnostics
@@ -16127,7 +16175,7 @@ impl Editor {
pub fn go_to_next_hunk(&mut self, _: &GoToHunk, window: &mut Window, cx: &mut Context<Self>) {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let snapshot = self.snapshot(window, cx);
let selection = self.selections.newest::<Point>(cx);
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
self.go_to_hunk_before_or_after_position(
&snapshot,
selection.head(),
@@ -16188,7 +16236,7 @@ impl Editor {
) {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let snapshot = self.snapshot(window, cx);
let selection = self.selections.newest::<Point>(cx);
let selection = self.selections.newest::<Point>(&snapshot.display_snapshot);
self.go_to_hunk_before_or_after_position(
&snapshot,
selection.head(),
@@ -16278,7 +16326,10 @@ impl Editor {
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
let snapshot = self.snapshot(window, cx);
let buffer = &snapshot.buffer_snapshot();
let position = self.selections.newest::<Point>(cx).head();
let position = self
.selections
.newest::<Point>(&snapshot.display_snapshot)
.head();
let anchor_position = buffer.anchor_after(position);
// Get all document highlights (both read and write)
@@ -16461,7 +16512,10 @@ impl Editor {
let Some(provider) = self.semantics_provider.clone() else {
return Task::ready(Ok(Navigated::No));
};
let head = self.selections.newest::<usize>(cx).head();
let head = self
.selections
.newest::<usize>(&self.display_snapshot(cx))
.head();
let buffer = self.buffer.read(cx);
let Some((buffer, head)) = buffer.text_anchor_for_position(head, cx) else {
return Task::ready(Ok(Navigated::No));
@@ -16792,7 +16846,7 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) -> Option<Task<Result<Navigated>>> {
let selection = self.selections.newest::<usize>(cx);
let selection = self.selections.newest::<usize>(&self.display_snapshot(cx));
let multi_buffer = self.buffer.read(cx);
let head = selection.head();
@@ -17267,7 +17321,10 @@ impl Editor {
if moving_cursor {
let cursor_in_rename_editor = rename.editor.update(cx, |editor, cx| {
editor.selections.newest::<usize>(cx).head()
editor
.selections
.newest::<usize>(&editor.display_snapshot(cx))
.head()
});
// Update the selection to match the position of the selection inside
@@ -17330,7 +17387,7 @@ impl Editor {
let ranges = self
.selections
.all_adjusted(cx)
.all_adjusted(&self.display_snapshot(cx))
.into_iter()
.map(|selection| selection.range())
.collect_vec();
@@ -18029,9 +18086,9 @@ impl Editor {
cx: &mut Context<Self>,
) {
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
let selection = self.selections.newest::<Point>(cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selection = self.selections.newest::<Point>(&display_map);
let range = if selection.is_empty() {
let point = selection.head().to_display_point(&display_map);
let start = DisplayPoint::new(point.row(), 0).to_point(&display_map);
@@ -18074,7 +18131,7 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let selection = self.selections.newest::<Point>(cx);
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let range = if selection.is_empty() {
@@ -18097,7 +18154,7 @@ impl Editor {
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
let mut to_fold = Vec::new();
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all_adjusted(cx);
let selections = self.selections.all_adjusted(&display_map);
for selection in selections {
let range = selection.range().sorted();
@@ -18204,7 +18261,7 @@ impl Editor {
let row_ranges_to_keep: Vec<Range<u32>> = self
.selections
.all::<Point>(cx)
.all::<Point>(&self.display_snapshot(cx))
.into_iter()
.map(|sel| sel.start.row..sel.end.row)
.collect();
@@ -18379,7 +18436,7 @@ impl Editor {
) {
let mut to_fold = Vec::new();
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all_adjusted(cx);
let selections = self.selections.all_adjusted(&display_map);
for selection in selections {
let range = selection.range().sorted();
@@ -18423,7 +18480,7 @@ impl Editor {
if let Some(crease) = display_map.crease_for_buffer_row(buffer_row) {
let autoscroll = self
.selections
.all::<Point>(cx)
.all::<Point>(&display_map)
.iter()
.any(|selection| crease.range().overlaps(&selection.range()));
@@ -18435,7 +18492,7 @@ impl Editor {
if self.buffer_kind(cx) == ItemBufferKind::Singleton {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let buffer = display_map.buffer_snapshot();
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let ranges = selections
.iter()
.map(|s| {
@@ -18469,7 +18526,7 @@ impl Editor {
cx: &mut Context<Self>,
) {
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all::<Point>(cx);
let selections = self.selections.all::<Point>(&display_map);
let ranges = selections
.iter()
.map(|s| {
@@ -18501,7 +18558,7 @@ impl Editor {
let autoscroll = self
.selections
.all::<Point>(cx)
.all::<Point>(&display_map)
.iter()
.any(|selection| RangeExt::overlaps(&selection.range(), &intersection_range));
@@ -18536,8 +18593,8 @@ impl Editor {
window: &mut Window,
cx: &mut Context<Self>,
) {
let selections = self.selections.all_adjusted(cx);
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
let selections = self.selections.all_adjusted(&display_map);
let ranges = selections
.into_iter()
.map(|s| Crease::simple(s.range(), display_map.fold_placeholder.clone()))
@@ -18870,7 +18927,10 @@ impl Editor {
self.stage_or_unstage_diff_hunks(stage, ranges, cx);
let snapshot = self.snapshot(window, cx);
let position = self.selections.newest::<Point>(cx).head();
let position = self
.selections
.newest::<Point>(&snapshot.display_snapshot)
.head();
let mut row = snapshot
.buffer_snapshot()
.diff_hunks_in_range(position..snapshot.buffer_snapshot().max_point())
@@ -19018,7 +19078,7 @@ impl Editor {
let snapshot = self.snapshot(window, cx);
let hunks = snapshot.hunks_for_ranges(
self.selections
.all(cx)
.all(&snapshot.display_snapshot)
.into_iter()
.map(|selection| selection.range()),
);
@@ -19754,7 +19814,10 @@ impl Editor {
) -> Option<()> {
let blame = self.blame.as_ref()?;
let snapshot = self.snapshot(window, cx);
let cursor = self.selections.newest::<Point>(cx).head();
let cursor = self
.selections
.newest::<Point>(&snapshot.display_snapshot)
.head();
let (buffer, point, _) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)?;
let (_, blame_entry) = blame
.update(cx, |blame, cx| {
@@ -19896,7 +19959,7 @@ impl Editor {
fn get_permalink_to_line(&self, cx: &mut Context<Self>) -> Task<Result<url::Url>> {
let buffer_and_selection = maybe!({
let selection = self.selections.newest::<Point>(cx);
let selection = self.selections.newest::<Point>(&self.display_snapshot(cx));
let selection_range = selection.range();
let multi_buffer = self.buffer().read(cx);
@@ -19974,7 +20037,12 @@ impl Editor {
_: &mut Window,
cx: &mut Context<Self>,
) {
let selection = self.selections.newest::<Point>(cx).start.row + 1;
let selection = self
.selections
.newest::<Point>(&self.display_snapshot(cx))
.start
.row
+ 1;
if let Some(file) = self.target_file(cx) {
let path = file.path().display(file.path_style(cx));
cx.write_to_clipboard(ClipboardItem::new_string(format!("{path}:{selection}")));
@@ -20045,7 +20113,7 @@ impl Editor {
self.transact(window, cx, |this, window, cx| {
let edits = this
.selections
.all::<Point>(cx)
.all::<Point>(&this.display_snapshot(cx))
.into_iter()
.map(|selection| {
let uuid = match version {
@@ -21131,7 +21199,7 @@ impl Editor {
return;
};
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
let multi_buffer = self.buffer.read(cx);
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
let mut new_selections_by_buffer = HashMap::default();
@@ -21255,7 +21323,7 @@ impl Editor {
}
}
None => {
let selections = self.selections.all::<usize>(cx);
let selections = self.selections.all::<usize>(&self.display_snapshot(cx));
let multi_buffer = self.buffer.read(cx);
for selection in selections {
for (snapshot, range, _, anchor) in multi_buffer
@@ -21393,7 +21461,9 @@ impl Editor {
range: Range<OffsetUtf16>,
cx: &mut App,
) -> Vec<Range<OffsetUtf16>> {
let selections = self.selections.all::<OffsetUtf16>(cx);
let selections = self
.selections
.all::<OffsetUtf16>(&self.display_snapshot(cx));
let newest_selection = selections
.iter()
.max_by_key(|selection| selection.id)
@@ -21556,7 +21626,10 @@ impl Editor {
cx: &mut Context<Self>,
) {
self.request_autoscroll(Autoscroll::newest(), cx);
let position = self.selections.newest_display(cx).start;
let position = self
.selections
.newest_display(&self.display_snapshot(cx))
.start;
mouse_context_menu::deploy_context_menu(self, None, position, window, cx);
}
@@ -21576,7 +21649,9 @@ impl Editor {
return;
}
if let Some(relative_utf16_range) = relative_utf16_range {
let selections = self.selections.all::<OffsetUtf16>(cx);
let selections = self
.selections
.all::<OffsetUtf16>(&self.display_snapshot(cx));
self.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
let new_ranges = selections.into_iter().map(|range| {
let start = OffsetUtf16(
@@ -21716,7 +21791,7 @@ impl Editor {
}
let transaction =
self.transact(window, cx, |this, window, cx| {
let selections = this.selections.all::<usize>(cx);
let selections = this.selections.all::<usize>(&this.display_snapshot(cx));
let edits = selections
.iter()
.map(|selection| (selection.end..selection.end, pending.clone()));
@@ -21735,7 +21810,7 @@ impl Editor {
let snapshot = self.snapshot(window, cx);
let ranges = self
.selections
.all::<usize>(cx)
.all::<usize>(&snapshot.display_snapshot)
.into_iter()
.map(|selection| {
snapshot.buffer_snapshot().anchor_after(selection.end)
@@ -23867,7 +23942,9 @@ impl EntityInputHandler for Editor {
return None;
}
let selection = self.selections.newest::<OffsetUtf16>(cx);
let selection = self
.selections
.newest::<OffsetUtf16>(&self.display_snapshot(cx));
let range = selection.range();
Some(UTF16Selection {
@@ -23910,7 +23987,7 @@ impl EntityInputHandler for Editor {
let range_to_replace = new_selected_ranges.as_ref().and_then(|ranges_to_replace| {
let newest_selection_id = this.selections.newest_anchor().id;
this.selections
.all::<OffsetUtf16>(cx)
.all::<OffsetUtf16>(&this.display_snapshot(cx))
.iter()
.zip(ranges_to_replace.iter())
.find_map(|(selection, range)| {
@@ -23985,7 +24062,7 @@ impl EntityInputHandler for Editor {
let range_to_replace = ranges_to_replace.as_ref().and_then(|ranges_to_replace| {
let newest_selection_id = this.selections.newest_anchor().id;
this.selections
.all::<OffsetUtf16>(cx)
.all::<OffsetUtf16>(&this.display_snapshot(cx))
.iter()
.zip(ranges_to_replace.iter())
.find_map(|(selection, range)| {