@@ -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<Project>,
- _workspace: WindowHandle<Workspace>,
+ _workspace: WeakView<Workspace>,
_workspace_id: WorkspaceId,
_item_id: ItemId,
_cx: &mut ViewContext<Pane>,
@@ -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<Project>,
-// workspace_id: WorkspaceId,
-// workspace: WeakView<Workspace>,
-// cx: &mut AsyncAppContext,
-// ) -> Option<(Member, Option<View<Pane>>, Vec<Option<Box<dyn ItemHandle>>>)> {
-// 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.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()?;
-
-// // 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
-// }
-// }
-// }
-// }
+impl SerializedPaneGroup {
+ #[async_recursion(?Send)]
+ pub(crate) async fn deserialize(
+ self,
+ project: &Model<Project>,
+ workspace_id: WorkspaceId,
+ workspace: WeakView<Workspace>,
+ cx: &mut AsyncWindowContext,
+ ) -> Option<(Member, Option<View<Pane>>, Vec<Option<Box<dyn ItemHandle>>>)> {
+ 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.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()?;
+
+ 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<Project>,
- // _pane: &WeakView<Pane>,
- // _workspace_id: WorkspaceId,
- // _workspace: WindowHandle<Workspace>,
- // _cx: &mut AsyncAppContext,
- // ) -> Result<Vec<Option<Box<dyn ItemHandle>>>> {
- // 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::<ItemDeserializers>().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();
-
- // // 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 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);
- // // })?;
- // // }
-
- // // anyhow::Ok(items)
- // }
+ pub async fn deserialize_to(
+ &self,
+ project: &Model<Project>,
+ pane: &WeakView<Pane>,
+ workspace_id: WorkspaceId,
+ workspace: WeakView<Workspace>,
+ cx: &mut AsyncWindowContext,
+ ) -> Result<Vec<Option<Box<dyn ItemHandle>>>> {
+ 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::<ItemDeserializers>().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());
+
+ 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 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)
+ }
}
pub type GroupId = i64;
@@ -401,7 +401,7 @@ type ItemDeserializers = HashMap<
Arc<str>,
fn(
Model<Project>,
- WindowHandle<Workspace>,
+ WeakView<Workspace>,
WorkspaceId,
ItemId,
&mut ViewContext<Pane>,
@@ -936,17 +936,17 @@ impl Workspace {
self.weak_self.clone()
}
- // pub fn left_dock(&self) -> &View<Dock> {
- // &self.left_dock
- // }
+ pub fn left_dock(&self) -> &View<Dock> {
+ &self.left_dock
+ }
- // pub fn bottom_dock(&self) -> &View<Dock> {
- // &self.bottom_dock
- // }
+ pub fn bottom_dock(&self) -> &View<Dock> {
+ &self.bottom_dock
+ }
- // pub fn right_dock(&self) -> &View<Dock> {
- // &self.right_dock
- // }
+ pub fn right_dock(&self) -> &View<Dock> {
+ &self.right_dock
+ }
// pub fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>)
// where
@@ -3394,126 +3394,127 @@ impl Workspace {
cx: &mut ViewContext<Workspace>,
) -> Task<Result<Vec<Option<Box<dyn ItemHandle>>>>> {
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 mut center_group: Option = None;
- // // let mut center_items: Option<Vec<Option<Box<dyn ItemHandle>>>> = 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))
- // }
-
- // 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::<HashMap<_, _>>()
- // })?;
-
- // 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::<Vec<_>>();
-
- // 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);
+ let (project, old_center_pane) = workspace.update(&mut cx, |workspace, _| {
+ (
+ workspace.project().clone(),
+ workspace.last_active_center_pane.clone(),
+ )
+ })?;
- // // Swap workspace center group
- // workspace.center = PaneGroup::with_root(center_group);
+ let mut center_group = None;
+ let mut center_items = None;
- // // Change the focus to the workspace first so that we retrigger focus in on the pane.
- // cx.focus_self();
+ // 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))
+ }
- // 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 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::<HashMap<_, _>>()
+ })?;
+
+ 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::<Vec<_>>();
+
+ // 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);
+
+ // 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()
+ // }
+ }
- // 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));
+ 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));
- // 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);
- // }
- // }
+ 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);
+ }
+ }
- // 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 {
- // cx.focus_self()
- // }
- // });
+ if docks.bottom.visible && docks.bottom.zoom {
+ todo!()
+ // 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<WindowBounds> {
}
fn open_items(
- _serialized_workspace: Option<SerializedWorkspace>,
+ serialized_workspace: Option<SerializedWorkspace>,
project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>,
app_state: Arc<AppState>,
cx: &mut ViewContext<Workspace>,
) -> impl Future<Output = Result<Vec<Option<Result<Box<dyn ItemHandle>>>>>> {
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?;
-
- // let restored_project_paths = restored_items
- // .iter()
- // .filter_map(|item| item.as_ref()?.project_path(cx))
- // .collect::<HashSet<_>>();
-
- // for restored_item in restored_items {
- // opened_items.push(restored_item.map(Ok));
- // }
+ 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?;
- // 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);
+ let restored_project_paths = restored_items
+ .iter()
+ .filter_map(|item| item.as_ref()?.project_path(cx))
+ .collect::<HashSet<_>>();
+
+ 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);
+ }
}
- // }
assert!(opened_items.len() == project_paths_to_open.len());
let tasks =