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:
@@ -652,7 +652,9 @@ impl ContextPickerCompletionProvider {
|
||||
.active_item(cx)
|
||||
.and_then(|item| item.downcast::<Editor>())
|
||||
.is_some_and(|editor| {
|
||||
editor.update(cx, |editor, cx| editor.has_non_empty_selection(cx))
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.has_non_empty_selection(&editor.display_snapshot(cx))
|
||||
})
|
||||
});
|
||||
if has_selection {
|
||||
entries.push(ContextPickerEntry::Action(
|
||||
|
||||
@@ -452,7 +452,10 @@ fn update_editor_selection(
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
let newest_cursor = editor.selections.newest::<Point>(cx).head();
|
||||
let newest_cursor = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
|
||||
if !diff_hunks.iter().any(|hunk| {
|
||||
hunk.row_range
|
||||
@@ -1895,7 +1898,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(1, 0)..Point::new(1, 0)
|
||||
);
|
||||
@@ -1909,7 +1914,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -1930,7 +1937,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -1962,7 +1971,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -2119,7 +2130,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(1, 0)..Point::new(1, 0)
|
||||
);
|
||||
@@ -2160,7 +2173,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -2181,7 +2196,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -2207,7 +2224,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor1
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(3, 0)..Point::new(3, 0)
|
||||
);
|
||||
@@ -2240,7 +2259,9 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
editor2
|
||||
.update(cx, |editor, cx| editor.selections.newest::<Point>(cx))
|
||||
.update(cx, |editor, cx| editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx)))
|
||||
.range(),
|
||||
Point::new(0, 0)..Point::new(0, 0)
|
||||
);
|
||||
|
||||
@@ -606,7 +606,11 @@ pub(crate) fn available_context_picker_entries(
|
||||
.read(cx)
|
||||
.active_item(cx)
|
||||
.and_then(|item| item.downcast::<Editor>())
|
||||
.is_some_and(|editor| editor.update(cx, |editor, cx| editor.has_non_empty_selection(cx)));
|
||||
.is_some_and(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor.has_non_empty_selection(&editor.display_snapshot(cx))
|
||||
})
|
||||
});
|
||||
if has_selection {
|
||||
entries.push(ContextPickerEntry::Action(
|
||||
ContextPickerAction::AddSelections,
|
||||
@@ -725,7 +729,7 @@ pub(crate) fn selection_ranges(
|
||||
};
|
||||
|
||||
editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all_adjusted(cx);
|
||||
let selections = editor.selections.all_adjusted(&editor.display_snapshot(cx));
|
||||
|
||||
let buffer = editor.buffer().clone().read(cx);
|
||||
let snapshot = buffer.snapshot(cx);
|
||||
|
||||
@@ -363,9 +363,12 @@ impl InlineAssistant {
|
||||
cx: &mut App,
|
||||
) {
|
||||
let (snapshot, initial_selections, newest_selection) = editor.update(cx, |editor, cx| {
|
||||
let selections = editor.selections.all::<Point>(cx);
|
||||
let newest_selection = editor.selections.newest::<Point>(cx);
|
||||
(editor.snapshot(window, cx), selections, newest_selection)
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let selections = editor.selections.all::<Point>(&snapshot.display_snapshot);
|
||||
let newest_selection = editor
|
||||
.selections
|
||||
.newest::<Point>(&snapshot.display_snapshot);
|
||||
(snapshot, selections, newest_selection)
|
||||
});
|
||||
|
||||
// Check if there is already an inline assistant that contains the
|
||||
@@ -798,7 +801,9 @@ impl InlineAssistant {
|
||||
if editor.read(cx).selections.count() == 1 {
|
||||
let (selection, buffer) = editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.selections.newest::<usize>(cx),
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx)),
|
||||
editor.buffer().read(cx).snapshot(cx),
|
||||
)
|
||||
});
|
||||
@@ -829,7 +834,9 @@ impl InlineAssistant {
|
||||
if editor.read(cx).selections.count() == 1 {
|
||||
let (selection, buffer) = editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.selections.newest::<usize>(cx),
|
||||
editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx)),
|
||||
editor.buffer().read(cx).snapshot(cx),
|
||||
)
|
||||
});
|
||||
|
||||
@@ -431,9 +431,9 @@ impl TextThreadEditor {
|
||||
}
|
||||
|
||||
fn cursors(&self, cx: &mut App) -> Vec<usize> {
|
||||
let selections = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.selections.all::<usize>(cx));
|
||||
let selections = self.editor.update(cx, |editor, cx| {
|
||||
editor.selections.all::<usize>(&editor.display_snapshot(cx))
|
||||
});
|
||||
selections
|
||||
.into_iter()
|
||||
.map(|selection| selection.head())
|
||||
@@ -446,7 +446,10 @@ impl TextThreadEditor {
|
||||
editor.transact(window, cx, |editor, window, cx| {
|
||||
editor.change_selections(Default::default(), window, cx, |s| s.try_cancel());
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
let newest_cursor = editor.selections.newest::<Point>(cx).head();
|
||||
let newest_cursor = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
if newest_cursor.column > 0
|
||||
|| snapshot
|
||||
.chars_at(newest_cursor)
|
||||
@@ -1248,11 +1251,19 @@ impl TextThreadEditor {
|
||||
|
||||
let context_editor = context_editor_view.read(cx).editor.clone();
|
||||
context_editor.update(cx, |context_editor, cx| {
|
||||
if context_editor.selections.newest::<Point>(cx).is_empty() {
|
||||
let display_map = context_editor.display_snapshot(cx);
|
||||
if context_editor
|
||||
.selections
|
||||
.newest::<Point>(&display_map)
|
||||
.is_empty()
|
||||
{
|
||||
let snapshot = context_editor.buffer().read(cx).snapshot(cx);
|
||||
let (_, _, snapshot) = snapshot.as_singleton()?;
|
||||
|
||||
let head = context_editor.selections.newest::<Point>(cx).head();
|
||||
let head = context_editor
|
||||
.selections
|
||||
.newest::<Point>(&display_map)
|
||||
.head();
|
||||
let offset = snapshot.point_to_offset(head);
|
||||
|
||||
let surrounding_code_block_range = find_surrounding_code_block(snapshot, offset)?;
|
||||
@@ -1269,7 +1280,7 @@ impl TextThreadEditor {
|
||||
|
||||
(!text.is_empty()).then_some((text, true))
|
||||
} else {
|
||||
let selection = context_editor.selections.newest_adjusted(cx);
|
||||
let selection = context_editor.selections.newest_adjusted(&display_map);
|
||||
let buffer = context_editor.buffer().read(cx).snapshot(cx);
|
||||
let selected_text = buffer.text_for_range(selection.range()).collect::<String>();
|
||||
|
||||
@@ -1457,7 +1468,7 @@ impl TextThreadEditor {
|
||||
let selections = editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.selections
|
||||
.all_adjusted(cx)
|
||||
.all_adjusted(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.filter_map(|s| {
|
||||
(!s.is_empty())
|
||||
@@ -1489,7 +1500,10 @@ impl TextThreadEditor {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.insert("\n", window, cx);
|
||||
for (text, crease_title) in creases {
|
||||
let point = editor.selections.newest::<Point>(cx).head();
|
||||
let point = editor
|
||||
.selections
|
||||
.newest::<Point>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
let start_row = MultiBufferRow(point.row);
|
||||
|
||||
editor.insert(&text, window, cx);
|
||||
@@ -1561,7 +1575,9 @@ impl TextThreadEditor {
|
||||
cx: &mut Context<Self>,
|
||||
) -> (String, CopyMetadata, Vec<text::Selection<usize>>) {
|
||||
let (mut selection, creases) = self.editor.update(cx, |editor, cx| {
|
||||
let mut selection = editor.selections.newest_adjusted(cx);
|
||||
let mut selection = editor
|
||||
.selections
|
||||
.newest_adjusted(&editor.display_snapshot(cx));
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
selection.goal = SelectionGoal::None;
|
||||
@@ -1680,7 +1696,10 @@ impl TextThreadEditor {
|
||||
|
||||
if images.is_empty() {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
let paste_position = editor.selections.newest::<usize>(cx).head();
|
||||
let paste_position = editor
|
||||
.selections
|
||||
.newest::<usize>(&editor.display_snapshot(cx))
|
||||
.head();
|
||||
editor.paste(action, window, cx);
|
||||
|
||||
if let Some(metadata) = metadata {
|
||||
@@ -1727,13 +1746,13 @@ impl TextThreadEditor {
|
||||
editor.transact(window, cx, |editor, _window, cx| {
|
||||
let edits = editor
|
||||
.selections
|
||||
.all::<usize>(cx)
|
||||
.all::<usize>(&editor.display_snapshot(cx))
|
||||
.into_iter()
|
||||
.map(|selection| (selection.start..selection.end, "\n"));
|
||||
editor.edit(edits, cx);
|
||||
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
for selection in editor.selections.all::<usize>(cx) {
|
||||
for selection in editor.selections.all::<usize>(&editor.display_snapshot(cx)) {
|
||||
image_positions.push(snapshot.anchor_before(selection.end));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user