pane: Hide "Copy Relative Path" and "Reveal In Project Panel" actions for files outside of the projects (#25386)

Egor Krugletsov created

"Copy Relative Path" action had a check for existence of relative path
but it always passed because
[`WorktreeStore::find_worktree()`](https://github.com/zed-industries/zed/blob/1d5499bee72f1ea57ed883b942f05d5c1e7cec89/crates/project/src/worktree_store.rs#L148)
function returned empty path for these kinds of files. It feels correct
to make changes there, but I don't know what else could be impacted.

"Reveal In Project Panel" had no check whatsoever and so I made one.

Release Notes:

- N/A

Change summary

crates/workspace/src/pane.rs | 61 +++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 20 deletions(-)

Detailed changes

crates/workspace/src/pane.rs 🔗

@@ -2566,15 +2566,34 @@ impl Pane {
                         })
                     };
                     if let Some(entry) = single_entry_to_resolve {
+                        let project_path = pane
+                            .read(cx)
+                            .item_for_entry(entry, cx)
+                            .and_then(|item| item.project_path(cx));
+                        let worktree = project_path.as_ref().and_then(|project_path| {
+                            pane.read(cx)
+                                .project
+                                .upgrade()?
+                                .read(cx)
+                                .worktree_for_id(project_path.worktree_id, cx)
+                        });
+                        let has_relative_path = worktree.as_ref().is_some_and(|worktree| {
+                            worktree
+                                .read(cx)
+                                .root_entry()
+                                .map_or(false, |entry| entry.is_dir())
+                        });
+
                         let entry_abs_path = pane.read(cx).entry_abs_path(entry, cx);
                         let parent_abs_path = entry_abs_path
                             .as_deref()
                             .and_then(|abs_path| Some(abs_path.parent()?.to_path_buf()));
-                        let relative_path = pane
-                            .read(cx)
-                            .item_for_entry(entry, cx)
-                            .and_then(|item| item.project_path(cx))
-                            .map(|project_path| project_path.path);
+                        let relative_path = project_path
+                            .map(|project_path| project_path.path)
+                            .filter(|_| has_relative_path);
+
+                        let visible_in_project_panel = relative_path.is_some()
+                            && worktree.is_some_and(|worktree| worktree.read(cx).is_visible());
 
                         let entry_id = entry.to_proto();
                         menu = menu
@@ -2603,21 +2622,23 @@ impl Pane {
                             })
                             .map(pin_tab_entries)
                             .separator()
-                            .entry(
-                                "Reveal In Project Panel",
-                                Some(Box::new(RevealInProjectPanel {
-                                    entry_id: Some(entry_id),
-                                })),
-                                window.handler_for(&pane, move |pane, _, cx| {
-                                    pane.project
-                                        .update(cx, |_, cx| {
-                                            cx.emit(project::Event::RevealInProjectPanel(
-                                                ProjectEntryId::from_proto(entry_id),
-                                            ))
-                                        })
-                                        .ok();
-                                }),
-                            )
+                            .when(visible_in_project_panel, |menu| {
+                                menu.entry(
+                                    "Reveal In Project Panel",
+                                    Some(Box::new(RevealInProjectPanel {
+                                        entry_id: Some(entry_id),
+                                    })),
+                                    window.handler_for(&pane, move |pane, _, cx| {
+                                        pane.project
+                                            .update(cx, |_, cx| {
+                                                cx.emit(project::Event::RevealInProjectPanel(
+                                                    ProjectEntryId::from_proto(entry_id),
+                                                ))
+                                            })
+                                            .ok();
+                                    }),
+                                )
+                            })
                             .when_some(parent_abs_path, |menu, parent_abs_path| {
                                 menu.entry(
                                     "Open in Terminal",