diff --git a/crates/remote/src/remote_client.rs b/crates/remote/src/remote_client.rs index 0b4eed025e6c1e..ac2f3537b1ebb3 100644 --- a/crates/remote/src/remote_client.rs +++ b/crates/remote/src/remote_client.rs @@ -1275,6 +1275,21 @@ impl RemoteConnectionOptions { RemoteConnectionOptions::Mock(opts) => format!("mock-{}", opts.id), } } + + pub fn same_host(&self, other: &Self) -> bool { + match (self, other) { + (RemoteConnectionOptions::Ssh(a), RemoteConnectionOptions::Ssh(b)) => { + a.host == b.host && a.username == b.username && a.port == b.port + } + (RemoteConnectionOptions::Wsl(a), RemoteConnectionOptions::Wsl(b)) => a == b, + (RemoteConnectionOptions::Docker(a), RemoteConnectionOptions::Docker(b)) => { + a.container_id == b.container_id + } + #[cfg(any(test, feature = "test-support"))] + (RemoteConnectionOptions::Mock(a), RemoteConnectionOptions::Mock(b)) => a.id == b.id, + _ => false, + } + } } impl From for RemoteConnectionOptions { diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 3bac2b92198946..2df9535855eb62 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -1097,18 +1097,58 @@ fn handle_open_request(request: OpenRequest, app_state: Arc, cx: &mut } if let Some(connection_options) = request.remote_connection { - cx.spawn(async move |cx| { - let paths: Vec = request.open_paths.into_iter().map(PathBuf::from).collect(); - open_remote_project( - connection_options, - paths, - app_state, - workspace::OpenOptions::default(), - cx, - ) - .await - }) - .detach_and_log_err(cx); + let paths: Vec = request.open_paths.into_iter().map(PathBuf::from).collect(); + + let existing_window = cx.windows().into_iter().find_map(|window| { + let handle = window.downcast::()?; + handle + .read(cx) + .ok()? + .project() + .read(cx) + .remote_connection_options(cx)? + .same_host(&connection_options) + .then_some(handle) + }); + + if let Some(window) = existing_window { + cx.spawn(async move |cx| { + window + .update(cx, |workspace, window, cx| { + window.activate_window(); + workspace.open_paths( + paths, + workspace::OpenOptions { + visible: Some(workspace::OpenVisible::All), + ..Default::default() + }, + None, + window, + cx, + ) + })? + .await + .into_iter() + .flatten() + .for_each(|result| { + result.log_err(); + }); + anyhow::Ok(()) + }) + .detach_and_log_err(cx); + } else { + cx.spawn(async move |cx| { + open_remote_project( + connection_options, + paths, + app_state, + workspace::OpenOptions::default(), + cx, + ) + .await + }) + .detach_and_log_err(cx); + } return; }