diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 57e8f89539..4753450110 100644 --- a/crates/gpui/src/platform.rs +++ b/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; 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)>>; diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 3d57a7fe2a..ccbae5a832 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/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); diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 173c8d8505..cf0e31c2b8 100644 --- a/crates/gpui/src/platform/test.rs +++ b/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(()) } diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index e59353aae4..f2330dfd4f 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -119,6 +119,7 @@ actions!( AddFile, Copy, CopyPath, + RevealInFinder, Cut, Paste, Delete, @@ -147,6 +148,7 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(ProjectPanel::cancel); cx.add_action(ProjectPanel::copy); cx.add_action(ProjectPanel::copy_path); + cx.add_action(ProjectPanel::reveal_in_finder); cx.add_action(ProjectPanel::cut); cx.add_action( |this: &mut ProjectPanel, action: &Paste, cx: &mut ViewContext| { @@ -305,6 +307,7 @@ impl ProjectPanel { } menu_entries.push(ContextMenuItem::item("New File", AddFile)); menu_entries.push(ContextMenuItem::item("New Folder", AddDirectory)); + menu_entries.push(ContextMenuItem::item("Reveal in Finder", RevealInFinder)); menu_entries.push(ContextMenuItem::Separator); menu_entries.push(ContextMenuItem::item("Copy", Copy)); menu_entries.push(ContextMenuItem::item("Copy Path", CopyPath)); @@ -787,6 +790,13 @@ impl ProjectPanel { } } + fn reveal_in_finder(&mut self, _: &RevealInFinder, cx: &mut ViewContext) { + if let Some((worktree, entry)) = self.selected_entry(cx) { + cx.platform() + .reveal_path(&worktree.abs_path().join(&entry.path)); + } + } + fn move_entry( &mut self, &MoveProjectEntry { diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 65edf1b692..feed3d510f 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -32,17 +32,14 @@ use mappings::mouse::{ use procinfo::LocalProcessInfo; use settings::{AlternateScroll, Settings, Shell, TerminalBlink}; -use util::ResultExt; use std::{ cmp::min, collections::{HashMap, VecDeque}, fmt::Display, - io, ops::{Deref, Index, RangeInclusive, Sub}, - os::unix::{prelude::AsRawFd, process::CommandExt}, + os::unix::prelude::AsRawFd, path::PathBuf, - process::Command, sync::Arc, time::{Duration, Instant}, }; @@ -736,7 +733,7 @@ impl Terminal { if let Some((url, url_match)) = found_url { if *open { - open_uri(&url).log_err(); + cx.platform().open_url(url.as_str()); } else { self.update_hyperlink(prev_hyperlink, url, url_match); } @@ -1077,7 +1074,7 @@ impl Terminal { if self.selection_phase == SelectionPhase::Ended { let mouse_cell_index = content_index_for_mouse(position, &self.last_content); if let Some(link) = self.last_content.cells[mouse_cell_index].hyperlink() { - open_uri(link.uri()).log_err(); + cx.platform().open_url(link.uri()); } else { self.events .push_back(InternalEvent::FindHyperlink(position, true)); @@ -1236,31 +1233,6 @@ fn content_index_for_mouse<'a>(pos: Vector2F, content: &'a TerminalContent) -> u line * content.size.columns() + col } -fn open_uri(uri: &str) -> Result<(), std::io::Error> { - let mut command = Command::new("open"); - command.arg(uri); - - unsafe { - command - .pre_exec(|| { - match libc::fork() { - -1 => return Err(io::Error::last_os_error()), - 0 => (), - _ => libc::_exit(0), - } - - if libc::setsid() == -1 { - return Err(io::Error::last_os_error()); - } - - Ok(()) - }) - .spawn()? - .wait() - .map(|_| ()) - } -} - #[cfg(test)] mod tests { use alacritty_terminal::{ diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 72dec114d9..141a345382 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -121,7 +121,6 @@ impl Workspace { } pub mod simple_message_notification { - use std::process::Command; use gpui::{ actions, @@ -147,14 +146,8 @@ pub mod simple_message_notification { pub fn init(cx: &mut MutableAppContext) { cx.add_action(MessageNotification::dismiss); cx.add_action( - |_workspace: &mut Workspace, open_action: &OsOpen, _cx: &mut ViewContext| { - #[cfg(target_os = "macos")] - { - let mut command = Command::new("open"); - command.arg(open_action.0.clone()); - - command.spawn().ok(); - } + |_workspace: &mut Workspace, open_action: &OsOpen, cx: &mut ViewContext| { + cx.platform().open_url(open_action.0.as_str()); }, ) }