Do less work when revealing entries in the outline panel (#20031)
Before this change, we were trying to determine current element before debouncing, causing a lot of extra work on caret movement. Now, we only do this for the task that managed to wait the entire debounce period. Closes https://github.com/zed-industries/zed/issues/19817 Closes https://github.com/zed-industries/zed/issues/14235 Release Notes: - Fixed outline panel-related performance issues when selections change in the large document ([#19817](https://github.com/zed-industries/zed/issues/19817)), ([#14235](https://github.com/zed-industries/zed/issues/14235))
This commit is contained in:
parent
9dad897d49
commit
f766f6ceae
1 changed files with 27 additions and 18 deletions
|
@ -1440,26 +1440,26 @@ impl OutlinePanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reveal_entry_for_selection(
|
fn reveal_entry_for_selection(&mut self, editor: View<Editor>, cx: &mut ViewContext<'_, Self>) {
|
||||||
&mut self,
|
|
||||||
editor: &View<Editor>,
|
|
||||||
cx: &mut ViewContext<'_, Self>,
|
|
||||||
) {
|
|
||||||
if !self.active {
|
if !self.active {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if !OutlinePanelSettings::get_global(cx).auto_reveal_entries {
|
if !OutlinePanelSettings::get_global(cx).auto_reveal_entries {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(entry_with_selection) = self.location_for_editor_selection(editor, cx) else {
|
|
||||||
self.selected_entry = SelectedEntry::None;
|
|
||||||
cx.notify();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let project = self.project.clone();
|
let project = self.project.clone();
|
||||||
self.reveal_selection_task = cx.spawn(|outline_panel, mut cx| async move {
|
self.reveal_selection_task = cx.spawn(|outline_panel, mut cx| async move {
|
||||||
cx.background_executor().timer(UPDATE_DEBOUNCE).await;
|
cx.background_executor().timer(UPDATE_DEBOUNCE).await;
|
||||||
|
let entry_with_selection = outline_panel.update(&mut cx, |outline_panel, cx| {
|
||||||
|
outline_panel.location_for_editor_selection(&editor, cx)
|
||||||
|
})?;
|
||||||
|
let Some(entry_with_selection) = entry_with_selection else {
|
||||||
|
outline_panel.update(&mut cx, |outline_panel, cx| {
|
||||||
|
outline_panel.selected_entry = SelectedEntry::None;
|
||||||
|
cx.notify();
|
||||||
|
})?;
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
let related_buffer_entry = match &entry_with_selection {
|
let related_buffer_entry = match &entry_with_selection {
|
||||||
PanelEntry::Fs(FsEntry::File(worktree_id, _, buffer_id, _)) => {
|
PanelEntry::Fs(FsEntry::File(worktree_id, _, buffer_id, _)) => {
|
||||||
project.update(&mut cx, |project, cx| {
|
project.update(&mut cx, |project, cx| {
|
||||||
|
@ -2436,7 +2436,7 @@ impl OutlinePanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn location_for_editor_selection(
|
fn location_for_editor_selection(
|
||||||
&mut self,
|
&self,
|
||||||
editor: &View<Editor>,
|
editor: &View<Editor>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Option<PanelEntry> {
|
) -> Option<PanelEntry> {
|
||||||
|
@ -2500,7 +2500,7 @@ impl OutlinePanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn outline_location(
|
fn outline_location(
|
||||||
&mut self,
|
&self,
|
||||||
buffer_id: BufferId,
|
buffer_id: BufferId,
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
multi_buffer_snapshot: editor::MultiBufferSnapshot,
|
multi_buffer_snapshot: editor::MultiBufferSnapshot,
|
||||||
|
@ -4321,7 +4321,7 @@ fn subscribe_for_editor_events(
|
||||||
editor,
|
editor,
|
||||||
move |outline_panel, editor, e: &EditorEvent, cx| match e {
|
move |outline_panel, editor, e: &EditorEvent, cx| match e {
|
||||||
EditorEvent::SelectionsChanged { local: true } => {
|
EditorEvent::SelectionsChanged { local: true } => {
|
||||||
outline_panel.reveal_entry_for_selection(&editor, cx);
|
outline_panel.reveal_entry_for_selection(editor, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
EditorEvent::ExcerptsAdded { excerpts, .. } => {
|
EditorEvent::ExcerptsAdded { excerpts, .. } => {
|
||||||
|
@ -4479,7 +4479,13 @@ mod tests {
|
||||||
cx.executor()
|
cx.executor()
|
||||||
.advance_clock(UPDATE_DEBOUNCE + Duration::from_millis(100));
|
.advance_clock(UPDATE_DEBOUNCE + Duration::from_millis(100));
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
outline_panel.update(cx, |outline_panel, _| {
|
outline_panel.update(cx, |outline_panel, cx| {
|
||||||
|
// Project search re-adds items to the buffer, removing the caret from it.
|
||||||
|
// Select the first entry and move 4 elements down.
|
||||||
|
for _ in 0..6 {
|
||||||
|
outline_panel.select_next(&SelectNext, cx);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
display_entries(
|
display_entries(
|
||||||
&outline_panel.cached_entries,
|
&outline_panel.cached_entries,
|
||||||
|
@ -4795,7 +4801,7 @@ mod tests {
|
||||||
r#"/
|
r#"/
|
||||||
public/lottie/
|
public/lottie/
|
||||||
syntax-tree.json
|
syntax-tree.json
|
||||||
search: { "something": "static" } <==== selected
|
search: { "something": "static" }
|
||||||
src/
|
src/
|
||||||
app/(site)/
|
app/(site)/
|
||||||
(about)/jobs/[slug]/
|
(about)/jobs/[slug]/
|
||||||
|
@ -4811,8 +4817,11 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
outline_panel.update(cx, |outline_panel, cx| {
|
outline_panel.update(cx, |outline_panel, cx| {
|
||||||
outline_panel.select_next(&SelectNext, cx);
|
// After the search is done, we have updated the outline panel contents and caret is not in any excerot, so there are no selections.
|
||||||
outline_panel.select_next(&SelectNext, cx);
|
// Move to 5th element in the list (0th action will selection the first element)
|
||||||
|
for _ in 0..6 {
|
||||||
|
outline_panel.select_next(&SelectNext, cx);
|
||||||
|
}
|
||||||
outline_panel.collapse_selected_entry(&CollapseSelectedEntry, cx);
|
outline_panel.collapse_selected_entry(&CollapseSelectedEntry, cx);
|
||||||
});
|
});
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue