Introduce reveal_path in Platform

Petros Amoiridis created

And implement it for MacPlatform, and instead of using an external process to run `open`, use the NSWorkspace selectFile instance method.

Change summary

crates/gpui/src/platform.rs               |  1 +
crates/gpui/src/platform/mac/platform.rs  | 13 +++++++++++++
crates/gpui/src/platform/test.rs          |  2 ++
crates/project_panel/src/project_panel.rs |  5 +++--
crates/util/src/lib.rs                    | 12 ------------
5 files changed, 19 insertions(+), 14 deletions(-)

Detailed changes

crates/gpui/src/platform.rs 🔗

@@ -65,6 +65,7 @@ pub trait Platform: Send + Sync {
     fn write_to_clipboard(&self, item: ClipboardItem);
     fn read_from_clipboard(&self) -> Option<ClipboardItem>;
     fn open_url(&self, url: &str);
+    fn reveal_path(&self, path: &Path);
 
     fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Result<()>;
     fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>>;

crates/gpui/src/platform/mac/platform.rs 🔗

@@ -599,6 +599,19 @@ impl platform::Platform for MacPlatform {
         }
     }
 
+    fn reveal_path(&self, path: &Path) {
+        unsafe {
+            let full_path = ns_string(path.to_str().unwrap_or(""));
+            let root_full_path = ns_string("");
+            let workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace];
+            msg_send![
+                workspace,
+                selectFile: full_path
+                inFileViewerRootedAtPath: root_full_path
+            ]
+        }
+    }
+
     fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Result<()> {
         let url = CFString::from(url);
         let username = CFString::from(username);

crates/gpui/src/platform/test.rs 🔗

@@ -173,6 +173,8 @@ impl super::Platform for Platform {
 
     fn open_url(&self, _: &str) {}
 
+    fn reveal_path(&self, _: &Path) {}
+
     fn write_credentials(&self, _: &str, _: &str, _: &[u8]) -> Result<()> {
         Ok(())
     }

crates/project_panel/src/project_panel.rs 🔗

@@ -791,8 +791,9 @@ impl ProjectPanel {
     }
 
     fn reveal_in_finder(&mut self, _: &RevealInFinder, cx: &mut ViewContext<Self>) {
-        if let Some((_worktree, entry)) = self.selected_entry(cx) {
-            util::reveal_in_finder(&entry.path);
+        if let Some((worktree, entry)) = self.selected_entry(cx) {
+            cx.platform()
+                .reveal_path(&worktree.abs_path().join(&entry.path));
         }
     }
 

crates/util/src/lib.rs 🔗

@@ -65,18 +65,6 @@ pub fn open<P: AsRef<Path>>(path: P) {
     }
 }
 
-pub fn reveal_in_finder<P: AsRef<Path>>(path: P) {
-    let path_to_reveal = path.as_ref().to_string_lossy();
-    #[cfg(target_os = "macos")]
-    {
-        std::process::Command::new("open")
-            .arg("-R") // To reveal in Finder instead of opening the file
-            .arg(path_to_reveal.as_ref())
-            .spawn()
-            .log_err();
-    }
-}
-
 pub fn post_inc<T: From<u8> + AddAssign<T> + Copy>(value: &mut T) -> T {
     let prev = *value;
     *value += T::from(1);