Organize Project Panel context menus (#10456)

Nate Butler created

This design polish PR brings the project panel context menu into better
alignment with other editors, better follows system patterns and
identifies focus shifting actions with the `…` indicator (like adding a
new folder to a project, which will open a modal window.)

## Before & After:

**Root level**

![CleanShot - 2024-04-11 at 22 40
53@2x](https://github.com/zed-industries/zed/assets/1714999/aa103d14-0747-4be9-acbf-1c3ed0542a15)

**Folder level**

![CleanShot - 2024-04-11 at 22 43
45@2x](https://github.com/zed-industries/zed/assets/1714999/180224f2-26d1-45bd-8f78-822f46068a6d)

**File level**

![CleanShot - 2024-04-11 at 22 44
56@2x](https://github.com/zed-industries/zed/assets/1714999/67edd0ae-bcb6-4920-a480-c4d50c6bccfa)

Note: That double divider in the after has been fixed 😅

---

Release Notes:

- Improved ordering and organization of context menus in the project
panel to bring them closer to those in similar applications.

Change summary

crates/project_panel/src/project_panel.rs | 86 +++++++++++++-----------
1 file changed, 46 insertions(+), 40 deletions(-)

Detailed changes

crates/project_panel/src/project_panel.rs 🔗

@@ -419,48 +419,54 @@ impl ProjectPanel {
                             })
                     },
                     |menu| {
-                        menu.when(is_local, |menu| {
-                            menu.action(
-                                "Add Folder to Project",
-                                Box::new(workspace::AddFolderToProject),
-                            )
-                            .when(is_root, |menu| {
-                                menu.entry(
-                                    "Remove from Project",
-                                    None,
-                                    cx.handler_for(&this, move |this, cx| {
-                                        this.project.update(cx, |project, cx| {
-                                            project.remove_worktree(worktree_id, cx)
-                                        });
-                                    }),
-                                )
-                                .action("Collapse All", Box::new(CollapseAllEntries))
+                        menu.action("New File", Box::new(NewFile))
+                            .action("New Folder", Box::new(NewDirectory))
+                            .separator()
+                            .action("Reveal in Finder", Box::new(RevealInFinder))
+                            .when(is_dir, |menu| {
+                                menu.action("Open in Terminal…", Box::new(OpenInTerminal))
+                            })
+                            .when(is_dir, |menu| {
+                                menu.separator()
+                                    .action("Find in Folder…", Box::new(NewSearchInDirectory))
+                            })
+                            .separator()
+                            .action("Cut", Box::new(Cut))
+                            .action("Copy", Box::new(Copy))
+                            // TODO: Paste should always be visible, but disabled when clipboard is empty
+                            .when_some(self.clipboard_entry, |menu, entry| {
+                                menu.when(entry.worktree_id() == worktree_id, |menu| {
+                                    menu.action("Paste", Box::new(Paste))
+                                })
+                            })
+                            .separator()
+                            .action("Copy Path", Box::new(CopyPath))
+                            .action("Copy Relative Path", Box::new(CopyRelativePath))
+                            .separator()
+                            .action("Rename", Box::new(Rename))
+                            .when(!is_root, |menu| {
+                                menu.action("Delete", Box::new(Delete { skip_prompt: false }))
+                            })
+                            .when(is_local & is_root, |menu| {
+                                menu.separator()
+                                    .action(
+                                        "Add Folder to Project…",
+                                        Box::new(workspace::AddFolderToProject),
+                                    )
+                                    .entry(
+                                        "Remove from Project",
+                                        None,
+                                        cx.handler_for(&this, move |this, cx| {
+                                            this.project.update(cx, |project, cx| {
+                                                project.remove_worktree(worktree_id, cx)
+                                            });
+                                        }),
+                                    )
                             })
-                        })
-                        .action("New File", Box::new(NewFile))
-                        .action("New Folder", Box::new(NewDirectory))
-                        .separator()
-                        .action("Cut", Box::new(Cut))
-                        .action("Copy", Box::new(Copy))
-                        .when_some(self.clipboard_entry, |menu, entry| {
-                            menu.when(entry.worktree_id() == worktree_id, |menu| {
-                                menu.action("Paste", Box::new(Paste))
+                            .when(is_local & is_root, |menu| {
+                                menu.separator()
+                                    .action("Collapse All", Box::new(CollapseAllEntries))
                             })
-                        })
-                        .separator()
-                        .action("Copy Path", Box::new(CopyPath))
-                        .action("Copy Relative Path", Box::new(CopyRelativePath))
-                        .separator()
-                        .action("Reveal in Finder", Box::new(RevealInFinder))
-                        .when(is_dir, |menu| {
-                            menu.action("Open in Terminal", Box::new(OpenInTerminal))
-                                .action("Search Inside", Box::new(NewSearchInDirectory))
-                        })
-                        .separator()
-                        .action("Rename", Box::new(Rename))
-                        .when(!is_root, |menu| {
-                            menu.action("Delete", Box::new(Delete { skip_prompt: false }))
-                        })
                     },
                 )
             });