diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index 6ffac21021..7de8872c64 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -1440,26 +1440,26 @@ impl OutlinePanel { } } - fn reveal_entry_for_selection( - &mut self, - editor: &View, - cx: &mut ViewContext<'_, Self>, - ) { + fn reveal_entry_for_selection(&mut self, editor: View, 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, cx: &mut ViewContext, ) -> Option { @@ -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| { - outline_panel.select_next(&SelectNext, 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. + // 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); }); cx.run_until_parked();