project_panel: Reveal in file manager when no entry is selected (#50866)
Closes #48284 ## Summary - Fix `project_panel::RevealInFileManager` when no project panel entry is selected. - Preserve existing selected entry behavior. - Add fallback to reveal the last visible worktree root when selection is empty. - Add regression test cov. ## Root Cause `RevealInFileManager` previously depended on `selected_sub_entry()`. When selection is cleared (e.g. click project panel background), Command Palette dispatch had no target and no-op'd. ## Verification - `cargo fmt --all -- --check` - `./script/check-keymaps` - `./script/clippy -p project_panel` - `cargo test -p project_panel -- --nocapture` ## Manual Testing - Reproduced issue steps from #48284. - Confirmed Command Palette `Project panel: Reveal in file manager` now opens project root when selection is empty. - Confirmed selected file reveal behavior remains unchanged. - Confirmed context menu reveal behavior remains unchanged. Release Notes: - Fixed `Project panel: Reveal in file manager` to work even when no project panel entry is selected.
This commit is contained in:
1 parent
d1a323b4ac
commit
8fa257bbe0
2 files changed
+64
-2
No files matched your search
@@ -3403,8 +3403,7 @@ impl ProjectPanel {
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||
let path = worktree.read(cx).absolutize(&entry.path);
|
||||
if let Some(path) = self.reveal_in_file_manager_path(cx) {
|
||||
self.project
|
||||
.update(cx, |project, cx| project.reveal_path(&path, cx));
|
||||
}
|
||||
@@ -3761,6 +3760,20 @@ impl ProjectPanel {
|
||||
}
|
||||
Some((worktree, entry))
|
||||
}
|
||||
|
||||
fn reveal_in_file_manager_path(&self, cx: &App) -> Option<PathBuf> {
|
||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||
return Some(worktree.read(cx).absolutize(&entry.path));
|
||||
}
|
||||
|
||||
let root_entry_id = self.state.last_worktree_root_id?;
|
||||
let project = self.project.read(cx);
|
||||
let worktree = project.worktree_for_entry(root_entry_id, cx)?;
|
||||
let worktree = worktree.read(cx);
|
||||
let root_entry = worktree.entry_for_id(root_entry_id)?;
|
||||
Some(worktree.absolutize(&root_entry.path))
|
||||
}
|
||||
|
||||
fn selected_entry_handle<'a>(
|
||||
&self,
|
||||
cx: &'a App,
|
||||
|
||||
@@ -8670,6 +8670,55 @@ async fn test_compare_files_context_menu(cx: &mut gpui::TestAppContext) {
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_reveal_in_file_manager_path_falls_back_to_worktree_root(
|
||||
cx: &mut gpui::TestAppContext,
|
||||
) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/root",
|
||||
json!({
|
||||
"file.txt": "content",
|
||||
"dir": {},
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let window = cx.add_window(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx));
|
||||
let workspace = window
|
||||
.read_with(cx, |mw, _| mw.workspace().clone())
|
||||
.unwrap();
|
||||
let cx = &mut VisualTestContext::from_window(window.into(), cx);
|
||||
let panel = workspace.update_in(cx, ProjectPanel::new);
|
||||
cx.run_until_parked();
|
||||
|
||||
select_path(&panel, "root/file.txt", cx);
|
||||
let selected_reveal_path = panel
|
||||
.update(cx, |panel, cx| panel.reveal_in_file_manager_path(cx))
|
||||
.expect("selected entry should produce a reveal path");
|
||||
assert!(
|
||||
selected_reveal_path.ends_with(Path::new("file.txt")),
|
||||
"Expected selected file path, got {:?}",
|
||||
selected_reveal_path
|
||||
);
|
||||
|
||||
panel.update(cx, |panel, _| {
|
||||
panel.selection = None;
|
||||
panel.marked_entries.clear();
|
||||
});
|
||||
let fallback_reveal_path = panel
|
||||
.update(cx, |panel, cx| panel.reveal_in_file_manager_path(cx))
|
||||
.expect("project root should be used when selection is empty");
|
||||
assert!(
|
||||
fallback_reveal_path.ends_with(Path::new("root")),
|
||||
"Expected worktree root path, got {:?}",
|
||||
fallback_reveal_path
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_hide_hidden_entries(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
Reference in new issue
Block a user