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(
|
||||
&mut self,
|
||||
editor: &View<Editor>,
|
||||
cx: &mut ViewContext<'_, Self>,
|
||||
) {
|
||||
fn reveal_entry_for_selection(&mut self, editor: View<Editor>, cx: &mut ViewContext<'_, Self>) {
|
||||
if !self.active {
|
||||
return;
|
||||
}
|
||||
if !OutlinePanelSettings::get_global(cx).auto_reveal_entries {
|
||||
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();
|
||||
self.reveal_selection_task = cx.spawn(|outline_panel, mut cx| async move {
|
||||
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 {
|
||||
PanelEntry::Fs(FsEntry::File(worktree_id, _, buffer_id, _)) => {
|
||||
project.update(&mut cx, |project, cx| {
|
||||
|
@ -2436,7 +2436,7 @@ impl OutlinePanel {
|
|||
}
|
||||
|
||||
fn location_for_editor_selection(
|
||||
&mut self,
|
||||
&self,
|
||||
editor: &View<Editor>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<PanelEntry> {
|
||||
|
@ -2500,7 +2500,7 @@ impl OutlinePanel {
|
|||
}
|
||||
|
||||
fn outline_location(
|
||||
&mut self,
|
||||
&self,
|
||||
buffer_id: BufferId,
|
||||
excerpt_id: ExcerptId,
|
||||
multi_buffer_snapshot: editor::MultiBufferSnapshot,
|
||||
|
@ -4321,7 +4321,7 @@ fn subscribe_for_editor_events(
|
|||
editor,
|
||||
move |outline_panel, editor, e: &EditorEvent, cx| match e {
|
||||
EditorEvent::SelectionsChanged { local: true } => {
|
||||
outline_panel.reveal_entry_for_selection(&editor, cx);
|
||||
outline_panel.reveal_entry_for_selection(editor, cx);
|
||||
cx.notify();
|
||||
}
|
||||
EditorEvent::ExcerptsAdded { excerpts, .. } => {
|
||||
|
@ -4479,7 +4479,13 @@ mod tests {
|
|||
cx.executor()
|
||||
.advance_clock(UPDATE_DEBOUNCE + Duration::from_millis(100));
|
||||
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!(
|
||||
display_entries(
|
||||
&outline_panel.cached_entries,
|
||||
|
@ -4795,7 +4801,7 @@ mod tests {
|
|||
r#"/
|
||||
public/lottie/
|
||||
syntax-tree.json
|
||||
search: { "something": "static" } <==== selected
|
||||
search: { "something": "static" }
|
||||
src/
|
||||
app/(site)/
|
||||
(about)/jobs/[slug]/
|
||||
|
@ -4811,8 +4817,11 @@ mod tests {
|
|||
});
|
||||
|
||||
outline_panel.update(cx, |outline_panel, 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.
|
||||
// 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.select_next(&SelectNext, cx);
|
||||
}
|
||||
outline_panel.collapse_selected_entry(&CollapseSelectedEntry, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue