Add right-click menu action to copy path in the breadcrumb button (#46483)

Danilo Leal created

This PR adds a right-click action to the breadcrumb button to copy the
path, when there is some (i.e., untitled buffers and others won't have
this feature).


https://github.com/user-attachments/assets/94ece12c-3071-4a07-a04d-8d89e10fd59e

Release Notes:

- Added the ability to right-click the breadcrumb button when it's a
file path and copy the path.

Change summary

crates/editor/src/element.rs | 58 +++++++++++++++++++++++++++++++------
1 file changed, 48 insertions(+), 10 deletions(-)

Detailed changes

crates/editor/src/element.rs 🔗

@@ -8012,6 +8012,8 @@ pub fn render_breadcrumb_text(
         .downcast::<Editor>()
         .map(|editor| editor.downgrade());
 
+    let has_project_path = active_item.project_path(cx).is_some();
+
     match editor {
         Some(editor) => element
             .id("breadcrumb_container")
@@ -8025,14 +8027,33 @@ pub fn render_breadcrumb_text(
                     .when(!multibuffer_header, |this| {
                         let focus_handle = editor.upgrade().unwrap().focus_handle(&cx);
 
-                        this.tooltip(move |_window, cx| {
-                            Tooltip::for_action_in(
-                                "Show Symbol Outline",
-                                &zed_actions::outline::ToggleOutline,
-                                &focus_handle,
-                                cx,
-                            )
-                        })
+                        this.tooltip(Tooltip::element(move |_window, cx| {
+                            v_flex()
+                                .gap_1()
+                                .child(
+                                    h_flex()
+                                        .gap_1()
+                                        .justify_between()
+                                        .child(Label::new("Show Symbol Outline"))
+                                        .child(ui::KeyBinding::for_action_in(
+                                            &zed_actions::outline::ToggleOutline,
+                                            &focus_handle,
+                                            cx,
+                                        )),
+                                )
+                                .when(has_project_path, |this| {
+                                    this.child(
+                                        h_flex()
+                                            .gap_1()
+                                            .justify_between()
+                                            .pt_1()
+                                            .border_t_1()
+                                            .border_color(cx.theme().colors().border_variant)
+                                            .child(Label::new("Right-Click to Copy Path")),
+                                    )
+                                })
+                                .into_any_element()
+                        }))
                         .on_click({
                             let editor = editor.clone();
                             move |_, window, cx| {
@@ -8044,12 +8065,29 @@ pub fn render_breadcrumb_text(
                                 }
                             }
                         })
+                        .when(has_project_path, |this| {
+                            this.on_right_click({
+                                let editor = editor.clone();
+                                move |_, _, cx| {
+                                    if let Some(abs_path) = editor.upgrade().and_then(|editor| {
+                                        editor.update(cx, |editor, cx| {
+                                            editor.target_file_abs_path(cx)
+                                        })
+                                    }) {
+                                        if let Some(path_str) = abs_path.to_str() {
+                                            cx.write_to_clipboard(ClipboardItem::new_string(
+                                                path_str.to_string(),
+                                            ));
+                                        }
+                                    }
+                                }
+                            })
+                        })
                     }),
             )
             .into_any_element(),
         None => element
-            // Match the height and padding of the `ButtonLike` in the other arm.
-            .h(rems_from_px(22.))
+            .h(rems_from_px(22.)) // Match the height and padding of the `ButtonLike` in the other arm.
             .pl_1()
             .child(breadcrumbs)
             .into_any_element(),