diff --git a/Cargo.lock b/Cargo.lock index 30999e233d..b28d6fd4a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4724,6 +4724,7 @@ dependencies = [ "project", "rpc", "settings", + "shellexpand", "util", ] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 1f4568e0f9..12440819d0 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -36,6 +36,9 @@ struct Args { /// Custom Zed.app path #[arg(short, long)] bundle_path: Option, + /// Run zed in dev-server mode + #[arg(long)] + dev_server_token: Option, } fn parse_path_with_position( @@ -67,6 +70,10 @@ fn main() -> Result<()> { let bundle = Bundle::detect(args.bundle_path.as_deref()).context("Bundle detection")?; + if let Some(dev_server_token) = args.dev_server_token { + return bundle.spawn(vec!["--dev-server-token".into(), dev_server_token]); + } + if args.version { println!("{}", bundle.zed_version_string()); return Ok(()); @@ -169,6 +176,10 @@ mod linux { unimplemented!() } + pub fn spawn(&self, _args: Vec) -> anyhow::Result<()> { + unimplemented!() + } + pub fn zed_version_string(&self) -> String { unimplemented!() } @@ -202,6 +213,10 @@ mod windows { unimplemented!() } + pub fn spawn(&self, _args: Vec) -> anyhow::Result<()> { + unimplemented!() + } + pub fn zed_version_string(&self) -> String { unimplemented!() } @@ -217,7 +232,7 @@ mod mac_os { url::{CFURLCreateWithBytes, CFURL}, }; use core_services::{kLSLaunchDefaults, LSLaunchURLSpec, LSOpenFromURLSpec, TCFType}; - use std::{fs, path::Path, ptr}; + use std::{fs, path::Path, process::Command, ptr}; use cli::{CliRequest, CliResponse, IpcHandshake, FORCE_CLI_MODE_ENV_VAR_NAME}; use ipc_channel::ipc::{IpcOneShotServer, IpcReceiver, IpcSender}; @@ -278,6 +293,15 @@ mod mac_os { } } + pub fn spawn(&self, args: Vec) -> Result<()> { + let path = match self { + Self::App { app_bundle, .. } => app_bundle.join("Contents/MacOS/zed"), + Self::LocalPath { executable, .. } => executable.clone(), + }; + Command::new(path).args(args).status()?; + Ok(()) + } + pub fn launch(&self) -> anyhow::Result<(IpcSender, IpcReceiver)> { let (server, server_name) = IpcOneShotServer::::new().context("Handshake before Zed spawn")?; @@ -358,12 +382,12 @@ mod mac_os { ) } } + pub(super) fn spawn_channel_cli( channel: release_channel::ReleaseChannel, leftover_args: Vec, ) -> Result<()> { use anyhow::bail; - use std::process::Command; let app_id_prompt = format!("id of app \"{}\"", channel.display_name()); let app_id_output = Command::new("osascript") diff --git a/crates/headless/Cargo.toml b/crates/headless/Cargo.toml index 772f625a6f..28a213f79e 100644 --- a/crates/headless/Cargo.toml +++ b/crates/headless/Cargo.toml @@ -26,6 +26,7 @@ project.workspace = true fs.workspace = true futures.workspace = true settings.workspace = true +shellexpand.workspace = true postage.workspace = true [dev-dependencies] diff --git a/crates/headless/src/headless.rs b/crates/headless/src/headless.rs index 13e6cbb9fa..dd31360f91 100644 --- a/crates/headless/src/headless.rs +++ b/crates/headless/src/headless.rs @@ -180,7 +180,8 @@ impl DevServer { _: Arc, cx: AsyncAppContext, ) -> Result { - let path = std::path::Path::new(&envelope.payload.path); + let expanded = shellexpand::tilde(&envelope.payload.path).to_string(); + let path = std::path::Path::new(&expanded); let fs = cx.read_model(&this, |this, _| this.app_state.fs.clone())?; let path_exists = fs.is_dir(path).await; @@ -232,9 +233,11 @@ impl DevServer { (this.client.clone(), project) })?; + let path = shellexpand::tilde(&remote_project.path).to_string(); + project .update(cx, |project, cx| { - project.find_or_create_local_worktree(&remote_project.path, true, cx) + project.find_or_create_local_worktree(&path, true, cx) })? .await?;