mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-09 21:26:14 +03:00
Locate the Zed app from the CLI using NSWorkspace API
This commit is contained in:
parent
43763fa2f8
commit
a81f7ebbf6
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -998,10 +998,12 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap 3.1.8",
|
"clap 3.1.8",
|
||||||
|
"cocoa",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"core-services",
|
"core-services",
|
||||||
"dirs 3.0.1",
|
"dirs 3.0.1",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
"objc",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -13,9 +13,13 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
core-foundation = "0.9"
|
|
||||||
core-services = "0.2"
|
|
||||||
clap = { version = "3.1", features = ["derive"] }
|
clap = { version = "3.1", features = ["derive"] }
|
||||||
dirs = "3.0"
|
dirs = "3.0"
|
||||||
ipc-channel = "0.16"
|
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 core_services::{kLSLaunchDefaults, LSLaunchURLSpec, LSOpenFromURLSpec, TCFType};
|
||||||
use ipc_channel::ipc::{IpcOneShotServer, IpcReceiver, IpcSender};
|
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)]
|
#[derive(Parser)]
|
||||||
#[clap(name = "zed")]
|
#[clap(name = "zed")]
|
||||||
@ -48,20 +49,46 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn locate_app() -> Result<PathBuf> {
|
fn locate_app() -> Result<PathBuf> {
|
||||||
Ok(std::env::current_exe()?
|
if cfg!(debug_assertions) {
|
||||||
.parent()
|
Ok(std::env::current_exe()?
|
||||||
.unwrap()
|
.parent()
|
||||||
.join("bundle/osx/Zed.app"))
|
.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>)> {
|
fn launch_app(app_path: PathBuf) -> Result<(IpcSender<CliRequest>, IpcReceiver<CliResponse>)> {
|
||||||
let (server, server_name) = IpcOneShotServer::<IpcHandshake>::new()?;
|
let (server, server_name) = IpcOneShotServer::<IpcHandshake>::new()?;
|
||||||
|
let url = format!("zed-cli://{server_name}");
|
||||||
|
|
||||||
let status = unsafe {
|
let status = unsafe {
|
||||||
let app_url =
|
let app_url =
|
||||||
CFURL::from_path(&app_path, true).ok_or_else(|| anyhow!("invalid app path"))?;
|
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(
|
let url_to_open = CFURL::wrap_under_create_rule(CFURLCreateWithBytes(
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
url.as_ptr(),
|
url.as_ptr(),
|
||||||
@ -69,9 +96,7 @@ fn launch_app(app_path: PathBuf) -> Result<(IpcSender<CliRequest>, IpcReceiver<C
|
|||||||
kCFStringEncodingUTF8,
|
kCFStringEncodingUTF8,
|
||||||
ptr::null(),
|
ptr::null(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let urls_to_open = CFArray::from_copyable(&[url_to_open.as_concrete_TypeRef()]);
|
let urls_to_open = CFArray::from_copyable(&[url_to_open.as_concrete_TypeRef()]);
|
||||||
|
|
||||||
LSOpenFromURLSpec(
|
LSOpenFromURLSpec(
|
||||||
&LSLaunchURLSpec {
|
&LSLaunchURLSpec {
|
||||||
appURL: app_url.as_concrete_TypeRef(),
|
appURL: app_url.as_concrete_TypeRef(),
|
||||||
|
Loading…
Reference in New Issue
Block a user