Detailed changes
@@ -70,6 +70,7 @@ async fn test_dev_server(cx: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppC
workspace::join_remote_project(
projects[0].project_id.unwrap(),
client.app_state.clone(),
+ None,
cx,
)
})
@@ -205,7 +206,12 @@ async fn create_remote_project(
let projects = store.remote_projects();
assert_eq!(projects.len(), 1);
assert_eq!(projects[0].path, "/remote");
- workspace::join_remote_project(projects[0].project_id.unwrap(), client_app_state, cx)
+ workspace::join_remote_project(
+ projects[0].project_id.unwrap(),
+ client_app_state,
+ None,
+ cx,
+ )
})
.await
.unwrap();
@@ -301,6 +307,7 @@ async fn test_dev_server_reconnect(
workspace::join_remote_project(
projects[0].project_id.unwrap(),
client2.app_state.clone(),
+ None,
cx,
)
})
@@ -310,7 +310,6 @@ impl PickerDelegate for RecentProjectsDelegate {
workspace.open_workspace_for_paths(false, paths, cx)
}
}
- //TODO support opening remote projects in the same window
SerializedWorkspaceLocation::Remote(remote_project) => {
let store = ::remote_projects::Store::global(cx).read(cx);
let Some(project_id) = store
@@ -338,12 +337,38 @@ impl PickerDelegate for RecentProjectsDelegate {
})
};
if let Some(app_state) = AppState::global(cx).upgrade() {
- let task =
- workspace::join_remote_project(project_id, app_state, cx);
- cx.spawn(|_, _| async move {
- task.await?;
- Ok(())
- })
+ let handle = if replace_current_window {
+ cx.window_handle().downcast::<Workspace>()
+ } else {
+ None
+ };
+
+ if let Some(handle) = handle {
+ cx.spawn(move |workspace, mut cx| async move {
+ let continue_replacing = workspace
+ .update(&mut cx, |workspace, cx| {
+ workspace.
+ prepare_to_close(true, cx)
+ })?
+ .await?;
+ if continue_replacing {
+ workspace
+ .update(&mut cx, |_workspace, cx| {
+ workspace::join_remote_project(project_id, app_state, Some(handle), cx)
+ })?
+ .await?;
+ }
+ Ok(())
+ })
+ }
+ else {
+ let task =
+ workspace::join_remote_project(project_id, app_state, None, cx);
+ cx.spawn(|_, _| async move {
+ task.await?;
+ Ok(())
+ })
+ }
} else {
Task::ready(Err(anyhow::anyhow!("App state not found")))
}
@@ -386,7 +386,7 @@ impl RemoteProjects {
.on_click(cx.listener(move |_, _, cx| {
if let Some(project_id) = project_id {
if let Some(app_state) = AppState::global(cx).upgrade() {
- workspace::join_remote_project(project_id, app_state, cx)
+ workspace::join_remote_project(project_id, app_state, None, cx)
.detach_and_prompt_err("Could not join project", cx, |_, _| None)
}
} else {
@@ -9,8 +9,8 @@ use fs::Fs;
use futures::stream::StreamExt;
use futures_batch::ChunksTimeoutStreamExt;
use gpui::{
- AppContext, AsyncAppContext, Context, EntityId, EventEmitter, Global, Model, ModelContext,
- Subscription, Task, WeakModel,
+ AppContext, AsyncAppContext, BorrowAppContext, Context, Entity, EntityId, EventEmitter, Global,
+ Model, ModelContext, Subscription, Task, WeakModel,
};
use heed::types::{SerdeBincode, Str};
use language::LanguageRegistry;
@@ -68,6 +68,18 @@ impl SemanticIndex {
project: Model<Project>,
cx: &mut AppContext,
) -> Model<ProjectIndex> {
+ let project_weak = project.downgrade();
+ project.update(cx, move |_, cx| {
+ cx.on_release(move |_, cx| {
+ if cx.has_global::<SemanticIndex>() {
+ cx.update_global::<SemanticIndex, _>(|this, _| {
+ this.project_indices.remove(&project_weak);
+ })
+ }
+ })
+ .detach();
+ });
+
self.project_indices
.entry(project.downgrade())
.or_insert_with(|| {
@@ -86,7 +98,7 @@ impl SemanticIndex {
pub struct ProjectIndex {
db_connection: heed::Env,
- project: Model<Project>,
+ project: WeakModel<Project>,
worktree_indices: HashMap<EntityId, WorktreeIndexHandle>,
language_registry: Arc<LanguageRegistry>,
fs: Arc<dyn Fs>,
@@ -116,7 +128,7 @@ impl ProjectIndex {
let fs = project.read(cx).fs().clone();
let mut this = ProjectIndex {
db_connection,
- project: project.clone(),
+ project: project.downgrade(),
worktree_indices: HashMap::default(),
language_registry,
fs,
@@ -143,8 +155,11 @@ impl ProjectIndex {
}
fn update_worktree_indices(&mut self, cx: &mut ModelContext<Self>) {
- let worktrees = self
- .project
+ let Some(project) = self.project.upgrade() else {
+ return;
+ };
+
+ let worktrees = project
.read(cx)
.visible_worktrees(cx)
.filter_map(|worktree| {
@@ -4785,6 +4785,7 @@ pub fn join_hosted_project(
pub fn join_remote_project(
project_id: ProjectId,
app_state: Arc<AppState>,
+ window_to_replace: Option<WindowHandle<Workspace>>,
cx: &mut AppContext,
) -> Task<Result<WindowHandle<Workspace>>> {
let windows = cx.windows();
@@ -4816,16 +4817,25 @@ pub fn join_remote_project(
)
.await?;
- let window_bounds_override = window_bounds_env_override();
- cx.update(|cx| {
- let mut options = (app_state.build_window_options)(None, cx);
- options.bounds = window_bounds_override;
- cx.open_window(options, |cx| {
- cx.new_view(|cx| {
+ if let Some(window_to_replace) = window_to_replace {
+ cx.update_window(window_to_replace.into(), |_, cx| {
+ cx.replace_root_view(|cx| {
Workspace::new(Default::default(), project, app_state.clone(), cx)
+ });
+ })?;
+ window_to_replace
+ } else {
+ let window_bounds_override = window_bounds_env_override();
+ cx.update(|cx| {
+ let mut options = (app_state.build_window_options)(None, cx);
+ options.bounds = window_bounds_override;
+ cx.open_window(options, |cx| {
+ cx.new_view(|cx| {
+ Workspace::new(Default::default(), project, app_state.clone(), cx)
+ })
})
- })
- })?
+ })?
+ }
};
workspace.update(&mut cx, |_, cx| {