mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-25 19:29:49 +00:00
Add a command for installing the CLI
This commit is contained in:
parent
eee1cec3d4
commit
fbd1afc51f
4 changed files with 49 additions and 39 deletions
|
@ -54,8 +54,7 @@ pub trait Platform: Send + Sync {
|
|||
fn set_cursor_style(&self, style: CursorStyle);
|
||||
|
||||
fn local_timezone(&self) -> UtcOffset;
|
||||
|
||||
fn path_for_resource(&self, name: Option<&str>, extension: Option<&str>) -> Result<PathBuf>;
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf>;
|
||||
}
|
||||
|
||||
pub(crate) trait ForegroundPlatform {
|
||||
|
|
|
@ -14,9 +14,7 @@ use cocoa::{
|
|||
NSPasteboardTypeString, NSSavePanel, NSWindow,
|
||||
},
|
||||
base::{id, nil, selector, YES},
|
||||
foundation::{
|
||||
NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSString, NSUInteger, NSURL,
|
||||
},
|
||||
foundation::{NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSString, NSURL},
|
||||
};
|
||||
use core_foundation::{
|
||||
base::{CFType, CFTypeRef, OSStatus, TCFType as _},
|
||||
|
@ -38,8 +36,8 @@ use ptr::null_mut;
|
|||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
convert::TryInto,
|
||||
ffi::{c_void, CStr},
|
||||
os::raw::c_char,
|
||||
ffi::{c_void, CStr, OsStr},
|
||||
os::{raw::c_char, unix::ffi::OsStrExt},
|
||||
path::{Path, PathBuf},
|
||||
ptr,
|
||||
rc::Rc,
|
||||
|
@ -48,9 +46,6 @@ use std::{
|
|||
};
|
||||
use time::UtcOffset;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSUTF8StringEncoding: NSUInteger = 4;
|
||||
|
||||
const MAC_PLATFORM_IVAR: &'static str = "platform";
|
||||
static mut APP_CLASS: *const Class = ptr::null();
|
||||
static mut APP_DELEGATE_CLASS: *const Class = ptr::null();
|
||||
|
@ -274,10 +269,9 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
for i in 0..urls.count() {
|
||||
let url = urls.objectAtIndex(i);
|
||||
if url.isFileURL() == YES {
|
||||
let path = std::ffi::CStr::from_ptr(url.path().UTF8String())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
result.push(PathBuf::from(path));
|
||||
if let Ok(path) = ns_url_to_path(url) {
|
||||
result.push(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(result)
|
||||
|
@ -305,19 +299,13 @@ impl platform::ForegroundPlatform for MacForegroundPlatform {
|
|||
let (done_tx, done_rx) = oneshot::channel();
|
||||
let done_tx = Cell::new(Some(done_tx));
|
||||
let block = ConcreteBlock::new(move |response: NSModalResponse| {
|
||||
let result = if response == NSModalResponse::NSModalResponseOk {
|
||||
let mut result = None;
|
||||
if response == NSModalResponse::NSModalResponseOk {
|
||||
let url = panel.URL();
|
||||
if url.isFileURL() == YES {
|
||||
let path = std::ffi::CStr::from_ptr(url.path().UTF8String())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
Some(PathBuf::from(path))
|
||||
} else {
|
||||
None
|
||||
result = ns_url_to_path(panel.URL()).ok()
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
if let Some(mut done_tx) = done_tx.take() {
|
||||
let _ = postage::sink::Sink::try_send(&mut done_tx, result);
|
||||
|
@ -612,22 +600,18 @@ impl platform::Platform for MacPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
fn path_for_resource(&self, name: Option<&str>, extension: Option<&str>) -> Result<PathBuf> {
|
||||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = name.map_or(nil, |name| ns_string(name));
|
||||
let extension = extension.map_or(nil, |extension| ns_string(extension));
|
||||
let path: id = msg_send![bundle, pathForResource: name ofType: extension];
|
||||
if path.is_null() {
|
||||
Err(anyhow!("resource could not be found"))
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
let len = msg_send![path, lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
|
||||
let bytes = path.UTF8String() as *const u8;
|
||||
let path = str::from_utf8(slice::from_raw_parts(bytes, len)).unwrap();
|
||||
Ok(PathBuf::from(path))
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -717,9 +701,7 @@ extern "C" fn open_urls(this: &mut Object, _: Sel, _: id, urls: id) {
|
|||
.into_iter()
|
||||
.filter_map(|i| {
|
||||
let path = urls.objectAtIndex(i);
|
||||
match dbg!(
|
||||
CStr::from_ptr(path.absoluteString().UTF8String() as *mut c_char).to_str()
|
||||
) {
|
||||
match CStr::from_ptr(path.absoluteString().UTF8String() as *mut c_char).to_str() {
|
||||
Ok(string) => Some(string.to_string()),
|
||||
Err(err) => {
|
||||
log::error!("error converting path to string: {}", err);
|
||||
|
@ -754,6 +736,20 @@ unsafe fn ns_string(string: &str) -> id {
|
|||
NSString::alloc(nil).init_str(string).autorelease()
|
||||
}
|
||||
|
||||
unsafe fn ns_url_to_path(url: id) -> Result<PathBuf> {
|
||||
let path: *mut c_char = msg_send![url, fileSystemRepresentation];
|
||||
if path.is_null() {
|
||||
Err(anyhow!(
|
||||
"url is not a file path: {}",
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
))
|
||||
} else {
|
||||
Ok(PathBuf::from(OsStr::from_bytes(
|
||||
CStr::from_ptr(path).to_bytes(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
mod security {
|
||||
#![allow(non_upper_case_globals)]
|
||||
use super::*;
|
||||
|
|
|
@ -163,7 +163,7 @@ impl super::Platform for Platform {
|
|||
UtcOffset::UTC
|
||||
}
|
||||
|
||||
fn path_for_resource(&self, _name: Option<&str>, _extension: Option<&str>) -> Result<PathBuf> {
|
||||
fn path_for_auxiliary_executable(&self, _name: &str) -> Result<PathBuf> {
|
||||
Err(anyhow!("app not running inside a bundle"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ actions!(
|
|||
DebugElements,
|
||||
OpenSettings,
|
||||
IncreaseBufferFontSize,
|
||||
DecreaseBufferFontSize
|
||||
DecreaseBufferFontSize,
|
||||
InstallCommandLineTool,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -66,6 +67,20 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
|
|||
cx.refresh_windows();
|
||||
});
|
||||
});
|
||||
cx.add_global_action(move |_: &InstallCommandLineTool, cx| {
|
||||
cx.spawn(|cx| async move {
|
||||
let path = cx.platform().path_for_auxiliary_executable("cli")?;
|
||||
let link_path = "/usr/local/bin/zed";
|
||||
smol::fs::unix::symlink(link_path, path.as_path()).await?;
|
||||
log::info!(
|
||||
"created symlink {} -> {}",
|
||||
link_path,
|
||||
path.to_string_lossy()
|
||||
);
|
||||
Ok::<_, anyhow::Error>(())
|
||||
})
|
||||
.detach();
|
||||
});
|
||||
cx.add_action({
|
||||
let app_state = app_state.clone();
|
||||
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
|
||||
|
|
Loading…
Reference in a new issue