From 43763fa2f86ed3b85a3e47ad2ac7e6d8369857f4 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 19 Apr 2022 11:32:46 -0700 Subject: [PATCH] Allow opening paths from the CLI Co-Authored-By: Antonio Scandurra --- Cargo.lock | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/main.rs | 6 ++-- crates/zed/src/main.rs | 73 ++++++++++++++++++++++++------------------ 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69c75fef67..05382c74ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1000,6 +1000,7 @@ dependencies = [ "clap 3.1.8", "core-foundation", "core-services", + "dirs 3.0.1", "ipc-channel", "serde", ] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 011ed9caa1..367db26c8c 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -16,5 +16,6 @@ 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"] } \ No newline at end of file diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 2977f97ad3..6620f3d08b 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -48,8 +48,10 @@ fn main() -> Result<()> { } fn locate_app() -> Result { - Ok("/Users/nathan/src/zed/target/debug/bundle/osx/Zed.app".into()) - // Ok("/Applications/Zed.app".into()) + Ok(std::env::current_exe()? + .parent() + .unwrap() + .join("bundle/osx/Zed.app")) } fn launch_app(app_path: PathBuf) -> Result<(IpcSender, IpcReceiver)> { diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 03ceef3a43..6a6dc5ef49 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -13,7 +13,7 @@ use futures::{ channel::{mpsc, oneshot}, SinkExt, StreamExt, }; -use gpui::{App, AssetSource, Task}; +use gpui::{App, AssetSource, AsyncAppContext, Task}; use log::LevelFilter; use parking_lot::Mutex; use project::Fs; @@ -94,32 +94,14 @@ fn main() { }) }; - app.on_open_urls(|urls, cx| { + let (cli_connections_tx, mut cli_connections_rx) = mpsc::unbounded(); + app.on_open_urls(move |urls, _| { if let Some(server_name) = urls.first().and_then(|url| url.strip_prefix("zed-cli://")) { - if let Some((mut requests, responses)) = connect_to_cli(server_name).log_err() { - cx.spawn(|_| async move { - for request in requests.next().await { - match request { - CliRequest::Open { paths, wait } => { - if wait { - todo!(); - } - - log::info!("open paths {:?}", paths); - responses - .send(CliResponse::Stdout { - message: "Hello CLI!".to_string(), - }) - .log_err(); - responses.send(CliResponse::Exit { status: 0 }).log_err(); - - // TODO... get rid of AppState so we can do this here? - // cx.update(|cx| open_paths(&paths, app_state, cx)); - } - } - } - }) - .detach(); + if let Some(cli_connection) = connect_to_cli(server_name).log_err() { + cli_connections_tx + .unbounded_send(cli_connection) + .map_err(|_| anyhow!("no listener for cli connections")) + .log_err(); }; } }); @@ -207,13 +189,25 @@ fn main() { if stdout_is_a_pty() { cx.platform().activate(true); - } - - let paths = collect_path_args(); - if paths.is_empty() { - cx.dispatch_global_action(OpenNew(app_state.clone())); + let paths = collect_path_args(); + if paths.is_empty() { + cx.dispatch_global_action(OpenNew(app_state.clone())); + } else { + cx.dispatch_global_action(OpenPaths { paths, app_state }); + } } else { - cx.dispatch_global_action(OpenPaths { paths, app_state }); + if let Ok(Some(connection)) = cli_connections_rx.try_next() { + cx.spawn(|cx| handle_cli_connection(connection, app_state.clone(), cx)) + .detach(); + } else { + cx.dispatch_global_action(OpenNew(app_state.clone())); + } + cx.spawn(|cx| async move { + while let Some(connection) = cli_connections_rx.next().await { + handle_cli_connection(connection, app_state.clone(), cx.clone()).await; + } + }) + .detach(); } }); } @@ -358,3 +352,18 @@ fn connect_to_cli( Ok((async_request_rx, response_tx)) } + +async fn handle_cli_connection( + (mut requests, responses): (mpsc::Receiver, IpcSender), + app_state: Arc, + mut cx: AsyncAppContext, +) { + if let Some(request) = requests.next().await { + match request { + CliRequest::Open { paths, .. } => { + cx.update(|cx| cx.dispatch_global_action(OpenPaths { paths, app_state })); + responses.send(CliResponse::Exit { status: 0 }).log_err(); + } + } + } +}