diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index e11c04755e59b7d62ea16340d6ed23bdb36daf6d..7f746a6ccd7efec2b73354992c593433b0b6f281 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -6053,12 +6053,27 @@ impl ProjectPanel { .worktree_for_entry(entry_id, cx) .context("can't reveal a non-existent entry in the project panel")?; let worktree = worktree.read(cx); - if skip_ignored - && worktree - .entry_for_id(entry_id) - .is_none_or(|entry| entry.is_ignored && !entry.is_always_included) - { - anyhow::bail!("can't reveal an ignored entry in the project panel"); + let worktree_id = worktree.id(); + let is_ignored = worktree + .entry_for_id(entry_id) + .is_none_or(|entry| entry.is_ignored && !entry.is_always_included); + if skip_ignored && is_ignored { + if self.index_for_entry(entry_id, worktree_id).is_none() { + anyhow::bail!("can't reveal an ignored entry in the project panel"); + } + + self.selection = Some(SelectedEntry { + worktree_id, + entry_id, + }); + self.marked_entries.clear(); + self.marked_entries.push(SelectedEntry { + worktree_id, + entry_id, + }); + self.autoscroll(cx); + cx.notify(); + return Ok(()); } let is_active_item_file_diff_view = self .workspace @@ -6070,7 +6085,6 @@ impl ProjectPanel { return Ok(()); } - let worktree_id = worktree.id(); self.expand_entry(worktree_id, entry_id, cx); self.update_visible_entries(Some((worktree_id, entry_id)), false, true, window, cx); self.marked_entries.clear(); diff --git a/crates/project_panel/src/project_panel_tests.rs b/crates/project_panel/src/project_panel_tests.rs index 01d165174784f4ab5360b99e16a514a4b8f669b4..af84a7f522a60abf2608bf1f3435b367d24f6bdc 100644 --- a/crates/project_panel/src/project_panel_tests.rs +++ b/crates/project_panel/src/project_panel_tests.rs @@ -4843,6 +4843,64 @@ async fn test_autoreveal_and_gitignored_files(cx: &mut gpui::TestAppContext) { ], "When a gitignored entry is explicitly revealed, it should be shown in the project tree" ); + + panel.update(cx, |panel, cx| { + panel.project.update(cx, |_, cx| { + cx.emit(project::Event::ActiveEntryChanged(Some(dir_2_file))) + }) + }); + cx.run_until_parked(); + assert_eq!( + visible_entries_as_strings(&panel, 0..20, cx), + &[ + "v project_root", + " > .git", + " v dir_1", + " v gitignored_dir", + " file_a.py", + " file_b.py", + " file_c.py", + " file_1.py", + " file_2.py", + " file_3.py", + " v dir_2", + " file_1.py <== selected <== marked", + " file_2.py", + " file_3.py", + " .gitignore", + ], + "After switching to dir_2_file, it should be selected and marked" + ); + + panel.update(cx, |panel, cx| { + panel.project.update(cx, |_, cx| { + cx.emit(project::Event::ActiveEntryChanged(Some( + gitignored_dir_file, + ))) + }) + }); + cx.run_until_parked(); + assert_eq!( + visible_entries_as_strings(&panel, 0..20, cx), + &[ + "v project_root", + " > .git", + " v dir_1", + " v gitignored_dir", + " file_a.py <== selected <== marked", + " file_b.py", + " file_c.py", + " file_1.py", + " file_2.py", + " file_3.py", + " v dir_2", + " file_1.py", + " file_2.py", + " file_3.py", + " .gitignore", + ], + "When a gitignored entry is already visible, auto reveal should mark it as selected" + ); } #[gpui::test]