editor: Improve performance of update_visible_edit_prediction (#44161)
One half of https://github.com/zed-industries/zed/issues/42861 This basically reduces the main thread work for large enough json (and other) files from multiple milliseconds (15ms was observed in that test case) down to microseconds (100ms here). Release Notes: - Improved cursor movement performance when edit predictions are enabled
This commit is contained in:
@@ -182,7 +182,7 @@ use std::{
|
||||
iter::{self, Peekable},
|
||||
mem,
|
||||
num::NonZeroU32,
|
||||
ops::{Deref, DerefMut, Not, Range, RangeInclusive},
|
||||
ops::{ControlFlow, Deref, DerefMut, Not, Range, RangeInclusive},
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::Arc,
|
||||
@@ -8073,10 +8073,17 @@ impl Editor {
|
||||
|
||||
if self.edit_prediction_indent_conflict {
|
||||
let cursor_point = cursor.to_point(&multibuffer);
|
||||
let mut suggested_indent = None;
|
||||
multibuffer.suggested_indents_callback(
|
||||
cursor_point.row..cursor_point.row + 1,
|
||||
|_, indent| {
|
||||
suggested_indent = Some(indent);
|
||||
ControlFlow::Break(())
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
let indents = multibuffer.suggested_indents(cursor_point.row..cursor_point.row + 1, cx);
|
||||
|
||||
if let Some((_, indent)) = indents.iter().next()
|
||||
if let Some(indent) = suggested_indent
|
||||
&& indent.len == cursor_point.column
|
||||
{
|
||||
self.edit_prediction_indent_conflict = false;
|
||||
|
||||
@@ -43,7 +43,7 @@ use std::{
|
||||
io,
|
||||
iter::{self, FromIterator},
|
||||
mem,
|
||||
ops::{self, AddAssign, Range, RangeBounds, Sub, SubAssign},
|
||||
ops::{self, AddAssign, ControlFlow, Range, RangeBounds, Sub, SubAssign},
|
||||
rc::Rc,
|
||||
str,
|
||||
sync::Arc,
|
||||
@@ -4618,7 +4618,24 @@ impl MultiBufferSnapshot {
|
||||
cx: &App,
|
||||
) -> BTreeMap<MultiBufferRow, IndentSize> {
|
||||
let mut result = BTreeMap::new();
|
||||
self.suggested_indents_callback(
|
||||
rows,
|
||||
|row, indent| {
|
||||
result.insert(row, indent);
|
||||
ControlFlow::Continue(())
|
||||
},
|
||||
cx,
|
||||
);
|
||||
result
|
||||
}
|
||||
|
||||
// move this to be a generator once those are a thing
|
||||
pub fn suggested_indents_callback(
|
||||
&self,
|
||||
rows: impl IntoIterator<Item = u32>,
|
||||
mut cb: impl FnMut(MultiBufferRow, IndentSize) -> ControlFlow<()>,
|
||||
cx: &App,
|
||||
) {
|
||||
let mut rows_for_excerpt = Vec::new();
|
||||
let mut cursor = self.cursor::<Point, Point>();
|
||||
let mut rows = rows.into_iter().peekable();
|
||||
@@ -4662,16 +4679,17 @@ impl MultiBufferSnapshot {
|
||||
let buffer_indents = region
|
||||
.buffer
|
||||
.suggested_indents(buffer_rows, single_indent_size);
|
||||
let multibuffer_indents = buffer_indents.into_iter().map(|(row, indent)| {
|
||||
(
|
||||
for (row, indent) in buffer_indents {
|
||||
if cb(
|
||||
MultiBufferRow(start_multibuffer_row + row - start_buffer_row),
|
||||
indent,
|
||||
)
|
||||
});
|
||||
result.extend(multibuffer_indents);
|
||||
.is_break()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn indent_size_for_line(&self, row: MultiBufferRow) -> IndentSize {
|
||||
|
||||
Reference in New Issue
Block a user