diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 01639be82b..6c7b6df210 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -267,30 +267,6 @@ impl AppContext { .collect() } - pub(crate) fn update_window( - &mut self, - handle: AnyWindowHandle, - update: impl FnOnce(&mut WindowContext) -> R, - ) -> Result { - self.update(|cx| { - let mut window = cx - .windows - .get_mut(handle.id) - .ok_or_else(|| anyhow!("window not found"))? - .take() - .unwrap(); - - let result = update(&mut WindowContext::new(cx, &mut window)); - - cx.windows - .get_mut(handle.id) - .ok_or_else(|| anyhow!("window not found"))? - .replace(window); - - Ok(result) - }) - } - pub fn update_window_root( &mut self, handle: &WindowHandle, @@ -753,6 +729,7 @@ impl AppContext { } impl Context for AppContext { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'a, T> = ModelContext<'a, T>; type Result = T; @@ -784,6 +761,29 @@ impl Context for AppContext { result }) } + + fn update_window(&mut self, handle: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + self.update(|cx| { + let mut window = cx + .windows + .get_mut(handle.id) + .ok_or_else(|| anyhow!("window not found"))? + .take() + .unwrap(); + + let result = update(&mut WindowContext::new(cx, &mut window)); + + cx.windows + .get_mut(handle.id) + .ok_or_else(|| anyhow!("window not found"))? + .replace(window); + + Ok(result) + }) + } } impl MainThread diff --git a/crates/gpui2/src/app/async_context.rs b/crates/gpui2/src/app/async_context.rs index 8afd947e74..ed51f73fb7 100644 --- a/crates/gpui2/src/app/async_context.rs +++ b/crates/gpui2/src/app/async_context.rs @@ -1,6 +1,6 @@ use crate::{ - AnyWindowHandle, AppContext, Context, Executor, MainThread, Model, ModelContext, Result, Task, - View, ViewContext, VisualContext, WindowContext, WindowHandle, + AnyWindowHandle, AppContext, Context, Executor, MainThread, Model, ModelContext, Render, + Result, Task, View, ViewContext, VisualContext, WindowContext, WindowHandle, }; use anyhow::Context as _; use derive_more::{Deref, DerefMut}; @@ -14,6 +14,7 @@ pub struct AsyncAppContext { } impl Context for AsyncAppContext { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'a, T> = ModelContext<'a, T>; type Result = Result; @@ -38,6 +39,13 @@ impl Context for AsyncAppContext { let mut lock = app.lock(); // Need this to compile Ok(lock.update_model(handle, update)) } + + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + todo!() + } } impl AsyncAppContext { @@ -60,12 +68,12 @@ impl AsyncAppContext { pub fn update_window( &self, - handle: AnyWindowHandle, + window: AnyWindowHandle, update: impl FnOnce(&mut WindowContext) -> R, ) -> Result { let app = self.app.upgrade().context("app was released")?; let mut app_context = app.lock(); - app_context.update_window(handle, update) + app_context.update_window(window, update) } pub fn update_window_root( @@ -224,7 +232,9 @@ impl AsyncWindowContext { } impl Context for AsyncWindowContext { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'a, T> = ModelContext<'a, T>; + type Result = Result; fn build_model( @@ -246,6 +256,13 @@ impl Context for AsyncWindowContext { self.app .update_window(self.window, |cx| cx.update_model(handle, update)) } + + fn update_window(&mut self, window: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + self.app.update_window(window, update) + } } impl VisualContext for AsyncWindowContext { @@ -270,6 +287,17 @@ impl VisualContext for AsyncWindowContext { self.app .update_window(self.window, |cx| cx.update_view(view, update)) } + + fn replace_root_view( + &mut self, + build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, + ) -> Self::Result> + where + V: 'static + Send + Render, + { + self.app + .update_window(self.window, |cx| cx.replace_root_view(build_view)) + } } #[cfg(test)] diff --git a/crates/gpui2/src/app/entity_map.rs b/crates/gpui2/src/app/entity_map.rs index 8ceadfe73e..3aaf1c99c3 100644 --- a/crates/gpui2/src/app/entity_map.rs +++ b/crates/gpui2/src/app/entity_map.rs @@ -1,4 +1,4 @@ -use crate::{private::Sealed, AnyBox, AppContext, Context, Entity}; +use crate::{private::Sealed, AnyBox, AppContext, AsyncAppContext, Context, Entity, ModelContext}; use anyhow::{anyhow, Result}; use derive_more::{Deref, DerefMut}; use parking_lot::{RwLock, RwLockUpgradableReadGuard}; diff --git a/crates/gpui2/src/app/model_context.rs b/crates/gpui2/src/app/model_context.rs index 8fc9b5b544..c8b3eacdbc 100644 --- a/crates/gpui2/src/app/model_context.rs +++ b/crates/gpui2/src/app/model_context.rs @@ -1,7 +1,8 @@ use crate::{ - AppContext, AsyncAppContext, Context, Effect, Entity, EntityId, EventEmitter, MainThread, - Model, Subscription, Task, WeakModel, + AnyWindowHandle, AppContext, AsyncAppContext, Context, Effect, Entity, EntityId, EventEmitter, + MainThread, Model, Subscription, Task, WeakModel, WindowContext, }; +use anyhow::Result; use derive_more::{Deref, DerefMut}; use futures::FutureExt; use std::{ @@ -228,6 +229,7 @@ where } impl<'a, T> Context for ModelContext<'a, T> { + type WindowContext<'b> = WindowContext<'b>; type ModelContext<'b, U> = ModelContext<'b, U>; type Result = U; @@ -248,6 +250,13 @@ impl<'a, T> Context for ModelContext<'a, T> { ) -> R { self.app.update_model(handle, update) } + + fn update_window(&mut self, window: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> R, + { + self.app.update_window(window, update) + } } impl Borrow for ModelContext<'_, T> { diff --git a/crates/gpui2/src/app/test_context.rs b/crates/gpui2/src/app/test_context.rs index 2ab61bfd51..c53aefe565 100644 --- a/crates/gpui2/src/app/test_context.rs +++ b/crates/gpui2/src/app/test_context.rs @@ -12,6 +12,7 @@ pub struct TestAppContext { } impl Context for TestAppContext { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'a, T> = ModelContext<'a, T>; type Result = T; @@ -34,6 +35,14 @@ impl Context for TestAppContext { let mut lock = self.app.lock(); lock.update_model(handle, update) } + + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + let mut lock = self.app.lock(); + lock.update_window(window, f) + } } impl TestAppContext { diff --git a/crates/gpui2/src/gpui2.rs b/crates/gpui2/src/gpui2.rs index 55df1dcd09..5e5ac119d8 100644 --- a/crates/gpui2/src/gpui2.rs +++ b/crates/gpui2/src/gpui2.rs @@ -77,6 +77,7 @@ use taffy::TaffyLayoutEngine; type AnyBox = Box; pub trait Context { + type WindowContext<'a>: VisualContext; type ModelContext<'a, T>; type Result; @@ -87,11 +88,17 @@ pub trait Context { where T: 'static + Send; - fn update_model( + fn update_model( &mut self, handle: &Model, update: impl FnOnce(&mut T, &mut Self::ModelContext<'_, T>) -> R, - ) -> Self::Result; + ) -> Self::Result + where + T: 'static; + + fn update_window(&mut self, window: AnyWindowHandle, f: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T; } pub trait VisualContext: Context { @@ -99,7 +106,7 @@ pub trait VisualContext: Context { fn build_view( &mut self, - build_view_state: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, + build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, ) -> Self::Result> where V: 'static + Send; @@ -109,6 +116,13 @@ pub trait VisualContext: Context { view: &View, update: impl FnOnce(&mut V, &mut Self::ViewContext<'_, V>) -> R, ) -> Self::Result; + + fn replace_root_view( + &mut self, + build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, + ) -> Self::Result> + where + V: 'static + Send + Render; } pub trait Entity: Sealed { @@ -145,6 +159,7 @@ impl DerefMut for MainThread { } impl Context for MainThread { + type WindowContext<'a> = MainThread>; type ModelContext<'a, T> = MainThread>; type Result = C::Result; @@ -181,6 +196,20 @@ impl Context for MainThread { update(entity, cx) }) } + + fn update_window(&mut self, window: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + self.0.update_window(window, |cx| { + let cx = unsafe { + mem::transmute::<&mut C::WindowContext<'_>, &mut MainThread>>( + cx, + ) + }; + update(cx) + }) + } } impl VisualContext for MainThread { @@ -219,6 +248,24 @@ impl VisualContext for MainThread { update(view_state, cx) }) } + + fn replace_root_view( + &mut self, + build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, + ) -> Self::Result> + where + V: 'static + Send + Render, + { + self.0.replace_root_view(|cx| { + let cx = unsafe { + mem::transmute::< + &mut C::ViewContext<'_, V>, + &mut MainThread>, + >(cx) + }; + build_view(cx) + }) + } } pub trait BorrowAppContext { diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index f28544301b..b2f341d396 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -5,7 +5,7 @@ use crate::{ Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId, MainThread, MainThreadOnly, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow, - Point, PolychromeSprite, Quad, RenderGlyphParams, RenderImageParams, RenderSvgParams, + Point, PolychromeSprite, Quad, Render, RenderGlyphParams, RenderImageParams, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakView, WindowOptions, SUBPIXEL_VARIANTS, @@ -315,6 +315,8 @@ impl<'a> WindowContext<'a> { Self { app, window } } + // fn replace_root(&mut ) + /// Obtain a handle to the window that belongs to this context. pub fn window_handle(&self) -> AnyWindowHandle { self.window.handle @@ -1264,6 +1266,7 @@ impl<'a> WindowContext<'a> { } impl Context for WindowContext<'_> { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'a, T> = ModelContext<'a, T>; type Result = T; @@ -1292,6 +1295,17 @@ impl Context for WindowContext<'_> { self.entities.end_lease(entity); result } + + fn update_window(&mut self, window: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + if window == self.window.handle { + Ok(update(self)) + } else { + self.app.update_window(window, update) + } + } } impl VisualContext for WindowContext<'_> { @@ -1326,6 +1340,24 @@ impl VisualContext for WindowContext<'_> { cx.app.entities.end_lease(lease); result } + + fn replace_root_view( + &mut self, + build_view: impl FnOnce(&mut Self::ViewContext<'_, V>) -> V, + ) -> Self::Result> + where + V: 'static + Send + Render, + { + let slot = self.app.entities.reserve(); + let view = View { + model: slot.clone(), + }; + let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view); + let entity = build_view(&mut cx); + self.entities.insert(slot, entity); + self.window.root_view = Some(view.clone().into()); + view + } } impl<'a> std::ops::Deref for WindowContext<'a> { @@ -1900,6 +1932,7 @@ impl MainThread> { } impl Context for ViewContext<'_, V> { + type WindowContext<'a> = WindowContext<'a>; type ModelContext<'b, U> = ModelContext<'b, U>; type Result = U; @@ -1920,6 +1953,13 @@ impl Context for ViewContext<'_, V> { ) -> R { self.window_cx.update_model(model, update) } + + fn update_window(&mut self, window: AnyWindowHandle, update: F) -> Result + where + F: FnOnce(&mut Self::WindowContext<'_>) -> T, + { + self.window_cx.update_window(window, update) + } } impl VisualContext for ViewContext<'_, V> { @@ -1939,6 +1979,16 @@ impl VisualContext for ViewContext<'_, V> { ) -> Self::Result { self.window_cx.update_view(view, update) } + + fn replace_root_view( + &mut self, + build_view: impl FnOnce(&mut Self::ViewContext<'_, W>) -> W, + ) -> Self::Result> + where + W: 'static + Send + Render, + { + self.window_cx.replace_root_view(build_view) + } } impl<'a, V> std::ops::Deref for ViewContext<'a, V> { @@ -1972,18 +2022,7 @@ pub struct WindowHandle { state_type: PhantomData, } -impl Copy for WindowHandle {} - -impl Clone for WindowHandle { - fn clone(&self) -> Self { - WindowHandle { - any_handle: self.any_handle, - state_type: PhantomData, - } - } -} - -impl WindowHandle { +impl WindowHandle { pub fn new(id: WindowId) -> Self { WindowHandle { any_handle: AnyWindowHandle { @@ -1994,7 +2033,7 @@ impl WindowHandle { } } - pub fn update( + pub fn update_root( &self, cx: &mut AppContext, update: impl FnOnce(&mut V, &mut ViewContext) -> R, @@ -2012,6 +2051,17 @@ impl WindowHandle { } } +impl Copy for WindowHandle {} + +impl Clone for WindowHandle { + fn clone(&self) -> Self { + WindowHandle { + any_handle: self.any_handle, + state_type: PhantomData, + } + } +} + impl Into for WindowHandle { fn into(self) -> AnyWindowHandle { self.any_handle diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 8e6c8c2c64..99cc45572b 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -23,8 +23,8 @@ use futures::{ FutureExt, }; use gpui2::{ - AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, DisplayId, Entity, - EventEmitter, MainThread, Model, ModelContext, Subscription, Task, View, ViewContext, + div, AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, Div, Entity, + EventEmitter, MainThread, Model, ModelContext, Render, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem}; @@ -32,7 +32,10 @@ use language2::LanguageRegistry; use node_runtime::NodeRuntime; pub use pane::*; pub use pane_group::*; -use persistence::model::{ItemId, WorkspaceLocation}; +use persistence::{ + model::{ItemId, WorkspaceLocation}, + DB, +}; use project2::{Project, ProjectEntryId, ProjectPath, Worktree}; use std::{ any::TypeId, @@ -773,139 +776,137 @@ impl Workspace { // } // } - // fn new_local( - // abs_paths: Vec, - // app_state: Arc, - // requesting_window: Option>, - // cx: &mut AppContext, - // ) -> Task<( - // WeakView, - // Vec, anyhow::Error>>>, - // )> { - // let project_handle = Project::local( - // app_state.client.clone(), - // app_state.node_runtime.clone(), - // app_state.user_store.clone(), - // app_state.languages.clone(), - // app_state.fs.clone(), - // cx, - // ); + fn new_local( + abs_paths: Vec, + app_state: Arc, + requesting_window: Option>, + cx: &mut MainThread, + ) -> Task<( + WeakView, + Vec, anyhow::Error>>>, + )> { + let project_handle = Project::local( + app_state.client.clone(), + app_state.node_runtime.clone(), + app_state.user_store.clone(), + app_state.languages.clone(), + app_state.fs.clone(), + cx, + ); - // cx.spawn(|mut cx| async move { - // let serialized_workspace = persistence::DB.workspace_for_roots(&abs_paths.as_slice()); + cx.spawn_on_main(|mut cx| async move { + let serialized_workspace = persistence::DB.workspace_for_roots(&abs_paths.as_slice()); - // let paths_to_open = Arc::new(abs_paths); + let paths_to_open = Arc::new(abs_paths); - // // Get project paths for all of the abs_paths - // let mut worktree_roots: HashSet> = Default::default(); - // let mut project_paths: Vec<(PathBuf, Option)> = - // Vec::with_capacity(paths_to_open.len()); - // for path in paths_to_open.iter().cloned() { - // if let Some((worktree, project_entry)) = cx - // .update(|cx| { - // Workspace::project_path_for_path(project_handle.clone(), &path, true, cx) - // }) - // .await - // .log_err() - // { - // worktree_roots.insert(worktree.read_with(&mut cx, |tree, _| tree.abs_path())); - // project_paths.push((path, Some(project_entry))); - // } else { - // project_paths.push((path, None)); - // } - // } + // Get project paths for all of the abs_paths + let mut worktree_roots: HashSet> = Default::default(); + let mut project_paths: Vec<(PathBuf, Option)> = + Vec::with_capacity(paths_to_open.len()); + for path in paths_to_open.iter().cloned() { + if let Some((worktree, project_entry)) = cx + .update(|cx| { + Workspace::project_path_for_path(project_handle.clone(), &path, true, cx) + })? + .await + .log_err() + { + worktree_roots.extend(worktree.update(&mut cx, |tree, _| tree.abs_path()).ok()); + project_paths.push((path, Some(project_entry))); + } else { + project_paths.push((path, None)); + } + } - // let workspace_id = if let Some(serialized_workspace) = serialized_workspace.as_ref() { - // serialized_workspace.id - // } else { - // DB.next_id().await.unwrap_or(0) - // }; + let workspace_id = if let Some(serialized_workspace) = serialized_workspace.as_ref() { + serialized_workspace.id + } else { + DB.next_id().await.unwrap_or(0) + }; - // let window = if let Some(window) = requesting_window { - // window.replace_root(&mut cx, |cx| { - // Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) - // }); - // window - // } else { - // { - // let window_bounds_override = window_bounds_env_override(&cx); - // let (bounds, display) = if let Some(bounds) = window_bounds_override { - // (Some(bounds), None) - // } else { - // serialized_workspace - // .as_ref() - // .and_then(|serialized_workspace| { - // let display = serialized_workspace.display?; - // let mut bounds = serialized_workspace.bounds?; + let window = if let Some(window) = requesting_window { + cx.update_window(window.into(), |cx| { + cx.replace_root_view(|cx| { + Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx) + }); + }); + window + } else { + { + let window_bounds_override = window_bounds_env_override(&cx); + let (bounds, display) = if let Some(bounds) = window_bounds_override { + (Some(bounds), None) + } else { + serialized_workspace + .as_ref() + .and_then(|serialized_workspace| { + let display = serialized_workspace.display?; + let mut bounds = serialized_workspace.bounds?; - // // Stored bounds are relative to the containing display. - // // So convert back to global coordinates if that screen still exists - // if let WindowBounds::Fixed(mut window_bounds) = bounds { - // if let Some(screen) = cx.platform().screen_by_id(display) { - // let screen_bounds = screen.bounds(); - // window_bounds.set_origin_x( - // window_bounds.origin_x() + screen_bounds.origin_x(), - // ); - // window_bounds.set_origin_y( - // window_bounds.origin_y() + screen_bounds.origin_y(), - // ); - // bounds = WindowBounds::Fixed(window_bounds); - // } else { - // // Screen no longer exists. Return none here. - // return None; - // } - // } + // Stored bounds are relative to the containing display. + // So convert back to global coordinates if that screen still exists + if let WindowBounds::Fixed(mut window_bounds) = bounds { + if let Some(screen) = cx.platform().screen_by_id(display) { + let screen_bounds = screen.bounds(); + window_bounds.origin.x += screen_bounds.origin.x; + window_bounds.origin.y += screen_bounds.origin.y; + bounds = WindowBounds::Fixed(window_bounds); + } else { + // Screen no longer exists. Return none here. + return None; + } + } - // Some((bounds, display)) - // }) - // .unzip() - // }; + Some((bounds, display)) + }) + .unzip() + }; - // // Use the serialized workspace to construct the new window - // cx.add_window( - // (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), - // |cx| { - // Workspace::new( - // workspace_id, - // project_handle.clone(), - // app_state.clone(), - // cx, - // ) - // }, - // ) - // } - // }; + // Use the serialized workspace to construct the new window + cx.open_window( + (app_state.build_window_options)(bounds, display, cx.platform().as_ref()), + |cx| { + Workspace::new( + workspace_id, + project_handle.clone(), + app_state.clone(), + cx, + ) + }, + ) + } + }; - // // We haven't yielded the main thread since obtaining the window handle, - // // so the window exists. - // let workspace = window.root(&cx).unwrap(); + // We haven't yielded the main thread since obtaining the window handle, + // so the window exists. + let workspace = window.root(&cx).unwrap(); - // (app_state.initialize_workspace)( - // workspace.downgrade(), - // serialized_workspace.is_some(), - // app_state.clone(), - // cx.clone(), - // ) - // .await - // .log_err(); + (app_state.initialize_workspace)( + workspace.downgrade(), + serialized_workspace.is_some(), + app_state.clone(), + cx.clone(), + ) + .await + .log_err(); - // window.update(&mut cx, |cx| cx.activate_window()); + window.update_root(&mut cx, |cx| cx.activate_window()); - // let workspace = workspace.downgrade(); - // notify_if_database_failed(&workspace, &mut cx); - // let opened_items = open_items( - // serialized_workspace, - // &workspace, - // project_paths, - // app_state, - // cx, - // ) - // .await - // .unwrap_or_default(); + let workspace = workspace.downgrade(); + notify_if_database_failed(&workspace, &mut cx); + let opened_items = open_items( + serialized_workspace, + &workspace, + project_paths, + app_state, + cx, + ) + .await + .unwrap_or_default(); - // (workspace, opened_items) - // }) - // } + (workspace, opened_items) + }) + } pub fn weak_handle(&self) -> WeakView { self.weak_self.clone() @@ -3744,6 +3745,14 @@ impl EventEmitter for Workspace { type Event = Event; } +impl Render for Workspace { + type Element = Div; + + fn render(&mut self, cx: &mut ViewContext) -> Self::Element { + div() + } +} + // todo!() // impl Entity for Workspace { // type Event = Event; @@ -3960,7 +3969,7 @@ impl WorkspaceStore { let mut response = proto::FollowResponse::default(); for workspace in &this.workspaces { workspace - .update(cx, |workspace, cx| { + .update_root(cx, |workspace, cx| { let handler_response = workspace.handle_follow(follower.project_id, cx); if response.views.is_empty() { response.views = handler_response.views; @@ -4118,9 +4127,9 @@ pub async fn activate_workspace_for_project( .await } -// pub async fn last_opened_workspace_paths() -> Option { -// DB.last_workspace().await.log_err().flatten() -// } +pub async fn last_opened_workspace_paths() -> Option { + DB.last_workspace().await.log_err().flatten() +} // async fn join_channel_internal( // channel_id: u64, @@ -4345,24 +4354,24 @@ pub fn open_paths( }) } -// pub fn open_new( -// app_state: &Arc, -// cx: &mut AppContext, -// init: impl FnOnce(&mut Workspace, &mut ViewContext) + 'static, -// ) -> Task<()> { -// let task = Workspace::new_local(Vec::new(), app_state.clone(), None, cx); -// cx.spawn(|mut cx| async move { -// let (workspace, opened_paths) = task.await; +pub fn open_new( + app_state: &Arc, + cx: &mut AppContext, + init: impl FnOnce(&mut Workspace, &mut ViewContext) + 'static, +) -> Task<()> { + let task = Workspace::new_local(Vec::new(), app_state.clone(), None, cx); + cx.spawn(|mut cx| async move { + let (workspace, opened_paths) = task.await; -// workspace -// .update(&mut cx, |workspace, cx| { -// if opened_paths.is_empty() { -// init(workspace, cx) -// } -// }) -// .log_err(); -// }) -// } + workspace + .update(&mut cx, |workspace, cx| { + if opened_paths.is_empty() { + init(workspace, cx) + } + }) + .log_err(); + }) +} // pub fn create_and_open_local_file( // path: &'static Path, diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index c982a735c5..793c6d6139 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -314,21 +314,20 @@ async fn installation_id() -> Result { } async fn restore_or_create_workspace(_app_state: &Arc, mut _cx: AsyncAppContext) { - todo!("workspace") - // if let Some(location) = workspace::last_opened_workspace_paths().await { - // cx.update(|cx| workspace::open_paths(location.paths().as_ref(), app_state, None, cx)) - // .await - // .log_err(); - // } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) { - // cx.update(|cx| show_welcome_experience(app_state, cx)); - // } else { - // cx.update(|cx| { - // workspace::open_new(app_state, cx, |workspace, cx| { - // Editor::new_file(workspace, &Default::default(), cx) - // }) - // .detach(); - // }); - // } + if let Some(location) = workspace2::last_opened_workspace_paths().await { + cx.update(|cx| workspace2::open_paths(location.paths().as_ref(), app_state, None, cx)) + .await + .log_err(); + } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) { + cx.update(|cx| show_welcome_experience(app_state, cx)); + } else { + cx.update(|cx| { + workspace2::open_new(app_state, cx, |workspace, cx| { + Editor::new_file(workspace, &Default::default(), cx) + }) + .detach(); + }); + } } fn init_paths() {