mirror of
https://github.com/zed-industries/zed.git
synced 2024-10-23 06:56:33 +00:00
Add ability to open files with system default application (#17231)
This commit is contained in:
parent
06142f975b
commit
ae3880e71a
10 changed files with 63 additions and 1 deletions
|
@ -553,6 +553,7 @@
|
|||
"ctrl-backspace": ["project_panel::Delete", { "skip_prompt": false }],
|
||||
"ctrl-delete": ["project_panel::Delete", { "skip_prompt": false }],
|
||||
"alt-ctrl-r": "project_panel::RevealInFileManager",
|
||||
"ctrl-shift-enter": "project_panel::OpenWithSystem",
|
||||
"alt-shift-f": "project_panel::NewSearchInDirectory",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
|
|
|
@ -563,8 +563,8 @@
|
|||
"cmd-backspace": ["project_panel::Trash", { "skip_prompt": true }],
|
||||
"cmd-delete": ["project_panel::Delete", { "skip_prompt": false }],
|
||||
"alt-cmd-r": "project_panel::RevealInFileManager",
|
||||
"ctrl-shift-enter": "project_panel::OpenWithSystem",
|
||||
"cmd-alt-backspace": ["project_panel::Delete", { "skip_prompt": false }],
|
||||
|
||||
"alt-shift-f": "project_panel::NewSearchInDirectory",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
|
|
|
@ -493,6 +493,7 @@
|
|||
"v": "project_panel::OpenPermanent",
|
||||
"p": "project_panel::Open",
|
||||
"x": "project_panel::RevealInFileManager",
|
||||
"s": "project_panel::OpenWithSystem",
|
||||
"shift-g": "menu::SelectLast",
|
||||
"g g": "menu::SelectFirst",
|
||||
"-": "project_panel::SelectParent",
|
||||
|
|
|
@ -657,6 +657,11 @@ impl AppContext {
|
|||
self.platform.reveal_path(path)
|
||||
}
|
||||
|
||||
/// Opens the specified path with the system's default application.
|
||||
pub fn open_with_system(&self, path: &Path) {
|
||||
self.platform.open_with_system(path)
|
||||
}
|
||||
|
||||
/// Returns whether the user has configured scrollbars to auto-hide at the platform level.
|
||||
pub fn should_auto_hide_scrollbars(&self) -> bool {
|
||||
self.platform.should_auto_hide_scrollbars()
|
||||
|
|
|
@ -149,6 +149,7 @@ pub(crate) trait Platform: 'static {
|
|||
) -> oneshot::Receiver<Result<Option<Vec<PathBuf>>>>;
|
||||
fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Result<Option<PathBuf>>>;
|
||||
fn reveal_path(&self, path: &Path);
|
||||
fn open_with_system(&self, path: &Path);
|
||||
|
||||
fn on_quit(&self, callback: Box<dyn FnMut()>);
|
||||
fn on_reopen(&self, callback: Box<dyn FnMut()>);
|
||||
|
|
|
@ -351,6 +351,19 @@ impl<P: LinuxClient + 'static> Platform for P {
|
|||
self.reveal_path(path.to_owned());
|
||||
}
|
||||
|
||||
fn open_with_system(&self, path: &Path) {
|
||||
let executor = self.background_executor().clone();
|
||||
let path = path.to_owned();
|
||||
executor
|
||||
.spawn(async move {
|
||||
let _ = std::process::Command::new("xdg-open")
|
||||
.arg(path)
|
||||
.spawn()
|
||||
.expect("Failed to open file with xdg-open");
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn on_quit(&self, callback: Box<dyn FnMut()>) {
|
||||
self.with_common(|common| {
|
||||
common.callbacks.quit = Some(callback);
|
||||
|
|
|
@ -718,6 +718,20 @@ impl Platform for MacPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
fn open_with_system(&self, path: &Path) {
|
||||
let path = path.to_path_buf();
|
||||
self.0
|
||||
.lock()
|
||||
.background_executor
|
||||
.spawn(async move {
|
||||
std::process::Command::new("open")
|
||||
.arg(path)
|
||||
.spawn()
|
||||
.expect("Failed to open file");
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn on_quit(&self, callback: Box<dyn FnMut()>) {
|
||||
self.0.lock().quit = Some(callback);
|
||||
}
|
||||
|
|
|
@ -318,6 +318,10 @@ impl Platform for TestPlatform {
|
|||
fn register_url_scheme(&self, _: &str) -> Task<anyhow::Result<()>> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn open_with_system(&self, _path: &Path) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
|
|
|
@ -400,6 +400,19 @@ impl Platform for WindowsPlatform {
|
|||
.detach();
|
||||
}
|
||||
|
||||
fn open_with_system(&self, path: &Path) {
|
||||
let executor = self.background_executor().clone();
|
||||
let path = path.to_owned();
|
||||
executor
|
||||
.spawn(async move {
|
||||
let _ = std::process::Command::new("cmd")
|
||||
.args(&["/c", "start", "", path.to_str().expect("path to string")])
|
||||
.spawn()
|
||||
.expect("Failed to open file");
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn on_quit(&self, callback: Box<dyn FnMut()>) {
|
||||
self.state.borrow_mut().callbacks.quit = Some(callback);
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ actions!(
|
|||
CopyRelativePath,
|
||||
Duplicate,
|
||||
RevealInFileManager,
|
||||
OpenWithSystem,
|
||||
Cut,
|
||||
Paste,
|
||||
Rename,
|
||||
|
@ -500,6 +501,7 @@ impl ProjectPanel {
|
|||
.when(cfg!(not(target_os = "macos")), |menu| {
|
||||
menu.action("Reveal in File Manager", Box::new(RevealInFileManager))
|
||||
})
|
||||
.action("Open in Default App", Box::new(OpenWithSystem))
|
||||
.action("Open in Terminal", Box::new(OpenInTerminal))
|
||||
.when(is_dir, |menu| {
|
||||
menu.separator()
|
||||
|
@ -1497,6 +1499,13 @@ impl ProjectPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn open_system(&mut self, _: &OpenWithSystem, cx: &mut ViewContext<Self>) {
|
||||
if let Some((worktree, entry)) = self.selected_entry(cx) {
|
||||
let abs_path = worktree.abs_path().join(&entry.path);
|
||||
cx.open_with_system(&abs_path);
|
||||
}
|
||||
}
|
||||
|
||||
fn open_in_terminal(&mut self, _: &OpenInTerminal, cx: &mut ViewContext<Self>) {
|
||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||
let abs_path = worktree.abs_path().join(&entry.path);
|
||||
|
@ -2711,6 +2720,7 @@ impl Render for ProjectPanel {
|
|||
})
|
||||
.when(project.is_local_or_ssh(), |el| {
|
||||
el.on_action(cx.listener(Self::reveal_in_finder))
|
||||
.on_action(cx.listener(Self::open_system))
|
||||
.on_action(cx.listener(Self::open_in_terminal))
|
||||
})
|
||||
.on_mouse_down(
|
||||
|
|
Loading…
Reference in a new issue