Reduce render allocations and redundant work in core components
This commit is contained in:
@@ -462,10 +462,10 @@ fn render_row(
|
||||
line_height: Pixels,
|
||||
cx: &App,
|
||||
) -> gpui::AnyElement {
|
||||
let line = code.code().lines.get(line_ix).cloned().unwrap_or_default();
|
||||
let line = code.code().lines.get(line_ix);
|
||||
|
||||
let mut text = String::new();
|
||||
for span in &line.spans {
|
||||
for span in line.map_or(&[][..], |line| line.spans.as_slice()) {
|
||||
text.push_str(&span.text);
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ fn render_row(
|
||||
let mut roles = vec![Role::Text; char_count];
|
||||
let mut offset = 0usize;
|
||||
|
||||
for span in &line.spans {
|
||||
for span in line.map_or(&[][..], |line| line.spans.as_slice()) {
|
||||
let chars = span.text.chars().count();
|
||||
for slot in &mut roles[offset..offset + chars] {
|
||||
*slot = span.role;
|
||||
@@ -543,10 +543,7 @@ fn render_row(
|
||||
};
|
||||
|
||||
div()
|
||||
.debug_selector({
|
||||
let name = format!("{id}-row-{line_ix}");
|
||||
move || name
|
||||
})
|
||||
.debug_selector(move || format!("{id}-row-{line_ix}"))
|
||||
.id(("code-row", line_ix))
|
||||
.w_full()
|
||||
.h(line_height)
|
||||
|
||||
@@ -237,6 +237,8 @@ pub fn diff_rows(old: &str, new: &str, language: Language) -> Vec<DiffRow> {
|
||||
pub struct DiffViewState {
|
||||
id: ElementId,
|
||||
rows: Vec<DiffRow>,
|
||||
/// The row whose width drives horizontal scroll extent, `rows`-derived.
|
||||
widest_row: Option<usize>,
|
||||
options: DiffViewOptions,
|
||||
/// Drives both scroll axes of the virtualized row list.
|
||||
handle: UniformListScrollHandle,
|
||||
@@ -251,13 +253,32 @@ impl DiffViewState {
|
||||
O: AsRef<str>,
|
||||
N: AsRef<str>,
|
||||
{
|
||||
Self {
|
||||
let mut state = Self {
|
||||
id: id.into(),
|
||||
rows: diff_rows(old.as_ref(), new.as_ref(), language),
|
||||
rows: Vec::new(),
|
||||
widest_row: None,
|
||||
options: DiffViewOptions::default(),
|
||||
handle: UniformListScrollHandle::new(),
|
||||
a11y_label: None,
|
||||
}
|
||||
};
|
||||
state.set_rows(old, new, language);
|
||||
state
|
||||
}
|
||||
|
||||
/// Replaces the rows, recomputing `widest_row` with them.
|
||||
fn set_rows<O, N>(&mut self, old: O, new: N, language: Language)
|
||||
where
|
||||
O: AsRef<str>,
|
||||
N: AsRef<str>,
|
||||
{
|
||||
self.rows = diff_rows(old.as_ref(), new.as_ref(), language);
|
||||
self.widest_row = self
|
||||
.rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, row)| row.kind != DiffRowKind::Hunk)
|
||||
.max_by_key(|(_, row)| row.char_count())
|
||||
.map(|(ix, _)| ix);
|
||||
}
|
||||
|
||||
/// Sets how changed rows are marked.
|
||||
@@ -284,7 +305,7 @@ impl DiffViewState {
|
||||
O: AsRef<str>,
|
||||
N: AsRef<str>,
|
||||
{
|
||||
self.rows = diff_rows(old.as_ref(), new.as_ref(), language);
|
||||
self.set_rows(old, new, language);
|
||||
self.handle.scroll_to_item(0, ScrollStrategy::Top);
|
||||
// The replaced versions rarely share the old width; start at the left.
|
||||
let offset = ScrollbarHandle::offset(&self.handle);
|
||||
@@ -328,14 +349,7 @@ impl Render for DiffViewState {
|
||||
let state = cx.entity();
|
||||
let row_count = self.rows.len();
|
||||
let options = self.options;
|
||||
|
||||
let widest_row = self
|
||||
.rows
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, row)| row.kind != DiffRowKind::Hunk)
|
||||
.max_by_key(|(_, row)| row.char_count())
|
||||
.map(|(ix, _)| ix);
|
||||
let widest_row = self.widest_row;
|
||||
|
||||
let mut rows = uniform_list((id.clone(), "rows"), row_count, {
|
||||
move |range, _window, cx| {
|
||||
|
||||
@@ -784,8 +784,8 @@ fn block_frame(
|
||||
let theme = cx.theme();
|
||||
let content = div()
|
||||
.debug_selector({
|
||||
let name = SharedString::from(format!("{id}"));
|
||||
move || name.to_string()
|
||||
let id = id.clone();
|
||||
move || id.to_string()
|
||||
})
|
||||
.w_full()
|
||||
.flex()
|
||||
|
||||
Reference in New Issue
Block a user