mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 19:10:24 +00:00
Locate the Zed app from the CLI using NSWorkspace API
This commit is contained in:
parent
43763fa2f8
commit
a81f7ebbf6
3 changed files with 43 additions and 12 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -998,10 +998,12 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 3.1.8",
|
||||
"cocoa",
|
||||
"core-foundation",
|
||||
"core-services",
|
||||
"dirs 3.0.1",
|
||||
"ipc-channel",
|
||||
"objc",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
|
|
@ -13,9 +13,13 @@ path = "src/main.rs"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
core-foundation = "0.9"
|
||||
core-services = "0.2"
|
||||
clap = { version = "3.1", features = ["derive"] }
|
||||
dirs = "3.0"
|
||||
ipc-channel = "0.16"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.24"
|
||||
core-foundation = "0.9"
|
||||
core-services = "0.2"
|
||||
objc = "0.2"
|
|
@ -8,7 +8,8 @@ use core_foundation::{
|
|||
};
|
||||
use core_services::{kLSLaunchDefaults, LSLaunchURLSpec, LSOpenFromURLSpec, TCFType};
|
||||
use ipc_channel::ipc::{IpcOneShotServer, IpcReceiver, IpcSender};
|
||||
use std::{fs, path::PathBuf, ptr};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use std::{ffi::CStr, fs, path::PathBuf, ptr};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(name = "zed")]
|
||||
|
@ -48,20 +49,46 @@ fn main() -> Result<()> {
|
|||
}
|
||||
|
||||
fn locate_app() -> Result<PathBuf> {
|
||||
Ok(std::env::current_exe()?
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("bundle/osx/Zed.app"))
|
||||
if cfg!(debug_assertions) {
|
||||
Ok(std::env::current_exe()?
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("bundle/osx/Zed.app"))
|
||||
} else {
|
||||
Ok(path_to_app_with_bundle_identifier("dev.zed.Zed")
|
||||
.unwrap_or_else(|| "/Applications/Zed.dev".into()))
|
||||
}
|
||||
}
|
||||
|
||||
fn path_to_app_with_bundle_identifier(bundle_id: &str) -> Option<PathBuf> {
|
||||
use cocoa::{
|
||||
base::{id, nil},
|
||||
foundation::{NSString, NSURL as _},
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace];
|
||||
let bundle_id = NSString::alloc(nil).init_str(bundle_id);
|
||||
let app_url: id = msg_send![workspace, URLForApplicationWithBundleIdentifier: bundle_id];
|
||||
if !app_url.is_null() {
|
||||
Some(PathBuf::from(
|
||||
CStr::from_ptr(app_url.path().UTF8String())
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn launch_app(app_path: PathBuf) -> Result<(IpcSender<CliRequest>, IpcReceiver<CliResponse>)> {
|
||||
let (server, server_name) = IpcOneShotServer::<IpcHandshake>::new()?;
|
||||
let url = format!("zed-cli://{server_name}");
|
||||
|
||||
let status = unsafe {
|
||||
let app_url =
|
||||
CFURL::from_path(&app_path, true).ok_or_else(|| anyhow!("invalid app path"))?;
|
||||
|
||||
let url = format!("zed-cli://{server_name}");
|
||||
let url_to_open = CFURL::wrap_under_create_rule(CFURLCreateWithBytes(
|
||||
ptr::null(),
|
||||
url.as_ptr(),
|
||||
|
@ -69,9 +96,7 @@ fn launch_app(app_path: PathBuf) -> Result<(IpcSender<CliRequest>, IpcReceiver<C
|
|||
kCFStringEncodingUTF8,
|
||||
ptr::null(),
|
||||
));
|
||||
|
||||
let urls_to_open = CFArray::from_copyable(&[url_to_open.as_concrete_TypeRef()]);
|
||||
|
||||
LSOpenFromURLSpec(
|
||||
&LSLaunchURLSpec {
|
||||
appURL: app_url.as_concrete_TypeRef(),
|
||||
|
|
Loading…
Reference in a new issue