Centralize the `CopyPath` and `CopyRelativePath` actions to `zed_actions` (#24836)

Mikayla Maki created

I spent an hour with @marcospb19 this morning debugging an issue with
adding `Copy Path` and `Copy Relative Path` actions to the editor
context menu. Turned out that the problem was using
`workspace::CopyPath` in the menu and `editor::CopyPath` in the action
handler.

This is an easy mistake to make, so let's fix it for everyone.

Release Notes:

- N/A

Change summary

Cargo.lock                                |  3 ++
assets/keymaps/default-linux.json         |  8 +++---
assets/keymaps/default-macos.json         |  8 +++---
crates/editor/src/actions.rs              |  2 -
crates/editor/src/editor.rs               |  9 ++++++-
crates/outline_panel/Cargo.toml           |  1 
crates/outline_panel/src/outline_panel.rs | 23 ++++++++++++++++-----
crates/project_panel/Cargo.toml           |  1 
crates/project_panel/src/project_panel.rs | 23 ++++++++++++++++-----
crates/workspace/Cargo.toml               |  1 
crates/workspace/src/pane.rs              |  8 +++---
crates/workspace/src/workspace.rs         |  2 -
crates/zed_actions/src/lib.rs             | 26 ++++++++++++++++++++++++
13 files changed, 84 insertions(+), 31 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -8984,6 +8984,7 @@ dependencies = [
  "util",
  "workspace",
  "worktree",
+ "zed_actions",
 ]
 
 [[package]]
@@ -10179,6 +10180,7 @@ dependencies = [
  "util",
  "workspace",
  "worktree",
+ "zed_actions",
 ]
 
 [[package]]
@@ -16248,6 +16250,7 @@ dependencies = [
  "ui",
  "util",
  "uuid",
+ "zed_actions",
 ]
 
 [[package]]

assets/keymaps/default-linux.json 🔗

@@ -650,8 +650,8 @@
       "right": "outline_panel::ExpandSelectedEntry",
       "alt-copy": "outline_panel::CopyPath",
       "ctrl-alt-c": "outline_panel::CopyPath",
-      "alt-shift-copy": "outline_panel::CopyRelativePath",
-      "alt-ctrl-shift-c": "outline_panel::CopyRelativePath",
+      "alt-shift-copy": "workspace::CopyRelativePath",
+      "alt-ctrl-shift-c": "workspace::CopyRelativePath",
       "alt-ctrl-r": "outline_panel::RevealInFileManager",
       "space": "outline_panel::Open",
       "shift-down": "menu::SelectNext",
@@ -679,8 +679,8 @@
       "ctrl-v": "project_panel::Paste",
       "alt-copy": "project_panel::CopyPath",
       "ctrl-alt-c": "project_panel::CopyPath",
-      "alt-shift-copy": "project_panel::CopyRelativePath",
-      "alt-ctrl-shift-c": "project_panel::CopyRelativePath",
+      "alt-shift-copy": "workspace::CopyRelativePath",
+      "alt-ctrl-shift-c": "workspace::CopyRelativePath",
       "enter": "project_panel::Rename",
       "f2": "project_panel::Rename",
       "backspace": ["project_panel::Trash", { "skip_prompt": false }],

assets/keymaps/default-macos.json 🔗

@@ -670,8 +670,8 @@
       "escape": "menu::Cancel",
       "left": "outline_panel::CollapseSelectedEntry",
       "right": "outline_panel::ExpandSelectedEntry",
-      "cmd-alt-c": "outline_panel::CopyPath",
-      "alt-cmd-shift-c": "outline_panel::CopyRelativePath",
+      "cmd-alt-c": "workspace::CopyPath",
+      "alt-cmd-shift-c": "workspace::CopyRelativePath",
       "alt-cmd-r": "outline_panel::RevealInFileManager",
       "space": "outline_panel::Open",
       "shift-down": "menu::SelectNext",
@@ -692,8 +692,8 @@
       "cmd-x": "project_panel::Cut",
       "cmd-c": "project_panel::Copy",
       "cmd-v": "project_panel::Paste",
-      "cmd-alt-c": "project_panel::CopyPath",
-      "alt-cmd-shift-c": "project_panel::CopyRelativePath",
+      "cmd-alt-c": "workspace::CopyPath",
+      "alt-cmd-shift-c": "workspace::CopyRelativePath",
       "enter": "project_panel::Rename",
       "f2": "project_panel::Rename",
       "backspace": ["project_panel::Trash", { "skip_prompt": false }],

crates/editor/src/actions.rs 🔗

@@ -267,9 +267,7 @@ gpui::actions!(
         CopyHighlightJson,
         CopyFileName,
         CopyFileNameWithoutExtension,
-        CopyPath,
         CopyPermalinkToLine,
-        CopyRelativePath,
         Cut,
         CutToEndOfLine,
         Delete,

crates/editor/src/editor.rs 🔗

@@ -13106,7 +13106,12 @@ impl Editor {
         }
     }
 
-    pub fn copy_path(&mut self, _: &CopyPath, _window: &mut Window, cx: &mut Context<Self>) {
+    pub fn copy_path(
+        &mut self,
+        _: &zed_actions::workspace::CopyPath,
+        _window: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
         if let Some(path) = self.target_file_abs_path(cx) {
             if let Some(path) = path.to_str() {
                 cx.write_to_clipboard(ClipboardItem::new_string(path.to_string()));
@@ -13116,7 +13121,7 @@ impl Editor {
 
     pub fn copy_relative_path(
         &mut self,
-        _: &CopyRelativePath,
+        _: &zed_actions::workspace::CopyRelativePath,
         _window: &mut Window,
         cx: &mut Context<Self>,
     ) {

crates/outline_panel/Cargo.toml 🔗

@@ -38,6 +38,7 @@ ui.workspace = true
 util.workspace = true
 workspace.workspace = true
 worktree.workspace = true
+zed_actions.workspace = true
 
 [dev-dependencies]
 search = { workspace = true, features = ["test-support"] }

crates/outline_panel/src/outline_panel.rs 🔗

@@ -67,8 +67,6 @@ actions!(
     [
         CollapseAllEntries,
         CollapseSelectedEntry,
-        CopyPath,
-        CopyRelativePath,
         ExpandAllEntries,
         ExpandSelectedEntry,
         FoldDirectory,
@@ -1361,8 +1359,11 @@ impl OutlinePanel {
                     menu.action("Fold Directory", Box::new(FoldDirectory))
                 })
                 .separator()
-                .action("Copy Path", Box::new(CopyPath))
-                .action("Copy Relative Path", Box::new(CopyRelativePath))
+                .action("Copy Path", Box::new(zed_actions::workspace::CopyPath))
+                .action(
+                    "Copy Relative Path",
+                    Box::new(zed_actions::workspace::CopyRelativePath),
+                )
         });
         window.focus(&context_menu.focus_handle(cx));
         let subscription = cx.subscribe(&context_menu, |outline_panel, _, _: &DismissEvent, cx| {
@@ -1827,7 +1828,12 @@ impl OutlinePanel {
         })
     }
 
-    fn copy_path(&mut self, _: &CopyPath, _: &mut Window, cx: &mut Context<Self>) {
+    fn copy_path(
+        &mut self,
+        _: &zed_actions::workspace::CopyPath,
+        _: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
         if let Some(clipboard_text) = self
             .selected_entry()
             .and_then(|entry| self.abs_path(entry, cx))
@@ -1837,7 +1843,12 @@ impl OutlinePanel {
         }
     }
 
-    fn copy_relative_path(&mut self, _: &CopyRelativePath, _: &mut Window, cx: &mut Context<Self>) {
+    fn copy_relative_path(
+        &mut self,
+        _: &zed_actions::workspace::CopyRelativePath,
+        _: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
         if let Some(clipboard_text) = self
             .selected_entry()
             .and_then(|entry| match entry {

crates/project_panel/Cargo.toml 🔗

@@ -39,6 +39,7 @@ client.workspace = true
 worktree.workspace = true
 workspace.workspace = true
 language.workspace = true
+zed_actions.workspace = true
 
 [dev-dependencies]
 client = { workspace = true, features = ["test-support"] }

crates/project_panel/src/project_panel.rs 🔗

@@ -186,8 +186,6 @@ actions!(
         NewDirectory,
         NewFile,
         Copy,
-        CopyPath,
-        CopyRelativePath,
         Duplicate,
         RevealInFileManager,
         RemoveFromProject,
@@ -730,8 +728,11 @@ impl ProjectPanel {
                                 }
                             })
                             .separator()
-                            .action("Copy Path", Box::new(CopyPath))
-                            .action("Copy Relative Path", Box::new(CopyRelativePath))
+                            .action("Copy Path", Box::new(zed_actions::workspace::CopyPath))
+                            .action(
+                                "Copy Relative Path",
+                                Box::new(zed_actions::workspace::CopyRelativePath),
+                            )
                             .separator()
                             .when(!is_root || !cfg!(target_os = "windows"), |menu| {
                                 menu.action("Rename", Box::new(Rename))
@@ -2161,7 +2162,12 @@ impl ProjectPanel {
         self.paste(&Paste {}, window, cx);
     }
 
-    fn copy_path(&mut self, _: &CopyPath, _: &mut Window, cx: &mut Context<Self>) {
+    fn copy_path(
+        &mut self,
+        _: &zed_actions::workspace::CopyPath,
+        _: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
         let abs_file_paths = {
             let project = self.project.read(cx);
             self.effective_entries()
@@ -2185,7 +2191,12 @@ impl ProjectPanel {
         }
     }
 
-    fn copy_relative_path(&mut self, _: &CopyRelativePath, _: &mut Window, cx: &mut Context<Self>) {
+    fn copy_relative_path(
+        &mut self,
+        _: &zed_actions::workspace::CopyRelativePath,
+        _: &mut Window,
+        cx: &mut Context<Self>,
+    ) {
         let file_paths = {
             let project = self.project.read(cx);
             self.effective_entries()

crates/workspace/Cargo.toml 🔗

@@ -63,6 +63,7 @@ theme.workspace = true
 ui.workspace = true
 util.workspace = true
 uuid.workspace = true
+zed_actions.workspace = true
 
 [dev-dependencies]
 call = { workspace = true, features = ["test-support"] }

crates/workspace/src/pane.rs 🔗

@@ -7,8 +7,8 @@ use crate::{
     notifications::NotifyResultExt,
     toolbar::Toolbar,
     workspace_settings::{AutosaveSetting, TabBarSettings, WorkspaceSettings},
-    CloseWindow, CopyPath, CopyRelativePath, NewFile, NewTerminal, OpenInTerminal, OpenTerminal,
-    OpenVisible, SplitDirection, ToggleFileFinder, ToggleProjectSymbols, ToggleZoom, Workspace,
+    CloseWindow, NewFile, NewTerminal, OpenInTerminal, OpenTerminal, OpenVisible, SplitDirection,
+    ToggleFileFinder, ToggleProjectSymbols, ToggleZoom, Workspace,
 };
 use anyhow::Result;
 use collections::{BTreeSet, HashMap, HashSet, VecDeque};
@@ -2552,7 +2552,7 @@ impl Pane {
                             .when_some(entry_abs_path, |menu, abs_path| {
                                 menu.entry(
                                     "Copy Path",
-                                    Some(Box::new(CopyPath)),
+                                    Some(Box::new(zed_actions::workspace::CopyPath)),
                                     window.handler_for(&pane, move |_, _, cx| {
                                         cx.write_to_clipboard(ClipboardItem::new_string(
                                             abs_path.to_string_lossy().to_string(),
@@ -2563,7 +2563,7 @@ impl Pane {
                             .when_some(relative_path, |menu, relative_path| {
                                 menu.entry(
                                     "Copy Relative Path",
-                                    Some(Box::new(CopyRelativePath)),
+                                    Some(Box::new(zed_actions::workspace::CopyRelativePath)),
                                     window.handler_for(&pane, move |_, _, cx| {
                                         cx.write_to_clipboard(ClipboardItem::new_string(
                                             relative_path.to_string_lossy().to_string(),

crates/workspace/src/workspace.rs 🔗

@@ -133,8 +133,6 @@ actions!(
         ClearAllNotifications,
         CloseAllDocks,
         CloseWindow,
-        CopyPath,
-        CopyRelativePath,
         Feedback,
         FollowNextCollaborator,
         MoveFocusedPanelToNextPosition,

crates/zed_actions/src/lib.rs 🔗

@@ -43,10 +43,34 @@ actions!(
         ResetBufferFontSize,
         DecreaseUiFontSize,
         IncreaseUiFontSize,
-        ResetUiFontSize
+        ResetUiFontSize,
     ]
 );
 
+pub mod workspace {
+    use gpui::action_with_deprecated_aliases;
+
+    action_with_deprecated_aliases!(
+        workspace,
+        CopyPath,
+        [
+            "editor::CopyPath",
+            "outline_panel::CopyPath",
+            "project_panel::CopyPath"
+        ]
+    );
+
+    action_with_deprecated_aliases!(
+        workspace,
+        CopyRelativePath,
+        [
+            "editor::CopyRelativePath",
+            "outline_panel::CopyRelativePath",
+            "project_panel::CopyRelativePath"
+        ]
+    );
+}
+
 pub mod git {
     use gpui::action_with_deprecated_aliases;