Detailed changes
@@ -1,112 +1,7 @@
-use anyhow::{Context as _, Result};
-use client::ZED_URL_SCHEME;
-use gpui::{AppContext as _, AsyncApp, Context, PromptLevel, Window, actions};
-use release_channel::ReleaseChannel;
-use std::ops::Deref;
-use std::path::{Path, PathBuf};
-use util::ResultExt;
-use workspace::notifications::{DetachAndPromptErr, NotificationId};
-use workspace::{Toast, Workspace};
+#[cfg(not(target_os = "windows"))]
+mod install_cli_binary;
+mod register_zed_scheme;
-actions!(
- cli,
- [
- /// Installs the Zed CLI tool to the system PATH.
- Install,
- /// Registers the zed:// URL scheme handler.
- RegisterZedScheme
- ]
-);
-
-async fn install_script(cx: &AsyncApp) -> Result<PathBuf> {
- let cli_path = cx.update(|cx| cx.path_for_auxiliary_executable("cli"))??;
- let link_path = Path::new("/usr/local/bin/zed");
- let bin_dir_path = link_path.parent().unwrap();
-
- // Don't re-create symlink if it points to the same CLI binary.
- if smol::fs::read_link(link_path).await.ok().as_ref() == Some(&cli_path) {
- return Ok(link_path.into());
- }
-
- // If the symlink is not there or is outdated, first try replacing it
- // without escalating.
- smol::fs::remove_file(link_path).await.log_err();
- // todo("windows")
- #[cfg(not(windows))]
- {
- if smol::fs::unix::symlink(&cli_path, link_path)
- .await
- .log_err()
- .is_some()
- {
- return Ok(link_path.into());
- }
- }
-
- // The symlink could not be created, so use osascript with admin privileges
- // to create it.
- let status = smol::process::Command::new("/usr/bin/osascript")
- .args([
- "-e",
- &format!(
- "do shell script \" \
- mkdir -p \'{}\' && \
- ln -sf \'{}\' \'{}\' \
- \" with administrator privileges",
- bin_dir_path.to_string_lossy(),
- cli_path.to_string_lossy(),
- link_path.to_string_lossy(),
- ),
- ])
- .stdout(smol::process::Stdio::inherit())
- .stderr(smol::process::Stdio::inherit())
- .output()
- .await?
- .status;
- anyhow::ensure!(status.success(), "error running osascript");
- Ok(link_path.into())
-}
-
-pub async fn register_zed_scheme(cx: &AsyncApp) -> anyhow::Result<()> {
- cx.update(|cx| cx.register_url_scheme(ZED_URL_SCHEME))?
- .await
-}
-
-pub fn install_cli(window: &mut Window, cx: &mut Context<Workspace>) {
- const LINUX_PROMPT_DETAIL: &str = "If you installed Zed from our official release add ~/.local/bin to your PATH.\n\nIf you installed Zed from a different source like your package manager, then you may need to create an alias/symlink manually.\n\nDepending on your package manager, the CLI might be named zeditor, zedit, zed-editor or something else.";
-
- cx.spawn_in(window, async move |workspace, cx| {
- if cfg!(any(target_os = "linux", target_os = "freebsd")) {
- let prompt = cx.prompt(
- PromptLevel::Warning,
- "CLI should already be installed",
- Some(LINUX_PROMPT_DETAIL),
- &["Ok"],
- );
- cx.background_spawn(prompt).detach();
- return Ok(());
- }
- let path = install_script(cx.deref())
- .await
- .context("error creating CLI symlink")?;
-
- workspace.update_in(cx, |workspace, _, cx| {
- struct InstalledZedCli;
-
- workspace.show_toast(
- Toast::new(
- NotificationId::unique::<InstalledZedCli>(),
- format!(
- "Installed `zed` to {}. You can launch {} from your terminal.",
- path.to_string_lossy(),
- ReleaseChannel::global(cx).display_name()
- ),
- ),
- cx,
- )
- })?;
- register_zed_scheme(cx).await.log_err();
- Ok(())
- })
- .detach_and_prompt_err("Error installing zed cli", window, cx, |_, _, _| None);
-}
+#[cfg(not(target_os = "windows"))]
+pub use install_cli_binary::{InstallCliBinary, install_cli_binary};
+pub use register_zed_scheme::{RegisterZedScheme, register_zed_scheme};
@@ -0,0 +1,101 @@
+use super::register_zed_scheme;
+use anyhow::{Context as _, Result};
+use gpui::{AppContext as _, AsyncApp, Context, PromptLevel, Window, actions};
+use release_channel::ReleaseChannel;
+use std::ops::Deref;
+use std::path::{Path, PathBuf};
+use util::ResultExt;
+use workspace::notifications::{DetachAndPromptErr, NotificationId};
+use workspace::{Toast, Workspace};
+
+actions!(
+ cli,
+ [
+ /// Installs the Zed CLI tool to the system PATH.
+ InstallCliBinary,
+ ]
+);
+
+async fn install_script(cx: &AsyncApp) -> Result<PathBuf> {
+ let cli_path = cx.update(|cx| cx.path_for_auxiliary_executable("cli"))??;
+ let link_path = Path::new("/usr/local/bin/zed");
+ let bin_dir_path = link_path.parent().unwrap();
+
+ // Don't re-create symlink if it points to the same CLI binary.
+ if smol::fs::read_link(link_path).await.ok().as_ref() == Some(&cli_path) {
+ return Ok(link_path.into());
+ }
+
+ // If the symlink is not there or is outdated, first try replacing it
+ // without escalating.
+ smol::fs::remove_file(link_path).await.log_err();
+ if smol::fs::unix::symlink(&cli_path, link_path)
+ .await
+ .log_err()
+ .is_some()
+ {
+ return Ok(link_path.into());
+ }
+
+ // The symlink could not be created, so use osascript with admin privileges
+ // to create it.
+ let status = smol::process::Command::new("/usr/bin/osascript")
+ .args([
+ "-e",
+ &format!(
+ "do shell script \" \
+ mkdir -p \'{}\' && \
+ ln -sf \'{}\' \'{}\' \
+ \" with administrator privileges",
+ bin_dir_path.to_string_lossy(),
+ cli_path.to_string_lossy(),
+ link_path.to_string_lossy(),
+ ),
+ ])
+ .stdout(smol::process::Stdio::inherit())
+ .stderr(smol::process::Stdio::inherit())
+ .output()
+ .await?
+ .status;
+ anyhow::ensure!(status.success(), "error running osascript");
+ Ok(link_path.into())
+}
+
+pub fn install_cli_binary(window: &mut Window, cx: &mut Context<Workspace>) {
+ const LINUX_PROMPT_DETAIL: &str = "If you installed Zed from our official release add ~/.local/bin to your PATH.\n\nIf you installed Zed from a different source like your package manager, then you may need to create an alias/symlink manually.\n\nDepending on your package manager, the CLI might be named zeditor, zedit, zed-editor or something else.";
+
+ cx.spawn_in(window, async move |workspace, cx| {
+ if cfg!(any(target_os = "linux", target_os = "freebsd")) {
+ let prompt = cx.prompt(
+ PromptLevel::Warning,
+ "CLI should already be installed",
+ Some(LINUX_PROMPT_DETAIL),
+ &["Ok"],
+ );
+ cx.background_spawn(prompt).detach();
+ return Ok(());
+ }
+ let path = install_script(cx.deref())
+ .await
+ .context("error creating CLI symlink")?;
+
+ workspace.update_in(cx, |workspace, _, cx| {
+ struct InstalledZedCli;
+
+ workspace.show_toast(
+ Toast::new(
+ NotificationId::unique::<InstalledZedCli>(),
+ format!(
+ "Installed `zed` to {}. You can launch {} from your terminal.",
+ path.to_string_lossy(),
+ ReleaseChannel::global(cx).display_name()
+ ),
+ ),
+ cx,
+ )
+ })?;
+ register_zed_scheme(cx).await.log_err();
+ Ok(())
+ })
+ .detach_and_prompt_err("Error installing zed cli", window, cx, |_, _, _| None);
+}
@@ -0,0 +1,15 @@
+use client::ZED_URL_SCHEME;
+use gpui::{AsyncApp, actions};
+
+actions!(
+ cli,
+ [
+ /// Registers the zed:// URL scheme handler.
+ RegisterZedScheme
+ ]
+);
+
+pub async fn register_zed_scheme(cx: &AsyncApp) -> anyhow::Result<()> {
+ cx.update(|cx| cx.register_url_scheme(ZED_URL_SCHEME))?
+ .await
+}
@@ -806,7 +806,6 @@ fn register_actions(
}
}
})
- .register_action(install_cli)
.register_action(|_, _: &install_cli::RegisterZedScheme, window, cx| {
cx.spawn_in(window, async move |workspace, cx| {
install_cli::register_zed_scheme(cx).await?;
@@ -915,6 +914,9 @@ fn register_actions(
capture_audio(workspace, window, cx);
});
+ #[cfg(not(target_os = "windows"))]
+ workspace.register_action(install_cli);
+
if workspace.project().read(cx).is_via_remote_server() {
workspace.register_action({
move |workspace, _: &OpenServerSettings, window, cx| {
@@ -1030,13 +1032,14 @@ fn about(
.detach();
}
+#[cfg(not(target_os = "windows"))]
fn install_cli(
_: &mut Workspace,
- _: &install_cli::Install,
+ _: &install_cli::InstallCliBinary,
window: &mut Window,
cx: &mut Context<Workspace>,
) {
- install_cli::install_cli(window, cx);
+ install_cli::install_cli_binary(window, cx)
}
static WAITING_QUIT_CONFIRMATION: AtomicBool = AtomicBool::new(false);
@@ -39,7 +39,8 @@ pub fn app_menus() -> Vec<Menu> {
MenuItem::os_submenu("Services", gpui::SystemMenuType::Services),
MenuItem::separator(),
MenuItem::action("Extensions", zed_actions::Extensions::default()),
- MenuItem::action("Install CLI", install_cli::Install),
+ #[cfg(not(target_os = "windows"))]
+ MenuItem::action("Install CLI", install_cli::InstallCliBinary),
MenuItem::separator(),
#[cfg(target_os = "macos")]
MenuItem::action("Hide Zed", super::Hide),