From d4e199cab1da0a63858f3e0b99f556ba6250f2d8 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 2 Nov 2023 13:58:42 +0100 Subject: [PATCH] WIP --- crates/workspace2/src/item.rs | 4 +- crates/workspace2/src/persistence/model.rs | 223 ++++++++-------- crates/workspace2/src/workspace2.rs | 296 ++++++++++----------- 3 files changed, 262 insertions(+), 261 deletions(-) diff --git a/crates/workspace2/src/item.rs b/crates/workspace2/src/item.rs index ebc51942d0..c2d5c25781 100644 --- a/crates/workspace2/src/item.rs +++ b/crates/workspace2/src/item.rs @@ -13,7 +13,7 @@ use client2::{ }; use gpui2::{ AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, HighlightStyle, Model, Pixels, - Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext, WindowHandle, + Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext, }; use parking_lot::Mutex; use project2::{Project, ProjectEntryId, ProjectPath}; @@ -190,7 +190,7 @@ pub trait Item: Render + EventEmitter + Send { fn deserialize( _project: Model, - _workspace: WindowHandle, + _workspace: WeakView, _workspace_id: WorkspaceId, _item_id: ItemId, _cx: &mut ViewContext, diff --git a/crates/workspace2/src/persistence/model.rs b/crates/workspace2/src/persistence/model.rs index 13b0560a19..25d5a970fa 100644 --- a/crates/workspace2/src/persistence/model.rs +++ b/crates/workspace2/src/persistence/model.rs @@ -1,14 +1,19 @@ -use crate::{Axis, WorkspaceId}; +use crate::{ + item::ItemHandle, Axis, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId, +}; use anyhow::{Context, Result}; +use async_recursion::async_recursion; use db2::sqlez::{ bindable::{Bind, Column, StaticColumnCount}, statement::Statement, }; -use gpui2::WindowBounds; +use gpui2::{AsyncWindowContext, Model, Task, View, WeakView, WindowBounds}; +use project2::Project; use std::{ path::{Path, PathBuf}, sync::Arc, }; +use util::ResultExt; use uuid::Uuid; #[derive(Debug, Clone, PartialEq, Eq)] @@ -142,75 +147,73 @@ impl Default for SerializedPaneGroup { } } -// impl SerializedPaneGroup { -// #[async_recursion(?Send)] -// pub(crate) async fn deserialize( -// self, -// project: &Model, -// workspace_id: WorkspaceId, -// workspace: WeakView, -// cx: &mut AsyncAppContext, -// ) -> Option<(Member, Option>, Vec>>)> { -// match self { -// SerializedPaneGroup::Group { -// axis, -// children, -// flexes, -// } => { -// let mut current_active_pane = None; -// let mut members = Vec::new(); -// let mut items = Vec::new(); -// for child in children { -// if let Some((new_member, active_pane, new_items)) = child -// .deserialize(project, workspace_id, workspace, cx) -// .await -// { -// members.push(new_member); -// items.extend(new_items); -// current_active_pane = current_active_pane.or(active_pane); -// } -// } +impl SerializedPaneGroup { + #[async_recursion(?Send)] + pub(crate) async fn deserialize( + self, + project: &Model, + workspace_id: WorkspaceId, + workspace: WeakView, + cx: &mut AsyncWindowContext, + ) -> Option<(Member, Option>, Vec>>)> { + match self { + SerializedPaneGroup::Group { + axis, + children, + flexes, + } => { + let mut current_active_pane = None; + let mut members = Vec::new(); + let mut items = Vec::new(); + for child in children { + if let Some((new_member, active_pane, new_items)) = child + .deserialize(project, workspace_id, workspace, cx) + .await + { + members.push(new_member); + items.extend(new_items); + current_active_pane = current_active_pane.or(active_pane); + } + } -// if members.is_empty() { -// return None; -// } + if members.is_empty() { + return None; + } -// if members.len() == 1 { -// return Some((members.remove(0), current_active_pane, items)); -// } + if members.len() == 1 { + return Some((members.remove(0), current_active_pane, items)); + } -// Some(( -// Member::Axis(PaneAxis::load(axis, members, flexes)), -// current_active_pane, -// items, -// )) -// } -// SerializedPaneGroup::Pane(serialized_pane) => { -// let pane = workspace -// .update(cx, |workspace, cx| workspace.add_pane(cx).downgrade()) -// .log_err()?; -// let active = serialized_pane.active; -// let new_items = serialized_pane -// .deserialize_to(project, &pane, workspace_id, workspace, cx) -// .await -// .log_err()?; + Some(( + Member::Axis(PaneAxis::load(axis, members, flexes)), + current_active_pane, + items, + )) + } + SerializedPaneGroup::Pane(serialized_pane) => { + let pane = workspace + .update(cx, |workspace, cx| workspace.add_pane(cx).downgrade()) + .log_err()?; + let active = serialized_pane.active; + let new_items = serialized_pane + .deserialize_to(project, &pane, workspace_id, workspace, cx) + .await + .log_err()?; -// // todo!(); -// // if pane.update(cx, |pane, _| pane.items_len() != 0).log_err()? { -// // let pane = pane.upgrade()?; -// // Some((Member::Pane(pane.clone()), active.then(|| pane), new_items)) -// // } else { -// // let pane = pane.upgrade()?; -// // workspace -// // .update(cx, |workspace, cx| workspace.force_remove_pane(&pane, cx)) -// // .log_err()?; -// // None -// // } -// None -// } -// } -// } -// } + if pane.update(cx, |pane, _| pane.items_len() != 0).log_err()? { + let pane = pane.upgrade()?; + Some((Member::Pane(pane.clone()), active.then(|| pane), new_items)) + } else { + let pane = pane.upgrade()?; + workspace + .update(cx, |workspace, cx| workspace.force_remove_pane(&pane, cx)) + .log_err()?; + None + } + } + } + } +} #[derive(Debug, PartialEq, Eq, Default, Clone)] pub struct SerializedPane { @@ -223,55 +226,53 @@ impl SerializedPane { SerializedPane { children, active } } - // pub async fn deserialize_to( - // &self, - // _project: &Model, - // _pane: &WeakView, - // _workspace_id: WorkspaceId, - // _workspace: WindowHandle, - // _cx: &mut AsyncAppContext, - // ) -> Result>>> { - // anyhow::bail!("todo!()") - // // todo!() - // // let mut items = Vec::new(); - // // let mut active_item_index = None; - // // for (index, item) in self.children.iter().enumerate() { - // // let project = project.clone(); - // // let item_handle = pane - // // .update(cx, |_, cx| { - // // if let Some(deserializer) = cx.global::().get(&item.kind) { - // // deserializer(project, workspace, workspace_id, item.item_id, cx) - // // } else { - // // Task::ready(Err(anyhow::anyhow!( - // // "Deserializer does not exist for item kind: {}", - // // item.kind - // // ))) - // // } - // // })? - // // .await - // // .log_err(); + pub async fn deserialize_to( + &self, + project: &Model, + pane: &WeakView, + workspace_id: WorkspaceId, + workspace: WeakView, + cx: &mut AsyncWindowContext, + ) -> Result>>> { + let mut items = Vec::new(); + let mut active_item_index = None; + for (index, item) in self.children.iter().enumerate() { + let project = project.clone(); + let item_handle = pane + .update(cx, |_, cx| { + if let Some(deserializer) = cx.global::().get(&item.kind) { + deserializer(project, workspace.clone(), workspace_id, item.item_id, cx) + } else { + Task::ready(Err(anyhow::anyhow!( + "Deserializer does not exist for item kind: {}", + item.kind + ))) + } + })? + .await + .log_err(); - // // items.push(item_handle.clone()); + items.push(item_handle.clone()); - // // if let Some(item_handle) = item_handle { - // // pane.update(cx, |pane, cx| { - // // pane.add_item(item_handle.clone(), true, true, None, cx); - // // })?; - // // } + if let Some(item_handle) = item_handle { + pane.update(cx, |pane, cx| { + pane.add_item(item_handle.clone(), true, true, None, cx); + })?; + } - // // if item.active { - // // active_item_index = Some(index); - // // } - // // } + if item.active { + active_item_index = Some(index); + } + } - // // if let Some(active_item_index) = active_item_index { - // // pane.update(cx, |pane, cx| { - // // pane.activate_item(active_item_index, false, false, cx); - // // })?; - // // } + if let Some(active_item_index) = active_item_index { + pane.update(cx, |pane, cx| { + pane.activate_item(active_item_index, false, false, cx); + })?; + } - // // anyhow::Ok(items) - // } + anyhow::Ok(items) + } } pub type GroupId = i64; diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 3f59312b11..0782e811e5 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -401,7 +401,7 @@ type ItemDeserializers = HashMap< Arc, fn( Model, - WindowHandle, + WeakView, WorkspaceId, ItemId, &mut ViewContext, @@ -936,17 +936,17 @@ impl Workspace { self.weak_self.clone() } - // pub fn left_dock(&self) -> &View { - // &self.left_dock - // } + pub fn left_dock(&self) -> &View { + &self.left_dock + } - // pub fn bottom_dock(&self) -> &View { - // &self.bottom_dock - // } + pub fn bottom_dock(&self) -> &View { + &self.bottom_dock + } - // pub fn right_dock(&self) -> &View { - // &self.right_dock - // } + pub fn right_dock(&self) -> &View { + &self.right_dock + } // pub fn add_panel(&mut self, panel: View, cx: &mut ViewContext) // where @@ -3394,126 +3394,127 @@ impl Workspace { cx: &mut ViewContext, ) -> Task>>>> { cx.spawn(|workspace, mut cx| async move { - // let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| { - // ( - // workspace.project().clone(), - // workspace.last_active_center_pane.clone(), - // ) - // })?; + let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| { + ( + workspace.project().clone(), + workspace.last_active_center_pane.clone(), + ) + })?; - // // let mut center_group: Option = None; - // // let mut center_items: Option>>> = None; + let mut center_group = None; + let mut center_items = None; - // // todo!() - // // // Traverse the splits tree and add to things - // if let Some((group, active_pane, items)) = serialized_workspace - // .center_group - // .deserialize(&project, serialized_workspace.id, workspace, &mut cx) - // .await - // { - // center_items = Some(items); - // center_group = Some((group, active_pane)) - // } + // Traverse the splits tree and add to things + if let Some((group, active_pane, items)) = serialized_workspace + .center_group + .deserialize(&project, serialized_workspace.id, workspace, &mut cx) + .await + { + center_items = Some(items); + center_group = Some((group, active_pane)) + } - // let mut items_by_project_path = cx.update(|_, cx| { - // center_items - // .unwrap_or_default() - // .into_iter() - // .filter_map(|item| { - // let item = item?; - // let project_path = item.project_path(cx)?; - // Some((project_path, item)) - // }) - // .collect::>() - // })?; + let mut items_by_project_path = cx.update(|_, cx| { + center_items + .unwrap_or_default() + .into_iter() + .filter_map(|item| { + let item = item?; + let project_path = item.project_path(cx)?; + Some((project_path, item)) + }) + .collect::>() + })?; - // let opened_items = paths_to_open - // .into_iter() - // .map(|path_to_open| { - // path_to_open - // .and_then(|path_to_open| items_by_project_path.remove(&path_to_open)) - // }) - // .collect::>(); + let opened_items = paths_to_open + .into_iter() + .map(|path_to_open| { + path_to_open + .and_then(|path_to_open| items_by_project_path.remove(&path_to_open)) + }) + .collect::>(); - // todo!() - // // Remove old panes from workspace panes list - // workspace.update(&mut cx, |workspace, cx| { - // if let Some((center_group, active_pane)) = center_group { - // workspace.remove_panes(workspace.center.root.clone(), cx); + // Remove old panes from workspace panes list + workspace.update(&mut cx, |workspace, cx| { + if let Some((center_group, active_pane)) = center_group { + workspace.remove_panes(workspace.center.root.clone(), cx); - // // Swap workspace center group - // workspace.center = PaneGroup::with_root(center_group); + // Swap workspace center group + workspace.center = PaneGroup::with_root(center_group); - // // Change the focus to the workspace first so that we retrigger focus in on the pane. - // cx.focus_self(); + // Change the focus to the workspace first so that we retrigger focus in on the pane. + todo!() + // cx.focus_self(); + // if let Some(active_pane) = active_pane { + // cx.focus(&active_pane); + // } else { + // cx.focus(workspace.panes.last().unwrap()); + // } + } else { + todo!() + // let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade()); + // if let Some(old_center_handle) = old_center_handle { + // cx.focus(&old_center_handle) + // } else { + // cx.focus_self() + // } + } - // if let Some(active_pane) = active_pane { - // cx.focus(&active_pane); - // } else { - // cx.focus(workspace.panes.last().unwrap()); - // } - // } else { - // let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade()); - // if let Some(old_center_handle) = old_center_handle { - // cx.focus(&old_center_handle) - // } else { - // cx.focus_self() - // } - // } + let docks = serialized_workspace.docks; + workspace.left_dock.update(cx, |dock, cx| { + dock.set_open(docks.left.visible, cx); + if let Some(active_panel) = docks.left.active_panel { + if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { + dock.activate_panel(ix, cx); + } + } + dock.active_panel() + .map(|panel| panel.set_zoomed(docks.left.zoom, cx)); + if docks.left.visible && docks.left.zoom { + todo!() + // cx.focus_self() + } + }); + // TODO: I think the bug is that setting zoom or active undoes the bottom zoom or something + workspace.right_dock.update(cx, |dock, cx| { + dock.set_open(docks.right.visible, cx); + if let Some(active_panel) = docks.right.active_panel { + if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { + dock.activate_panel(ix, cx); + } + } + dock.active_panel() + .map(|panel| panel.set_zoomed(docks.right.zoom, cx)); - // let docks = serialized_workspace.docks; - // workspace.left_dock.update(cx, |dock, cx| { - // dock.set_open(docks.left.visible, cx); - // if let Some(active_panel) = docks.left.active_panel { - // if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { - // dock.activate_panel(ix, cx); - // } - // } - // dock.active_panel() - // .map(|panel| panel.set_zoomed(docks.left.zoom, cx)); - // if docks.left.visible && docks.left.zoom { - // cx.focus_self() - // } - // }); - // // TODO: I think the bug is that setting zoom or active undoes the bottom zoom or something - // workspace.right_dock.update(cx, |dock, cx| { - // dock.set_open(docks.right.visible, cx); - // if let Some(active_panel) = docks.right.active_panel { - // if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { - // dock.activate_panel(ix, cx); - // } - // } - // dock.active_panel() - // .map(|panel| panel.set_zoomed(docks.right.zoom, cx)); + if docks.right.visible && docks.right.zoom { + todo!() + // cx.focus_self() + } + }); + workspace.bottom_dock.update(cx, |dock, cx| { + dock.set_open(docks.bottom.visible, cx); + if let Some(active_panel) = docks.bottom.active_panel { + if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { + dock.activate_panel(ix, cx); + } + } - // if docks.right.visible && docks.right.zoom { - // cx.focus_self() - // } - // }); - // workspace.bottom_dock.update(cx, |dock, cx| { - // dock.set_open(docks.bottom.visible, cx); - // if let Some(active_panel) = docks.bottom.active_panel { - // if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) { - // dock.activate_panel(ix, cx); - // } - // } + dock.active_panel() + .map(|panel| panel.set_zoomed(docks.bottom.zoom, cx)); - // dock.active_panel() - // .map(|panel| panel.set_zoomed(docks.bottom.zoom, cx)); + if docks.bottom.visible && docks.bottom.zoom { + todo!() + // cx.focus_self() + } + }); - // if docks.bottom.visible && docks.bottom.zoom { - // cx.focus_self() - // } - // }); - - // cx.notify(); - // })?; + cx.notify(); + })?; // Serialize ourself to make sure our timestamps and any pane / item changes are replicated - // workspace.update(&mut cx, |workspace, cx| workspace.serialize_workspace(cx))?; + workspace.update(&mut cx, |workspace, cx| workspace.serialize_workspace(cx))?; - // Ok(opened_items) - anyhow::bail!("todo") + Ok(opened_items) }) } @@ -3585,49 +3586,48 @@ fn window_bounds_env_override(cx: &AsyncAppContext) -> Option { } fn open_items( - _serialized_workspace: Option, + serialized_workspace: Option, project_paths_to_open: Vec<(PathBuf, Option)>, app_state: Arc, cx: &mut ViewContext, ) -> impl Future>>>>> { let mut opened_items = Vec::with_capacity(project_paths_to_open.len()); - // todo!() - // if let Some(serialized_workspace) = serialized_workspace { - // let restored_items = Workspace::load_workspace( - // serialized_workspace, - // project_paths_to_open - // .iter() - // .map(|(_, project_path)| project_path) - // .cloned() - // .collect(), - // cx, - // ) - // .await?; + if let Some(serialized_workspace) = serialized_workspace { + let restored_items = Workspace::load_workspace( + serialized_workspace, + project_paths_to_open + .iter() + .map(|(_, project_path)| project_path) + .cloned() + .collect(), + cx, + ) + .await?; - // let restored_project_paths = restored_items - // .iter() - // .filter_map(|item| item.as_ref()?.project_path(cx)) - // .collect::>(); + let restored_project_paths = restored_items + .iter() + .filter_map(|item| item.as_ref()?.project_path(cx)) + .collect::>(); - // for restored_item in restored_items { - // opened_items.push(restored_item.map(Ok)); - // } + for restored_item in restored_items { + opened_items.push(restored_item.map(Ok)); + } - // project_paths_to_open - // .iter_mut() - // .for_each(|(_, project_path)| { - // if let Some(project_path_to_open) = project_path { - // if restored_project_paths.contains(project_path_to_open) { - // *project_path = None; - // } - // } - // }); - // } else { - for _ in 0..project_paths_to_open.len() { - opened_items.push(None); + project_paths_to_open + .iter_mut() + .for_each(|(_, project_path)| { + if let Some(project_path_to_open) = project_path { + if restored_project_paths.contains(project_path_to_open) { + *project_path = None; + } + } + }); + } else { + for _ in 0..project_paths_to_open.len() { + opened_items.push(None); + } } - // } assert!(opened_items.len() == project_paths_to_open.len()); let tasks =