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
+32 -13
View File
@@ -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));
}
});