@@ -32,7 +32,10 @@ use util::ResultExt;
use workspace::OpenOptions;
use workspace::Toast;
use workspace::notifications::NotificationId;
-use workspace::{ModalView, Workspace, notifications::DetachAndPromptErr};
+use workspace::{
+ ModalView, Workspace, notifications::DetachAndPromptErr,
+ open_ssh_project_with_existing_connection,
+};
use crate::OpenRemote;
use crate::ssh_connections::RemoteSettingsContent;
@@ -157,13 +160,8 @@ impl ProjectPicker {
let app_state = workspace
.update(cx, |workspace, _| workspace.app_state().clone())
.ok()?;
- let options = cx
- .update(|_, cx| (app_state.build_window_options)(None, cx))
- .log_err()?;
-
- cx.open_window(options, |window, cx| {
- window.activate_window();
+ cx.update(|_, cx| {
let fs = app_state.fs.clone();
update_settings_file::<SshSettings>(fs, cx, {
let paths = paths
@@ -180,32 +178,27 @@ impl ProjectPicker {
}
}
});
+ })
+ .log_err();
- let tasks = paths
- .into_iter()
- .map(|path| {
- project.update(cx, |project, cx| {
- project.find_or_create_worktree(&path, true, cx)
- })
- })
- .collect::<Vec<_>>();
- window
- .spawn(cx, async move |_| {
- for task in tasks {
- task.await?;
- }
- Ok(())
+ let options = cx
+ .update(|_, cx| (app_state.build_window_options)(None, cx))
+ .log_err()?;
+ let window = cx
+ .open_window(options, |window, cx| {
+ cx.new(|cx| {
+ telemetry::event!("SSH Project Created");
+ Workspace::new(None, project.clone(), app_state.clone(), window, cx)
})
- .detach_and_prompt_err("Failed to open path", window, cx, |_, _, _| {
- None
- });
-
- cx.new(|cx| {
- telemetry::event!("SSH Project Created");
- Workspace::new(None, project.clone(), app_state.clone(), window, cx)
})
- })
+ .log_err()?;
+
+ open_ssh_project_with_existing_connection(
+ connection, project, paths, app_state, window, cx,
+ )
+ .await
.log_err();
+
this.update(cx, |_, cx| {
cx.emit(DismissEvent);
})
@@ -6279,7 +6279,7 @@ pub fn create_and_open_local_file(
})
}
-pub fn open_ssh_project(
+pub fn open_ssh_project_with_new_connection(
window: WindowHandle<Workspace>,
connection_options: SshConnectionOptions,
cancel_rx: oneshot::Receiver<()>,
@@ -6320,68 +6320,118 @@ pub fn open_ssh_project(
)
})?;
- let toolchains = DB.toolchains(workspace_id).await?;
- for (toolchain, worktree_id, path) in toolchains {
- project
- .update(cx, |this, cx| {
- this.activate_toolchain(ProjectPath { worktree_id, path }, toolchain, cx)
- })?
- .await;
- }
- let mut project_paths_to_open = vec![];
- let mut project_path_errors = vec![];
+ open_ssh_project_inner(
+ project,
+ paths,
+ serialized_ssh_project,
+ workspace_id,
+ serialized_workspace,
+ app_state,
+ window,
+ cx,
+ )
+ .await
+ })
+}
- for path in paths {
- let result = cx
- .update(|cx| Workspace::project_path_for_path(project.clone(), &path, true, cx))?
- .await;
- match result {
- Ok((_, project_path)) => {
- project_paths_to_open.push((path.clone(), Some(project_path)));
- }
- Err(error) => {
- project_path_errors.push(error);
- }
- };
- }
+pub fn open_ssh_project_with_existing_connection(
+ connection_options: SshConnectionOptions,
+ project: Entity<Project>,
+ paths: Vec<PathBuf>,
+ app_state: Arc<AppState>,
+ window: WindowHandle<Workspace>,
+ cx: &mut AsyncApp,
+) -> Task<Result<()>> {
+ cx.spawn(async move |cx| {
+ let (serialized_ssh_project, workspace_id, serialized_workspace) =
+ serialize_ssh_project(connection_options.clone(), paths.clone(), &cx).await?;
- if project_paths_to_open.is_empty() {
- return Err(project_path_errors
- .pop()
- .unwrap_or_else(|| anyhow!("no paths given")));
- }
+ open_ssh_project_inner(
+ project,
+ paths,
+ serialized_ssh_project,
+ workspace_id,
+ serialized_workspace,
+ app_state,
+ window,
+ cx,
+ )
+ .await
+ })
+}
+
+async fn open_ssh_project_inner(
+ project: Entity<Project>,
+ paths: Vec<PathBuf>,
+ serialized_ssh_project: SerializedSshProject,
+ workspace_id: WorkspaceId,
+ serialized_workspace: Option<SerializedWorkspace>,
+ app_state: Arc<AppState>,
+ window: WindowHandle<Workspace>,
+ cx: &mut AsyncApp,
+) -> Result<()> {
+ let toolchains = DB.toolchains(workspace_id).await?;
+ for (toolchain, worktree_id, path) in toolchains {
+ project
+ .update(cx, |this, cx| {
+ this.activate_toolchain(ProjectPath { worktree_id, path }, toolchain, cx)
+ })?
+ .await;
+ }
+ let mut project_paths_to_open = vec![];
+ let mut project_path_errors = vec![];
- cx.update_window(window.into(), |_, window, cx| {
- window.replace_root(cx, |window, cx| {
- telemetry::event!("SSH Project Opened");
+ for path in paths {
+ let result = cx
+ .update(|cx| Workspace::project_path_for_path(project.clone(), &path, true, cx))?
+ .await;
+ match result {
+ Ok((_, project_path)) => {
+ project_paths_to_open.push((path.clone(), Some(project_path)));
+ }
+ Err(error) => {
+ project_path_errors.push(error);
+ }
+ };
+ }
- let mut workspace =
- Workspace::new(Some(workspace_id), project, app_state.clone(), window, cx);
- workspace.set_serialized_ssh_project(serialized_ssh_project);
- workspace
- });
- })?;
+ if project_paths_to_open.is_empty() {
+ return Err(project_path_errors
+ .pop()
+ .unwrap_or_else(|| anyhow!("no paths given")));
+ }
- window
- .update(cx, |_, window, cx| {
- window.activate_window();
+ cx.update_window(window.into(), |_, window, cx| {
+ window.replace_root(cx, |window, cx| {
+ telemetry::event!("SSH Project Opened");
- open_items(serialized_workspace, project_paths_to_open, window, cx)
- })?
- .await?;
+ let mut workspace =
+ Workspace::new(Some(workspace_id), project, app_state.clone(), window, cx);
+ workspace.set_serialized_ssh_project(serialized_ssh_project);
+ workspace
+ });
+ })?;
- window.update(cx, |workspace, _, cx| {
- for error in project_path_errors {
- if error.error_code() == proto::ErrorCode::DevServerProjectPathDoesNotExist {
- if let Some(path) = error.error_tag("path") {
- workspace.show_error(&anyhow!("'{path}' does not exist"), cx)
- }
- } else {
- workspace.show_error(&error, cx)
+ window
+ .update(cx, |_, window, cx| {
+ window.activate_window();
+ open_items(serialized_workspace, project_paths_to_open, window, cx)
+ })?
+ .await?;
+
+ window.update(cx, |workspace, _, cx| {
+ for error in project_path_errors {
+ if error.error_code() == proto::ErrorCode::DevServerProjectPathDoesNotExist {
+ if let Some(path) = error.error_tag("path") {
+ workspace.show_error(&anyhow!("'{path}' does not exist"), cx)
}
+ } else {
+ workspace.show_error(&error, cx)
}
- })
- })
+ }
+ })?;
+
+ Ok(())
}
fn serialize_ssh_project(