Add ability to bind to pane::RevealInProjectPanel (#7487)

Thorsten Ball and Antonio created

Previously it wasn't possible to create a keybinding for this action
because it required an argument.

Now the action takes the active item of the pane and if it's a
multi-buffer the first one.

This also adds a default keybinding for Vim mode: `-` will reveal the
file in the project panel.

Fixes #7485.

Release Notes:

- Added `pane::RevealInProjectPanel` as an action in the command
palette. ([#7485](https://github.com/zed-industries/zed/issues/7485)).

Co-authored-by: Antonio <antonio@zed.dev>

Change summary

assets/keymaps/vim.json      |  3 ++-
crates/editor/src/actions.rs |  2 +-
crates/workspace/src/pane.rs | 22 ++++++++++++++--------
3 files changed, 17 insertions(+), 10 deletions(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -284,7 +284,8 @@
       "ctrl-w o": "workspace::CloseInactiveTabsAndPanes",
       "ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
       "ctrl-w n": ["workspace::NewFileInDirection", "Up"],
-      "ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"]
+      "ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"],
+      "-": "pane::RevealInProjectPanel"
     }
   },
   {

crates/editor/src/actions.rs 🔗

@@ -112,7 +112,7 @@ impl_actions!(
         MoveUpByLines,
         MoveDownByLines,
         SelectUpByLines,
-        SelectDownByLines,
+        SelectDownByLines
     ]
 );
 

crates/workspace/src/pane.rs 🔗

@@ -72,10 +72,10 @@ pub struct CloseAllItems {
     pub save_intent: Option<SaveIntent>,
 }
 
-#[derive(Clone, PartialEq, Debug, Deserialize)]
+#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
 #[serde(rename_all = "camelCase")]
 pub struct RevealInProjectPanel {
-    pub entry_id: u64,
+    pub entry_id: Option<u64>,
 }
 
 impl_actions!(
@@ -1442,7 +1442,9 @@ impl Pane {
                         let entry_id = entry.to_proto();
                         menu = menu.separator().entry(
                             "Reveal In Project Panel",
-                            Some(Box::new(RevealInProjectPanel { entry_id })),
+                            Some(Box::new(RevealInProjectPanel {
+                                entry_id: Some(entry_id),
+                            })),
                             cx.handler_for(&pane, move |pane, cx| {
                                 pane.project.update(cx, |_, cx| {
                                     cx.emit(project::Event::RevealInProjectPanel(
@@ -1807,11 +1809,15 @@ impl Render for Pane {
             )
             .on_action(
                 cx.listener(|pane: &mut Self, action: &RevealInProjectPanel, cx| {
-                    pane.project.update(cx, |_, cx| {
-                        cx.emit(project::Event::RevealInProjectPanel(
-                            ProjectEntryId::from_proto(action.entry_id),
-                        ))
-                    })
+                    let entry_id = action
+                        .entry_id
+                        .map(ProjectEntryId::from_proto)
+                        .or_else(|| pane.active_item()?.project_entry_ids(cx).first().copied());
+                    if let Some(entry_id) = entry_id {
+                        pane.project.update(cx, |_, cx| {
+                            cx.emit(project::Event::RevealInProjectPanel(entry_id))
+                        });
+                    }
                 }),
             )
             .when(self.active_item().is_some(), |pane| {