Detailed changes
@@ -13,7 +13,7 @@ use client2::{
};
use gpui2::{
AnyElement, AnyView, AppContext, EventEmitter, HighlightStyle, Model, Pixels, Point, Render,
- SharedString, Task, View, ViewContext, WeakView, WindowContext,
+ SharedString, Task, View, ViewContext, WeakView, WindowContext, WindowHandle,
};
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: WeakView<Workspace>,
+ _workspace: WindowHandle<Workspace>,
_workspace_id: WorkspaceId,
_item_id: ItemId,
_cx: &mut ViewContext<Pane>,
@@ -401,87 +401,86 @@ impl<T: Item> ItemHandle for View<T> {
let pending_update = Arc::new(Mutex::new(None));
let pending_update_scheduled = Arc::new(AtomicBool::new(false));
- let mut event_subscription =
- Some(cx.subscribe(self, move |workspace, item, event, cx| {
- let pane = if let Some(pane) = workspace
- .panes_by_item
- .get(&item.id())
- .and_then(|pane| pane.upgrade())
+ let event_subscription = Some(cx.subscribe(self, move |workspace, item, event, cx| {
+ let pane = if let Some(pane) = workspace
+ .panes_by_item
+ .get(&item.id())
+ .and_then(|pane| pane.upgrade())
+ {
+ pane
+ } else {
+ log::error!("unexpected item event after pane was dropped");
+ return;
+ };
+
+ if let Some(item) = item.to_followable_item_handle(cx) {
+ let _is_project_item = item.is_project_item(cx);
+ let leader_id = workspace.leader_for_pane(&pane);
+
+ if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
+ workspace.unfollow(&pane, cx);
+ }
+
+ if item.add_event_to_update_proto(event, &mut *pending_update.lock(), cx)
+ && !pending_update_scheduled.load(Ordering::SeqCst)
{
- pane
- } else {
- log::error!("unexpected item event after pane was dropped");
- return;
- };
-
- if let Some(item) = item.to_followable_item_handle(cx) {
- let _is_project_item = item.is_project_item(cx);
- let leader_id = workspace.leader_for_pane(&pane);
-
- if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
- workspace.unfollow(&pane, cx);
+ pending_update_scheduled.store(true, Ordering::SeqCst);
+ todo!("replace with on_next_frame?");
+ // cx.after_window_update({
+ // let pending_update = pending_update.clone();
+ // let pending_update_scheduled = pending_update_scheduled.clone();
+ // move |this, cx| {
+ // pending_update_scheduled.store(false, Ordering::SeqCst);
+ // this.update_followers(
+ // is_project_item,
+ // proto::update_followers::Variant::UpdateView(
+ // proto::UpdateView {
+ // id: item
+ // .remote_id(&this.app_state.client, cx)
+ // .map(|id| id.to_proto()),
+ // variant: pending_update.borrow_mut().take(),
+ // leader_id,
+ // },
+ // ),
+ // cx,
+ // );
+ // }
+ // });
+ }
+ }
+
+ for item_event in T::to_item_events(event).into_iter() {
+ match item_event {
+ ItemEvent::CloseItem => {
+ pane.update(cx, |pane, cx| {
+ pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
+ })
+ .detach_and_log_err(cx);
+ return;
}
- if item.add_event_to_update_proto(event, &mut *pending_update.lock(), cx)
- && !pending_update_scheduled.load(Ordering::SeqCst)
- {
- pending_update_scheduled.store(true, Ordering::SeqCst);
- todo!("replace with on_next_frame?");
- // cx.after_window_update({
- // let pending_update = pending_update.clone();
- // let pending_update_scheduled = pending_update_scheduled.clone();
- // move |this, cx| {
- // pending_update_scheduled.store(false, Ordering::SeqCst);
- // this.update_followers(
- // is_project_item,
- // proto::update_followers::Variant::UpdateView(
- // proto::UpdateView {
- // id: item
- // .remote_id(&this.app_state.client, cx)
- // .map(|id| id.to_proto()),
- // variant: pending_update.borrow_mut().take(),
- // leader_id,
- // },
- // ),
- // cx,
- // );
- // }
- // });
+ ItemEvent::UpdateTab => {
+ pane.update(cx, |_, cx| {
+ cx.emit(pane::Event::ChangeItemTitle);
+ cx.notify();
+ });
}
- }
- for item_event in T::to_item_events(event).into_iter() {
- match item_event {
- ItemEvent::CloseItem => {
- pane.update(cx, |pane, cx| {
- pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
- })
- .detach_and_log_err(cx);
- return;
- }
-
- ItemEvent::UpdateTab => {
- pane.update(cx, |_, cx| {
- cx.emit(pane::Event::ChangeItemTitle);
- cx.notify();
+ ItemEvent::Edit => {
+ let autosave = WorkspaceSettings::get_global(cx).autosave;
+ if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
+ let delay = Duration::from_millis(milliseconds);
+ let item = item.clone();
+ pending_autosave.fire_new(delay, cx, move |workspace, cx| {
+ Pane::autosave_item(&item, workspace.project().clone(), cx)
});
}
-
- ItemEvent::Edit => {
- let autosave = WorkspaceSettings::get_global(cx).autosave;
- if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
- let delay = Duration::from_millis(milliseconds);
- let item = item.clone();
- pending_autosave.fire_new(delay, cx, move |workspace, cx| {
- Pane::autosave_item(&item, workspace.project().clone(), cx)
- });
- }
- }
-
- _ => {}
}
+
+ _ => {}
}
- }));
+ }
+ }));
todo!("observe focus");
// cx.observe_focus(self, move |workspace, item, focused, cx| {
@@ -494,12 +493,12 @@ impl<T: Item> ItemHandle for View<T> {
// })
// .detach();
- let item_id = self.id();
- cx.observe_release(self, move |workspace, _, _| {
- workspace.panes_by_item.remove(&item_id);
- event_subscription.take();
- })
- .detach();
+ // let item_id = self.id();
+ // cx.observe_release(self, move |workspace, _, _| {
+ // workspace.panes_by_item.remove(&item_id);
+ // event_subscription.take();
+ // })
+ // .detach();
}
cx.defer(|workspace, cx| {
@@ -1,21 +1,14 @@
-use crate::{
- item::ItemHandle, Axis, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
-};
+use crate::{Axis, WorkspaceId};
use anyhow::{Context, Result};
-use async_recursion::async_recursion;
use db2::sqlez::{
bindable::{Bind, Column, StaticColumnCount},
statement::Statement,
};
-use gpui2::{
- AsyncAppContext, AsyncWindowContext, Model, Task, View, WeakView, WindowBounds, WindowHandle,
-};
-use project2::Project;
+use gpui2::WindowBounds;
use std::{
path::{Path, PathBuf},
sync::Arc,
};
-use util::ResultExt;
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -149,73 +142,75 @@ impl Default for SerializedPaneGroup {
}
}
-impl SerializedPaneGroup {
- #[async_recursion(?Send)]
- pub(crate) async fn deserialize(
- self,
- project: &Model<Project>,
- workspace_id: WorkspaceId,
- workspace: WindowHandle<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()?;
-
- 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
- }
- }
- }
- }
-}
+// 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
+// }
+// }
+// }
+// }
#[derive(Debug, PartialEq, Eq, Default, Clone)]
pub struct SerializedPane {
@@ -228,53 +223,55 @@ 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>>>> {
- 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: 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 type GroupId = i64;
@@ -288,15 +285,15 @@ pub struct SerializedItem {
pub active: bool,
}
-impl SerializedItem {
- pub fn new(kind: impl AsRef<str>, item_id: ItemId, active: bool) -> Self {
- Self {
- kind: Arc::from(kind.as_ref()),
- item_id,
- active,
- }
- }
-}
+// impl SerializedItem {
+// pub fn new(kind: impl AsRef<str>, item_id: ItemId, active: bool) -> Self {
+// Self {
+// kind: Arc::from(kind.as_ref()),
+// item_id,
+// active,
+// }
+// }
+// }
#[cfg(test)]
impl Default for SerializedItem {
@@ -25,16 +25,16 @@ use dock::{Dock, DockPosition, PanelButtons};
use futures::{
channel::{mpsc, oneshot},
future::try_join_all,
- FutureExt, StreamExt,
+ Future, FutureExt, StreamExt,
};
use gpui2::{
div, point, size, AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, Bounds,
- Context, Div, Entity, EventEmitter, GlobalPixels, MainThread, Model, ModelContext, Point,
- Render, Size, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds,
- WindowContext, WindowHandle, WindowOptions,
+ Context, Div, EventEmitter, GlobalPixels, MainThread, Model, ModelContext, Point, Render, Size,
+ Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowBounds, WindowContext,
+ WindowHandle, WindowOptions,
};
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
-use language2::LanguageRegistry;
+use language2::{LanguageRegistry, LocalFile};
use lazy_static::lazy_static;
use node_runtime::NodeRuntime;
use notifications::{simple_message_notification::MessageNotification, NotificationHandle};
@@ -412,7 +412,7 @@ pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) {
Arc::from(serialized_item_kind),
|project, workspace, workspace_id, item_id, cx| {
let task = I::deserialize(project, workspace, workspace_id, item_id, cx);
- cx.spawn_on_main(|cx| async { Ok(Box::new(task.await?) as Box<_>) })
+ cx.spawn_on_main(|_| async { Ok(Box::new(task.await?) as Box<_>) })
},
);
}
@@ -428,10 +428,10 @@ pub struct AppState {
pub build_window_options:
fn(Option<WindowBounds>, Option<Uuid>, &mut MainThread<AppContext>) -> WindowOptions,
pub initialize_workspace: fn(
- WindowHandle<Workspace>,
+ WeakView<Workspace>,
bool,
Arc<AppState>,
- AsyncAppContext,
+ AsyncWindowContext,
) -> Task<anyhow::Result<()>>,
pub node_runtime: Arc<dyn NodeRuntime>,
}
@@ -568,6 +568,9 @@ pub struct Workspace {
pane_history_timestamp: Arc<AtomicUsize>,
}
+trait AssertSend: Send {}
+impl AssertSend for WindowHandle<Workspace> {}
+
// struct ActiveModal {
// view: Box<dyn ModalHandle>,
// previously_focused_view_id: Option<usize>,
@@ -700,7 +703,7 @@ impl Workspace {
cx.build_view(|cx| PanelButtons::new(bottom_dock.clone(), weak_handle.clone(), cx));
let right_dock_buttons =
cx.build_view(|cx| PanelButtons::new(right_dock.clone(), weak_handle.clone(), cx));
- let status_bar = cx.build_view(|cx| {
+ let _status_bar = cx.build_view(|cx| {
let mut status_bar = StatusBar::new(¢er_pane.clone(), cx);
status_bar.add_left_item(left_dock_buttons, cx);
status_bar.add_right_item(right_dock_buttons, cx);
@@ -791,12 +794,14 @@ impl Workspace {
fn new_local(
abs_paths: Vec<PathBuf>,
app_state: Arc<AppState>,
- requesting_window: Option<WindowHandle<Workspace>>,
+ _requesting_window: Option<WindowHandle<Workspace>>,
cx: &mut MainThread<AppContext>,
- ) -> Task<(
- WeakView<Workspace>,
- Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
- )> {
+ ) -> Task<
+ anyhow::Result<(
+ WindowHandle<Workspace>,
+ Vec<Option<Result<Box<dyn ItemHandle>, anyhow::Error>>>,
+ )>,
+ > {
let project_handle = Project::local(
app_state.client.clone(),
app_state.node_runtime.clone(),
@@ -807,7 +812,7 @@ impl Workspace {
);
cx.spawn_on_main(|mut cx| async move {
- let serialized_workspace = persistence::DB.workspace_for_roots(&abs_paths.as_slice());
+ let serialized_workspace: Option<SerializedWorkspace> = None; //persistence::DB.workspace_for_roots(&abs_paths.as_slice());
let paths_to_open = Arc::new(abs_paths);
@@ -836,14 +841,15 @@ impl Workspace {
DB.next_id().await.unwrap_or(0)
};
- let window = if let Some(window) = requesting_window {
+ // todo!()
+ let window = /*if let Some(window) = requesting_window {
cx.update_window(window.into(), |old_workspace, cx| {
cx.replace_root_view(|cx| {
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
});
});
window
- } else {
+ } else */ {
let window_bounds_override = window_bounds_env_override(&cx);
let (bounds, display) = if let Some(bounds) = window_bounds_override {
(Some(bounds), None)
@@ -873,23 +879,34 @@ impl Workspace {
// Use the serialized workspace to construct the new window
let options =
cx.update(|cx| (app_state.build_window_options)(bounds, display, cx))?;
- cx.open_window(options, |cx| {
+
+ cx.open_window(options, {
+ let app_state = app_state.clone();
+ let workspace_id = workspace_id.clone();
+ let project_handle = project_handle.clone();
+ move |cx| {
cx.build_view(|cx| {
- Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
+ Workspace::new(workspace_id, project_handle, app_state, cx)
})
- })?
- };
+ }})?
+ };
+
+ // todo!() Ask how to do this
+ let weak_view = window.update(&mut cx, |_, cx| cx.view().downgrade())?;
+ let async_cx = window.update(&mut cx, |_, cx| cx.to_async())?;
(app_state.initialize_workspace)(
- window,
+ weak_view,
serialized_workspace.is_some(),
app_state.clone(),
- cx.clone(),
+ async_cx,
)
.await
.log_err();
- window.update(&mut cx, |_, cx| cx.activate_window());
+ window
+ .update(&mut cx, |_, cx| cx.activate_window())
+ .log_err();
notify_if_database_failed(window, &mut cx);
let opened_items = window
@@ -897,16 +914,16 @@ impl Workspace {
let workspace = cx.view().downgrade();
open_items(
serialized_workspace,
- &workspace,
+ // &workspace,
project_paths,
app_state,
cx,
)
- })
+ })?
.await
.unwrap_or_default();
- (window, opened_items)
+ Ok((window, opened_items))
})
}
@@ -2102,9 +2119,9 @@ impl Workspace {
> {
let project = self.project().clone();
let project_item = project.update(cx, |project, cx| project.open_path(path, cx));
- cx.spawn(|_, cx| async move {
+ cx.spawn(|_, mut cx| async move {
let (project_entry_id, project_item) = project_item.await?;
- let build_item = cx.update(|cx| {
+ let build_item = cx.update(|_, cx| {
cx.default_global::<ProjectItemBuilders>()
.get(&project_item.type_id())
.ok_or_else(|| anyhow!("no item builder for project item"))
@@ -2747,7 +2764,7 @@ impl Workspace {
title.push_str(" ↗");
}
- todo!()
+ // todo!()
// cx.set_window_title(&title);
}
@@ -3372,122 +3389,126 @@ 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 = None;
- let mut center_items = None;
- // 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 (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<_>>();
+ // 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);
+ // 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);
- // 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.
+ // 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()
- }
- }
+ // 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 {
- 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 {
- 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 {
- 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)
+ // Ok(opened_items)
+ anyhow::bail!("todo")
})
}
@@ -3558,49 +3579,50 @@ fn window_bounds_env_override(cx: &MainThread<AsyncAppContext>) -> Option<Window
})
}
-async fn open_items(
- serialized_workspace: Option<SerializedWorkspace>,
- mut project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>,
+fn open_items(
+ _serialized_workspace: Option<SerializedWorkspace>,
+ project_paths_to_open: Vec<(PathBuf, Option<ProjectPath>)>,
app_state: Arc<AppState>,
- mut cx: &mut MainThread<ViewContext<'_, Workspace>>,
-) -> Result<Vec<Option<Result<Box<dyn ItemHandle>>>>> {
+ cx: &mut MainThread<ViewContext<'_, Workspace>>,
+) -> impl Future<Output = Result<Vec<Option<Result<Box<dyn ItemHandle>>>>>> {
let mut opened_items = Vec::with_capacity(project_paths_to_open.len());
- 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));
- }
+ // 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));
+ // }
- 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 =
@@ -3629,16 +3651,17 @@ async fn open_items(
})
});
- for maybe_opened_path in futures::future::join_all(tasks.into_iter())
- .await
- .into_iter()
- {
- if let Some((i, path_open_result)) = maybe_opened_path {
- opened_items[i] = Some(path_open_result);
+ let tasks = tasks.collect::<Vec<_>>();
+ async move {
+ let tasks = futures::future::join_all(tasks.into_iter());
+ for maybe_opened_path in tasks.await.into_iter() {
+ if let Some((i, path_open_result)) = maybe_opened_path {
+ opened_items[i] = Some(path_open_result);
+ }
}
- }
- Ok(opened_items)
+ Ok(opened_items)
+ }
}
// fn notify_of_new_dock(workspace: &WeakView<Workspace>, cx: &mut AsyncAppContext) {
@@ -4102,8 +4125,8 @@ pub async fn activate_workspace_for_project(
continue;
};
- let predicate = cx
- .update_window_root(&workspace, |workspace, cx| {
+ let predicate = workspace
+ .update(cx, |workspace, cx| {
let project = workspace.project.read(cx);
if predicate(project, cx) {
cx.activate_window();
@@ -4326,10 +4349,11 @@ pub fn open_paths(
> {
let app_state = app_state.clone();
let abs_paths = abs_paths.to_vec();
- cx.spawn(move |mut cx| async move {
+ cx.spawn_on_main(move |mut cx| async move {
// Open paths in existing workspace if possible
- let existing = activate_workspace_for_project(&mut cx, move |project, cx| {
- project.contains_paths(&abs_paths, cx)
+ let existing = activate_workspace_for_project(&mut cx, {
+ let abs_paths = abs_paths.clone();
+ move |project, cx| project.contains_paths(&abs_paths, cx)
})
.await;
@@ -4343,32 +4367,30 @@ pub fn open_paths(
// ))
todo!()
} else {
- // Ok(cx
- // .update(|cx| {
- // Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx)
- // })
- // .await)
- todo!()
+ cx.update(move |cx| {
+ Workspace::new_local(abs_paths, app_state.clone(), requesting_window, cx)
+ })?
+ .await
}
})
}
pub fn open_new(
app_state: &Arc<AppState>,
- cx: &mut AppContext,
- init: impl FnOnce(&mut Workspace, &mut ViewContext<Workspace>) + 'static,
+ cx: &mut MainThread<AppContext>,
+ init: impl FnOnce(&mut Workspace, &mut ViewContext<Workspace>) + 'static + Send,
) -> 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();
+ cx.spawn_on_main(|mut cx| async move {
+ if let Some((workspace, opened_paths)) = task.await.log_err() {
+ workspace
+ .update(&mut cx, |workspace, cx| {
+ if opened_paths.is_empty() {
+ init(workspace, cx)
+ }
+ })
+ .log_err();
+ }
})
}
@@ -12,7 +12,7 @@ use client2::UserStore;
use db2::kvp::KEY_VALUE_STORE;
use fs2::RealFs;
use futures::{channel::mpsc, SinkExt, StreamExt};
-use gpui2::{Action, App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
+use gpui2::{Action, App, AppContext, AsyncAppContext, Context, MainThread, SemanticVersion, Task};
use isahc::{prelude::Configurable, Request};
use language2::LanguageRegistry;
use log::LevelFilter;
@@ -24,7 +24,7 @@ use settings2::{
default_settings, handle_settings_file_changes, watch_config_file, Settings, SettingsStore,
};
use simplelog::ConfigBuilder;
-use smol::process::Command;
+use smol::{future::FutureExt, process::Command};
use std::{
env,
ffi::OsStr,
@@ -40,6 +40,7 @@ use std::{
time::{SystemTime, UNIX_EPOCH},
};
use util::{
+ async_maybe,
channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL},
http::{self, HttpClient},
paths, ResultExt,
@@ -242,7 +243,7 @@ fn main() {
// .detach_and_log_err(cx)
}
Ok(None) | Err(_) => cx
- .spawn({
+ .spawn_on_main({
let app_state = app_state.clone();
|cx| async move { restore_or_create_workspace(&app_state, cx).await }
})
@@ -313,21 +314,33 @@ async fn installation_id() -> Result<String> {
}
}
-async fn restore_or_create_workspace(app_state: &Arc<AppState>, mut cx: AsyncAppContext) {
- 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();
- });
- }
+async fn restore_or_create_workspace(
+ app_state: &Arc<AppState>,
+ mut cx: MainThread<AsyncAppContext>,
+) {
+ async_maybe!({
+ 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("******* THIS IS A BAD KEY PLEASE UNCOMMENT BELOW TO FIX THIS VERY LONG LINE *******"), Ok(None)) {
+ // todo!(welcome)
+ //} else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) {
+ //todo!()
+ // cx.update(|cx| show_welcome_experience(app_state, cx));
+ } else {
+ cx.update(|cx| {
+ workspace2::open_new(app_state, cx, |workspace, cx| {
+ // todo!(editor)
+ // Editor::new_file(workspace, &Default::default(), cx)
+ })
+ .detach();
+ })?;
+ }
+ anyhow::Ok(())
+ })
+ .await
+ .log_err();
}
fn init_paths() {
@@ -7,7 +7,7 @@ pub use assets::*;
use collections::HashMap;
use gpui2::{
point, px, AppContext, AsyncAppContext, AsyncWindowContext, MainThread, Point, Task,
- TitlebarOptions, WeakView, WindowBounds, WindowKind, WindowOptions,
+ TitlebarOptions, WeakView, WindowBounds, WindowHandle, WindowKind, WindowOptions,
};
pub use only_instance::*;
pub use open_listener::*;
@@ -165,7 +165,7 @@ pub async fn handle_cli_connection(
if paths.is_empty() {
let (done_tx, done_rx) = oneshot::channel();
let _subscription =
- cx.update_window_root(&workspace, move |_, cx| {
+ workspace.update(&mut cx, move |_, cx| {
cx.on_release(|_, _| {
let _ = done_tx.send(());
})