WIP
This commit is contained in:
parent
d4d9fcc88c
commit
89bcbe3eeb
8 changed files with 1504 additions and 1493 deletions
|
@ -8,6 +8,7 @@ use client2::{
|
||||||
proto::{self, PeerId, ViewId},
|
proto::{self, PeerId, ViewId},
|
||||||
Client,
|
Client,
|
||||||
};
|
};
|
||||||
|
use settings2::Settings;
|
||||||
use theme2::Theme;
|
use theme2::Theme;
|
||||||
// use client2::{
|
// use client2::{
|
||||||
// proto::{self, PeerId},
|
// proto::{self, PeerId},
|
||||||
|
@ -16,8 +17,8 @@ use theme2::Theme;
|
||||||
// use gpui2::geometry::vector::Vector2F;
|
// use gpui2::geometry::vector::Vector2F;
|
||||||
// use gpui2::AnyWindowHandle;
|
// use gpui2::AnyWindowHandle;
|
||||||
// use gpui2::{
|
// use gpui2::{
|
||||||
// fonts::HighlightStyle, AnyElement, AnyViewHandle, AppContext, ModelHandle, Task, View,
|
// fonts::HighlightStyle, AnyElement, AnyViewHandle, AppContext, Handle, Task, View,
|
||||||
// ViewContext, ViewHandle, WeakViewHandle, WindowContext,
|
// ViewContext, View, WeakViewHandle, WindowContext,
|
||||||
// };
|
// };
|
||||||
// use project2::{Project, ProjectEntryId, ProjectPath};
|
// use project2::{Project, ProjectEntryId, ProjectPath};
|
||||||
// use schemars::JsonSchema;
|
// use schemars::JsonSchema;
|
||||||
|
@ -97,7 +98,7 @@ pub struct BreadcrumbText {
|
||||||
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Item: EventEmitter {
|
pub trait Item: EventEmitter + Sized {
|
||||||
// fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
// fn deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||||
// fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
// fn workspace_deactivated(&mut self, _: &mut ViewContext<Self>) {}
|
||||||
// fn navigate(&mut self, _: Box<dyn Any>, _: &mut ViewContext<Self>) -> bool {
|
// fn navigate(&mut self, _: Box<dyn Any>, _: &mut ViewContext<Self>) -> bool {
|
||||||
|
@ -138,14 +139,14 @@ pub trait Item: EventEmitter {
|
||||||
// }
|
// }
|
||||||
// fn save(
|
// fn save(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _project: ModelHandle<Project>,
|
// _project: Handle<Project>,
|
||||||
// _cx: &mut ViewContext<Self>,
|
// _cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<Result<()>> {
|
// ) -> Task<Result<()>> {
|
||||||
// unimplemented!("save() must be implemented if can_save() returns true")
|
// unimplemented!("save() must be implemented if can_save() returns true")
|
||||||
// }
|
// }
|
||||||
// fn save_as(
|
// fn save_as(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _project: ModelHandle<Project>,
|
// _project: Handle<Project>,
|
||||||
// _abs_path: PathBuf,
|
// _abs_path: PathBuf,
|
||||||
// _cx: &mut ViewContext<Self>,
|
// _cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<Result<()>> {
|
// ) -> Task<Result<()>> {
|
||||||
|
@ -153,7 +154,7 @@ pub trait Item: EventEmitter {
|
||||||
// }
|
// }
|
||||||
// fn reload(
|
// fn reload(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _project: ModelHandle<Project>,
|
// _project: Handle<Project>,
|
||||||
// _cx: &mut ViewContext<Self>,
|
// _cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<Result<()>> {
|
// ) -> Task<Result<()>> {
|
||||||
// unimplemented!("reload() must be implemented if can_save() returns true")
|
// unimplemented!("reload() must be implemented if can_save() returns true")
|
||||||
|
@ -171,7 +172,7 @@ pub trait Item: EventEmitter {
|
||||||
// fn act_as_type<'a>(
|
// fn act_as_type<'a>(
|
||||||
// &'a self,
|
// &'a self,
|
||||||
// type_id: TypeId,
|
// type_id: TypeId,
|
||||||
// self_handle: &'a ViewHandle<Self>,
|
// self_handle: &'a View<Self>,
|
||||||
// _: &'a AppContext,
|
// _: &'a AppContext,
|
||||||
// ) -> Option<&AnyViewHandle> {
|
// ) -> Option<&AnyViewHandle> {
|
||||||
// if TypeId::of::<Self>() == type_id {
|
// if TypeId::of::<Self>() == type_id {
|
||||||
|
@ -181,7 +182,7 @@ pub trait Item: EventEmitter {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn as_searchable(&self, _: &ViewHandle<Self>) -> Option<Box<dyn SearchableItemHandle>> {
|
// fn as_searchable(&self, _: &View<Self>) -> Option<Box<dyn SearchableItemHandle>> {
|
||||||
// None
|
// None
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -200,12 +201,12 @@ pub trait Item: EventEmitter {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn deserialize(
|
// fn deserialize(
|
||||||
// _project: ModelHandle<Project>,
|
// _project: Handle<Project>,
|
||||||
// _workspace: WeakViewHandle<Workspace>,
|
// _workspace: WeakViewHandle<Workspace>,
|
||||||
// _workspace_id: WorkspaceId,
|
// _workspace_id: WorkspaceId,
|
||||||
// _item_id: ItemId,
|
// _item_id: ItemId,
|
||||||
// _cx: &mut ViewContext<Pane>,
|
// _cx: &mut ViewContext<Pane>,
|
||||||
// ) -> Task<Result<ViewHandle<Self>>> {
|
// ) -> Task<Result<View<Self>>> {
|
||||||
// unimplemented!(
|
// unimplemented!(
|
||||||
// "deserialize() must be implemented if serialized_item_kind() returns Some(_)"
|
// "deserialize() must be implemented if serialized_item_kind() returns Some(_)"
|
||||||
// )
|
// )
|
||||||
|
@ -218,27 +219,36 @@ pub trait Item: EventEmitter {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
use core::fmt;
|
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::Any,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
cell::RefCell,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::Arc,
|
rc::Rc,
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicBool, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use gpui2::{
|
use gpui2::{
|
||||||
AnyElement, AnyView, AnyWindowHandle, AppContext, EventEmitter, Handle, HighlightStyle, Pixels,
|
AnyElement, AnyWindowHandle, AppContext, EventEmitter, Handle, HighlightStyle, Pixels, Point,
|
||||||
Point, Task, View, ViewContext, WindowContext,
|
Task, View, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
pane::Pane, searchable::SearchableItemHandle, ToolbarItemLocation, Workspace, WorkspaceId,
|
pane::{self, Pane},
|
||||||
|
searchable::SearchableItemHandle,
|
||||||
|
workspace_settings::{AutosaveSetting, WorkspaceSettings},
|
||||||
|
DelayedDebouncedEditAction, FollowableItemBuilders, ToolbarItemLocation, Workspace,
|
||||||
|
WorkspaceId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ItemHandle: 'static + fmt::Debug + Send {
|
pub trait ItemHandle: 'static + Send {
|
||||||
fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
&self,
|
&self,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
|
@ -305,355 +315,347 @@ pub trait WeakItemHandle {
|
||||||
|
|
||||||
// todo!()
|
// todo!()
|
||||||
// impl dyn ItemHandle {
|
// impl dyn ItemHandle {
|
||||||
// pub fn downcast<T: View>(&self) -> Option<ViewHandle<T>> {
|
// pub fn downcast<T: View>(&self) -> Option<View<T>> {
|
||||||
// self.as_any().clone().downcast()
|
// self.as_any().clone().downcast()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn act_as<T: View>(&self, cx: &AppContext) -> Option<ViewHandle<T>> {
|
// pub fn act_as<T: View>(&self, cx: &AppContext) -> Option<View<T>> {
|
||||||
// self.act_as_type(TypeId::of::<T>(), cx)
|
// self.act_as_type(TypeId::of::<T>(), cx)
|
||||||
// .and_then(|t| t.clone().downcast())
|
// .and_then(|t| t.clone().downcast())
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl<T: Item> ItemHandle for ViewHandle<T> {
|
impl<T: Item> ItemHandle for View<T> {
|
||||||
// fn subscribe_to_item_events(
|
fn subscribe_to_item_events(
|
||||||
// &self,
|
&self,
|
||||||
// cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
// handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
handler: Box<dyn Fn(ItemEvent, &mut WindowContext)>,
|
||||||
// ) -> gpui2::Subscription {
|
) -> gpui2::Subscription {
|
||||||
// cx.subscribe(self, move |_, event, cx| {
|
cx.subscribe(self, move |_, event, cx| {
|
||||||
// for item_event in T::to_item_events(event) {
|
for item_event in T::to_item_events(event) {
|
||||||
// handler(item_event, cx)
|
handler(item_event, cx)
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn tab_tooltip_text<'a>(&self, cx: &'a AppContext) -> Option<Cow<'a, str>> {
|
fn tab_tooltip_text<'a>(&self, cx: &'a AppContext) -> Option<Cow<'a, str>> {
|
||||||
// self.read(cx).tab_tooltip_text(cx)
|
self.read(cx).tab_tooltip_text(cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn tab_description<'a>(&'a self, detail: usize, cx: &'a AppContext) -> Option<Cow<'a, str>> {
|
fn tab_description<'a>(&'a self, detail: usize, cx: &'a AppContext) -> Option<Cow<'a, str>> {
|
||||||
// self.read(cx).tab_description(detail, cx)
|
self.read(cx).tab_description(detail, cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn tab_content(
|
fn tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Pane> {
|
||||||
// &self,
|
self.read(cx).tab_content(detail, cx)
|
||||||
// detail: Option<usize>,
|
}
|
||||||
// style: &theme2::Tab,
|
|
||||||
// cx: &AppContext,
|
|
||||||
// ) -> AnyElement<Pane> {
|
|
||||||
// self.read(cx).tab_content(detail, style, cx)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dragged_tab_content(
|
fn dragged_tab_content(&self, detail: Option<usize>, cx: &AppContext) -> AnyElement<Workspace> {
|
||||||
// &self,
|
self.read(cx).tab_content(detail, cx)
|
||||||
// detail: Option<usize>,
|
}
|
||||||
// style: &theme2::Tab,
|
|
||||||
// cx: &AppContext,
|
|
||||||
// ) -> AnyElement<Workspace> {
|
|
||||||
// self.read(cx).tab_content(detail, style, cx)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
fn project_path(&self, cx: &AppContext) -> Option<ProjectPath> {
|
||||||
// let this = self.read(cx);
|
let this = self.read(cx);
|
||||||
// let mut result = None;
|
let mut result = None;
|
||||||
// if this.is_singleton(cx) {
|
if this.is_singleton(cx) {
|
||||||
// this.for_each_project_item(cx, &mut |_, item| {
|
this.for_each_project_item(cx, &mut |_, item| {
|
||||||
// result = item.project_path(cx);
|
result = item.project_path(cx);
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// result
|
result
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
fn project_entry_ids(&self, cx: &AppContext) -> SmallVec<[ProjectEntryId; 3]> {
|
||||||
// let mut result = SmallVec::new();
|
let mut result = SmallVec::new();
|
||||||
// self.read(cx).for_each_project_item(cx, &mut |_, item| {
|
self.read(cx).for_each_project_item(cx, &mut |_, item| {
|
||||||
// if let Some(id) = item.entry_id(cx) {
|
if let Some(id) = item.entry_id(cx) {
|
||||||
// result.push(id);
|
result.push(id);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// result
|
result
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[usize; 3]> {
|
fn project_item_model_ids(&self, cx: &AppContext) -> SmallVec<[usize; 3]> {
|
||||||
// let mut result = SmallVec::new();
|
let mut result = SmallVec::new();
|
||||||
// self.read(cx).for_each_project_item(cx, &mut |id, _| {
|
self.read(cx).for_each_project_item(cx, &mut |id, _| {
|
||||||
// result.push(id);
|
result.push(id);
|
||||||
// });
|
});
|
||||||
// result
|
result
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn for_each_project_item(
|
fn for_each_project_item(
|
||||||
// &self,
|
&self,
|
||||||
// cx: &AppContext,
|
cx: &AppContext,
|
||||||
// f: &mut dyn FnMut(usize, &dyn project2::Item),
|
f: &mut dyn FnMut(usize, &dyn project2::Item),
|
||||||
// ) {
|
) {
|
||||||
// self.read(cx).for_each_project_item(cx, f)
|
self.read(cx).for_each_project_item(cx, f)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn is_singleton(&self, cx: &AppContext) -> bool {
|
fn is_singleton(&self, cx: &AppContext) -> bool {
|
||||||
// self.read(cx).is_singleton(cx)
|
self.read(cx).is_singleton(cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
fn boxed_clone(&self) -> Box<dyn ItemHandle> {
|
||||||
// Box::new(self.clone())
|
Box::new(self.clone())
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn clone_on_split(
|
fn clone_on_split(
|
||||||
// &self,
|
&self,
|
||||||
// workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
// cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
// ) -> Option<Box<dyn ItemHandle>> {
|
) -> Option<Box<dyn ItemHandle>> {
|
||||||
// self.update(cx, |item, cx| {
|
self.update(cx, |item, cx| {
|
||||||
// cx.add_option_view(|cx| item.clone_on_split(workspace_id, cx))
|
cx.add_option_view(|cx| item.clone_on_split(workspace_id, cx))
|
||||||
// })
|
})
|
||||||
// .map(|handle| Box::new(handle) as Box<dyn ItemHandle>)
|
.map(|handle| Box::new(handle) as Box<dyn ItemHandle>)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn added_to_pane(
|
fn added_to_pane(
|
||||||
// &self,
|
&self,
|
||||||
// workspace: &mut Workspace,
|
workspace: &mut Workspace,
|
||||||
// pane: ViewHandle<Pane>,
|
pane: View<Pane>,
|
||||||
// cx: &mut ViewContext<Workspace>,
|
cx: &mut ViewContext<Workspace>,
|
||||||
// ) {
|
) {
|
||||||
// let history = pane.read(cx).nav_history_for_item(self);
|
let history = pane.read(cx).nav_history_for_item(self);
|
||||||
// self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
// this.set_nav_history(history, cx);
|
this.set_nav_history(history, cx);
|
||||||
// this.added_to_workspace(workspace, cx);
|
this.added_to_workspace(workspace, cx);
|
||||||
// });
|
});
|
||||||
|
|
||||||
// if let Some(followed_item) = self.to_followable_item_handle(cx) {
|
if let Some(followed_item) = self.to_followable_item_handle(cx) {
|
||||||
// if let Some(message) = followed_item.to_state_proto(cx) {
|
if let Some(message) = followed_item.to_state_proto(cx) {
|
||||||
// workspace.update_followers(
|
workspace.update_followers(
|
||||||
// followed_item.is_project_item(cx),
|
followed_item.is_project_item(cx),
|
||||||
// proto::update_followers::Variant::CreateView(proto::View {
|
proto::update_followers::Variant::CreateView(proto::View {
|
||||||
// id: followed_item
|
id: followed_item
|
||||||
// .remote_id(&workspace.app_state.client, cx)
|
.remote_id(&workspace.app_state.client, cx)
|
||||||
// .map(|id| id.to_proto()),
|
.map(|id| id.to_proto()),
|
||||||
// variant: Some(message),
|
variant: Some(message),
|
||||||
// leader_id: workspace.leader_for_pane(&pane),
|
leader_id: workspace.leader_for_pane(&pane),
|
||||||
// }),
|
}),
|
||||||
// cx,
|
cx,
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if workspace
|
if workspace
|
||||||
// .panes_by_item
|
.panes_by_item
|
||||||
// .insert(self.id(), pane.downgrade())
|
.insert(self.id(), pane.downgrade())
|
||||||
// .is_none()
|
.is_none()
|
||||||
// {
|
{
|
||||||
// let mut pending_autosave = DelayedDebouncedEditAction::new();
|
let mut pending_autosave = DelayedDebouncedEditAction::new();
|
||||||
// let pending_update = Rc::new(RefCell::new(None));
|
let pending_update = Rc::new(RefCell::new(None));
|
||||||
// let pending_update_scheduled = Rc::new(AtomicBool::new(false));
|
let pending_update_scheduled = Rc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
// let mut event_subscription =
|
let mut event_subscription =
|
||||||
// Some(cx.subscribe(self, move |workspace, item, event, cx| {
|
Some(cx.subscribe(self, move |workspace, item, event, cx| {
|
||||||
// let pane = if let Some(pane) = workspace
|
let pane = if let Some(pane) = workspace
|
||||||
// .panes_by_item
|
.panes_by_item
|
||||||
// .get(&item.id())
|
.get(&item.id())
|
||||||
// .and_then(|pane| pane.upgrade(cx))
|
.and_then(|pane| pane.upgrade(cx))
|
||||||
// {
|
{
|
||||||
// pane
|
pane
|
||||||
// } else {
|
} else {
|
||||||
// log::error!("unexpected item event after pane was dropped");
|
log::error!("unexpected item event after pane was dropped");
|
||||||
// return;
|
return;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// if let Some(item) = item.to_followable_item_handle(cx) {
|
if let Some(item) = item.to_followable_item_handle(cx) {
|
||||||
// let is_project_item = item.is_project_item(cx);
|
let is_project_item = item.is_project_item(cx);
|
||||||
// let leader_id = workspace.leader_for_pane(&pane);
|
let leader_id = workspace.leader_for_pane(&pane);
|
||||||
|
|
||||||
// if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
|
if leader_id.is_some() && item.should_unfollow_on_event(event, cx) {
|
||||||
// workspace.unfollow(&pane, cx);
|
workspace.unfollow(&pane, cx);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if item.add_event_to_update_proto(
|
if item.add_event_to_update_proto(
|
||||||
// event,
|
event,
|
||||||
// &mut *pending_update.borrow_mut(),
|
&mut *pending_update.borrow_mut(),
|
||||||
// cx,
|
cx,
|
||||||
// ) && !pending_update_scheduled.load(Ordering::SeqCst)
|
) && !pending_update_scheduled.load(Ordering::SeqCst)
|
||||||
// {
|
{
|
||||||
// pending_update_scheduled.store(true, Ordering::SeqCst);
|
pending_update_scheduled.store(true, Ordering::SeqCst);
|
||||||
// cx.after_window_update({
|
cx.after_window_update({
|
||||||
// let pending_update = pending_update.clone();
|
let pending_update = pending_update.clone();
|
||||||
// let pending_update_scheduled = pending_update_scheduled.clone();
|
let pending_update_scheduled = pending_update_scheduled.clone();
|
||||||
// move |this, cx| {
|
move |this, cx| {
|
||||||
// pending_update_scheduled.store(false, Ordering::SeqCst);
|
pending_update_scheduled.store(false, Ordering::SeqCst);
|
||||||
// this.update_followers(
|
this.update_followers(
|
||||||
// is_project_item,
|
is_project_item,
|
||||||
// proto::update_followers::Variant::UpdateView(
|
proto::update_followers::Variant::UpdateView(
|
||||||
// proto::UpdateView {
|
proto::UpdateView {
|
||||||
// id: item
|
id: item
|
||||||
// .remote_id(&this.app_state.client, cx)
|
.remote_id(&this.app_state.client, cx)
|
||||||
// .map(|id| id.to_proto()),
|
.map(|id| id.to_proto()),
|
||||||
// variant: pending_update.borrow_mut().take(),
|
variant: pending_update.borrow_mut().take(),
|
||||||
// leader_id,
|
leader_id,
|
||||||
// },
|
},
|
||||||
// ),
|
),
|
||||||
// cx,
|
cx,
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// for item_event in T::to_item_events(event).into_iter() {
|
for item_event in T::to_item_events(event).into_iter() {
|
||||||
// match item_event {
|
match item_event {
|
||||||
// ItemEvent::CloseItem => {
|
ItemEvent::CloseItem => {
|
||||||
// pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
// pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
|
pane.close_item_by_id(item.id(), crate::SaveIntent::Close, cx)
|
||||||
// })
|
})
|
||||||
// .detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// ItemEvent::UpdateTab => {
|
ItemEvent::UpdateTab => {
|
||||||
// pane.update(cx, |_, cx| {
|
pane.update(cx, |_, cx| {
|
||||||
// cx.emit(pane::Event::ChangeItemTitle);
|
cx.emit(pane::Event::ChangeItemTitle);
|
||||||
// cx.notify();
|
cx.notify();
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// ItemEvent::Edit => {
|
ItemEvent::Edit => {
|
||||||
// let autosave = settings2::get::<WorkspaceSettings>(cx).autosave;
|
let autosave = WorkspaceSettings::get_global(cx).autosave;
|
||||||
// if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
|
if let AutosaveSetting::AfterDelay { milliseconds } = autosave {
|
||||||
// let delay = Duration::from_millis(milliseconds);
|
let delay = Duration::from_millis(milliseconds);
|
||||||
// let item = item.clone();
|
let item = item.clone();
|
||||||
// pending_autosave.fire_new(delay, cx, move |workspace, cx| {
|
pending_autosave.fire_new(delay, cx, move |workspace, cx| {
|
||||||
// Pane::autosave_item(&item, workspace.project().clone(), cx)
|
Pane::autosave_item(&item, workspace.project().clone(), cx)
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// _ => {}
|
_ => {}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }));
|
}));
|
||||||
|
|
||||||
// cx.observe_focus(self, move |workspace, item, focused, cx| {
|
cx.observe_focus(self, move |workspace, item, focused, cx| {
|
||||||
// if !focused
|
if !focused
|
||||||
// && settings2::get::<WorkspaceSettings>(cx).autosave
|
&& WorkspaceSettings::get_global(cx).autosave == AutosaveSetting::OnFocusChange
|
||||||
// == AutosaveSetting::OnFocusChange
|
{
|
||||||
// {
|
Pane::autosave_item(&item, workspace.project.clone(), cx)
|
||||||
// Pane::autosave_item(&item, workspace.project.clone(), cx)
|
.detach_and_log_err(cx);
|
||||||
// .detach_and_log_err(cx);
|
}
|
||||||
// }
|
})
|
||||||
// })
|
.detach();
|
||||||
// .detach();
|
|
||||||
|
|
||||||
// let item_id = self.id();
|
let item_id = self.id();
|
||||||
// cx.observe_release(self, move |workspace, _, _| {
|
cx.observe_release(self, move |workspace, _, _| {
|
||||||
// workspace.panes_by_item.remove(&item_id);
|
workspace.panes_by_item.remove(&item_id);
|
||||||
// event_subscription.take();
|
event_subscription.take();
|
||||||
// })
|
})
|
||||||
// .detach();
|
.detach();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// cx.defer(|workspace, cx| {
|
cx.defer(|workspace, cx| {
|
||||||
// workspace.serialize_workspace(cx);
|
workspace.serialize_workspace(cx);
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn deactivated(&self, cx: &mut WindowContext) {
|
fn deactivated(&self, cx: &mut WindowContext) {
|
||||||
// self.update(cx, |this, cx| this.deactivated(cx));
|
self.update(cx, |this, cx| this.deactivated(cx));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn workspace_deactivated(&self, cx: &mut WindowContext) {
|
fn workspace_deactivated(&self, cx: &mut WindowContext) {
|
||||||
// self.update(cx, |this, cx| this.workspace_deactivated(cx));
|
self.update(cx, |this, cx| this.workspace_deactivated(cx));
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn navigate(&self, data: Box<dyn Any>, cx: &mut WindowContext) -> bool {
|
fn navigate(&self, data: Box<dyn Any>, cx: &mut WindowContext) -> bool {
|
||||||
// self.update(cx, |this, cx| this.navigate(data, cx))
|
self.update(cx, |this, cx| this.navigate(data, cx))
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn id(&self) -> usize {
|
fn id(&self) -> usize {
|
||||||
// self.id()
|
self.id()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn window(&self) -> AnyWindowHandle {
|
fn window(&self) -> AnyWindowHandle {
|
||||||
// AnyViewHandle::window(self)
|
todo!()
|
||||||
// }
|
// AnyViewHandle::window(self)
|
||||||
|
}
|
||||||
|
|
||||||
// fn as_any(&self) -> &AnyViewHandle {
|
// todo!()
|
||||||
// self
|
// fn as_any(&self) -> &AnyViewHandle {
|
||||||
// }
|
// self
|
||||||
|
// }
|
||||||
|
|
||||||
// fn is_dirty(&self, cx: &AppContext) -> bool {
|
fn is_dirty(&self, cx: &AppContext) -> bool {
|
||||||
// self.read(cx).is_dirty(cx)
|
self.read(cx).is_dirty(cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn has_conflict(&self, cx: &AppContext) -> bool {
|
fn has_conflict(&self, cx: &AppContext) -> bool {
|
||||||
// self.read(cx).has_conflict(cx)
|
self.read(cx).has_conflict(cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn can_save(&self, cx: &AppContext) -> bool {
|
fn can_save(&self, cx: &AppContext) -> bool {
|
||||||
// self.read(cx).can_save(cx)
|
self.read(cx).can_save(cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn save(&self, project: ModelHandle<Project>, cx: &mut WindowContext) -> Task<Result<()>> {
|
fn save(&self, project: Handle<Project>, cx: &mut WindowContext) -> Task<Result<()>> {
|
||||||
// self.update(cx, |item, cx| item.save(project, cx))
|
self.update(cx, |item, cx| item.save(project, cx))
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn save_as(
|
fn save_as(
|
||||||
// &self,
|
&self,
|
||||||
// project: ModelHandle<Project>,
|
project: Handle<Project>,
|
||||||
// abs_path: PathBuf,
|
abs_path: PathBuf,
|
||||||
// cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
// ) -> Task<anyhow::Result<()>> {
|
) -> Task<anyhow::Result<()>> {
|
||||||
// self.update(cx, |item, cx| item.save_as(project, abs_path, cx))
|
self.update(cx, |item, cx| item.save_as(project, abs_path, cx))
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn reload(&self, project: ModelHandle<Project>, cx: &mut WindowContext) -> Task<Result<()>> {
|
fn reload(&self, project: Handle<Project>, cx: &mut WindowContext) -> Task<Result<()>> {
|
||||||
// self.update(cx, |item, cx| item.reload(project, cx))
|
self.update(cx, |item, cx| item.reload(project, cx))
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn act_as_type<'a>(&'a self, type_id: TypeId, cx: &'a AppContext) -> Option<&'a AnyViewHandle> {
|
// todo!()
|
||||||
// self.read(cx).act_as_type(type_id, self, cx)
|
// fn act_as_type<'a>(&'a self, type_id: TypeId, cx: &'a AppContext) -> Option<&'a AnyViewHandle> {
|
||||||
// }
|
// self.read(cx).act_as_type(type_id, self, cx)
|
||||||
|
// }
|
||||||
|
|
||||||
// fn to_followable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn FollowableItemHandle>> {
|
fn to_followable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn FollowableItemHandle>> {
|
||||||
// if cx.has_global::<FollowableItemBuilders>() {
|
if cx.has_global::<FollowableItemBuilders>() {
|
||||||
// let builders = cx.global::<FollowableItemBuilders>();
|
let builders = cx.global::<FollowableItemBuilders>();
|
||||||
// let item = self.as_any();
|
let item = self.as_any();
|
||||||
// Some(builders.get(&item.view_type())?.1(item))
|
Some(builders.get(&item.view_type())?.1(item))
|
||||||
// } else {
|
} else {
|
||||||
// None
|
None
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn on_release(
|
fn on_release(
|
||||||
// &self,
|
&self,
|
||||||
// cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
// callback: Box<dyn FnOnce(&mut AppContext)>,
|
callback: Box<dyn FnOnce(&mut AppContext)>,
|
||||||
// ) -> gpui2::Subscription {
|
) -> gpui2::Subscription {
|
||||||
// cx.observe_release(self, move |_, cx| callback(cx))
|
cx.observe_release(self, move |_, cx| callback(cx))
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn to_searchable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
|
fn to_searchable_item_handle(&self, cx: &AppContext) -> Option<Box<dyn SearchableItemHandle>> {
|
||||||
// self.read(cx).as_searchable(self)
|
self.read(cx).as_searchable(self)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation {
|
fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation {
|
||||||
// self.read(cx).breadcrumb_location()
|
self.read(cx).breadcrumb_location()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
|
fn breadcrumbs(&self, theme: &Theme, cx: &AppContext) -> Option<Vec<BreadcrumbText>> {
|
||||||
// self.read(cx).breadcrumbs(theme, cx)
|
self.read(cx).breadcrumbs(theme, cx)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn serialized_item_kind(&self) -> Option<&'static str> {
|
fn serialized_item_kind(&self) -> Option<&'static str> {
|
||||||
// T::serialized_item_kind()
|
T::serialized_item_kind()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn show_toolbar(&self, cx: &AppContext) -> bool {
|
fn show_toolbar(&self, cx: &AppContext) -> bool {
|
||||||
// self.read(cx).show_toolbar()
|
self.read(cx).show_toolbar()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn pixel_position_of_cursor(&self, cx: &AppContext) -> Option<Vector2F> {
|
fn pixel_position_of_cursor(&self, cx: &AppContext) -> Option<Point<Pixels>> {
|
||||||
// self.read(cx).pixel_position_of_cursor(cx)
|
self.read(cx).pixel_position_of_cursor(cx)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// impl From<Box<dyn ItemHandle>> for AnyViewHandle {
|
// impl From<Box<dyn ItemHandle>> for AnyViewHandle {
|
||||||
// fn from(val: Box<dyn ItemHandle>) -> Self {
|
// fn from(val: Box<dyn ItemHandle>) -> Self {
|
||||||
|
@ -747,7 +749,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
fn is_project_item(&self, cx: &AppContext) -> bool;
|
fn is_project_item(&self, cx: &AppContext) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<T: FollowableItem> FollowableItemHandle for ViewHandle<T> {
|
// impl<T: FollowableItem> FollowableItemHandle for View<T> {
|
||||||
// fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> {
|
// fn remote_id(&self, client: &Arc<Client>, cx: &AppContext) -> Option<ViewId> {
|
||||||
// self.read(cx).remote_id().or_else(|| {
|
// self.read(cx).remote_id().or_else(|| {
|
||||||
// client.peer_id().map(|creator| ViewId {
|
// client.peer_id().map(|creator| ViewId {
|
||||||
|
@ -780,7 +782,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
|
|
||||||
// fn apply_update_proto(
|
// fn apply_update_proto(
|
||||||
// &self,
|
// &self,
|
||||||
// project: &ModelHandle<Project>,
|
// project: &Handle<Project>,
|
||||||
// message: proto::update_view::Variant,
|
// message: proto::update_view::Variant,
|
||||||
// cx: &mut WindowContext,
|
// cx: &mut WindowContext,
|
||||||
// ) -> Task<Result<()>> {
|
// ) -> Task<Result<()>> {
|
||||||
|
@ -805,8 +807,8 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// use super::{Item, ItemEvent};
|
// use super::{Item, ItemEvent};
|
||||||
// use crate::{ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
|
// use crate::{ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId};
|
||||||
// use gpui2::{
|
// use gpui2::{
|
||||||
// elements::Empty, AnyElement, AppContext, Element, Entity, ModelHandle, Task, View,
|
// elements::Empty, AnyElement, AppContext, Element, Entity, Handle, Task, View,
|
||||||
// ViewContext, ViewHandle, WeakViewHandle,
|
// ViewContext, View, WeakViewHandle,
|
||||||
// };
|
// };
|
||||||
// use project2::{Project, ProjectEntryId, ProjectPath, WorktreeId};
|
// use project2::{Project, ProjectEntryId, ProjectPath, WorktreeId};
|
||||||
// use smallvec::SmallVec;
|
// use smallvec::SmallVec;
|
||||||
|
@ -827,7 +829,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// pub is_dirty: bool,
|
// pub is_dirty: bool,
|
||||||
// pub is_singleton: bool,
|
// pub is_singleton: bool,
|
||||||
// pub has_conflict: bool,
|
// pub has_conflict: bool,
|
||||||
// pub project_items: Vec<ModelHandle<TestProjectItem>>,
|
// pub project_items: Vec<Handle<TestProjectItem>>,
|
||||||
// pub nav_history: Option<ItemNavHistory>,
|
// pub nav_history: Option<ItemNavHistory>,
|
||||||
// pub tab_descriptions: Option<Vec<&'static str>>,
|
// pub tab_descriptions: Option<Vec<&'static str>>,
|
||||||
// pub tab_detail: Cell<Option<usize>>,
|
// pub tab_detail: Cell<Option<usize>>,
|
||||||
|
@ -872,7 +874,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl TestProjectItem {
|
// impl TestProjectItem {
|
||||||
// pub fn new(id: u64, path: &str, cx: &mut AppContext) -> ModelHandle<Self> {
|
// pub fn new(id: u64, path: &str, cx: &mut AppContext) -> Handle<Self> {
|
||||||
// let entry_id = Some(ProjectEntryId::from_proto(id));
|
// let entry_id = Some(ProjectEntryId::from_proto(id));
|
||||||
// let project_path = Some(ProjectPath {
|
// let project_path = Some(ProjectPath {
|
||||||
// worktree_id: WorktreeId::from_usize(0),
|
// worktree_id: WorktreeId::from_usize(0),
|
||||||
|
@ -884,7 +886,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn new_untitled(cx: &mut AppContext) -> ModelHandle<Self> {
|
// pub fn new_untitled(cx: &mut AppContext) -> Handle<Self> {
|
||||||
// cx.add_model(|_| Self {
|
// cx.add_model(|_| Self {
|
||||||
// project_path: None,
|
// project_path: None,
|
||||||
// entry_id: None,
|
// entry_id: None,
|
||||||
|
@ -937,7 +939,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// self
|
// self
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn with_project_items(mut self, items: &[ModelHandle<TestProjectItem>]) -> Self {
|
// pub fn with_project_items(mut self, items: &[Handle<TestProjectItem>]) -> Self {
|
||||||
// self.project_items.clear();
|
// self.project_items.clear();
|
||||||
// self.project_items.extend(items.iter().cloned());
|
// self.project_items.extend(items.iter().cloned());
|
||||||
// self
|
// self
|
||||||
|
@ -1048,7 +1050,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
|
|
||||||
// fn save(
|
// fn save(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _: ModelHandle<Project>,
|
// _: Handle<Project>,
|
||||||
// _: &mut ViewContext<Self>,
|
// _: &mut ViewContext<Self>,
|
||||||
// ) -> Task<anyhow::Result<()>> {
|
// ) -> Task<anyhow::Result<()>> {
|
||||||
// self.save_count += 1;
|
// self.save_count += 1;
|
||||||
|
@ -1058,7 +1060,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
|
|
||||||
// fn save_as(
|
// fn save_as(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _: ModelHandle<Project>,
|
// _: Handle<Project>,
|
||||||
// _: std::path::PathBuf,
|
// _: std::path::PathBuf,
|
||||||
// _: &mut ViewContext<Self>,
|
// _: &mut ViewContext<Self>,
|
||||||
// ) -> Task<anyhow::Result<()>> {
|
// ) -> Task<anyhow::Result<()>> {
|
||||||
|
@ -1069,7 +1071,7 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
|
|
||||||
// fn reload(
|
// fn reload(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// _: ModelHandle<Project>,
|
// _: Handle<Project>,
|
||||||
// _: &mut ViewContext<Self>,
|
// _: &mut ViewContext<Self>,
|
||||||
// ) -> Task<anyhow::Result<()>> {
|
// ) -> Task<anyhow::Result<()>> {
|
||||||
// self.reload_count += 1;
|
// self.reload_count += 1;
|
||||||
|
@ -1086,12 +1088,12 @@ pub trait FollowableItemHandle: ItemHandle {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn deserialize(
|
// fn deserialize(
|
||||||
// _project: ModelHandle<Project>,
|
// _project: Handle<Project>,
|
||||||
// _workspace: WeakViewHandle<Workspace>,
|
// _workspace: WeakViewHandle<Workspace>,
|
||||||
// workspace_id: WorkspaceId,
|
// workspace_id: WorkspaceId,
|
||||||
// _item_id: ItemId,
|
// _item_id: ItemId,
|
||||||
// cx: &mut ViewContext<Pane>,
|
// cx: &mut ViewContext<Pane>,
|
||||||
// ) -> Task<anyhow::Result<ViewHandle<Self>>> {
|
// ) -> Task<anyhow::Result<View<Self>>> {
|
||||||
// let view = cx.add_view(|_cx| Self::new_deserialized(workspace_id));
|
// let view = cx.add_view(|_cx| Self::new_deserialized(workspace_id));
|
||||||
// Task::Ready(Some(anyhow::Ok(view)))
|
// Task::Ready(Some(anyhow::Ok(view)))
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// WindowContext,
|
// WindowContext,
|
||||||
// };
|
// };
|
||||||
// use project2::{Project, ProjectEntryId, ProjectPath};
|
// use project2::{Project, ProjectEntryId, ProjectPath};
|
||||||
// use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
// use std::{
|
// use std::{
|
||||||
// any::Any,
|
// any::Any,
|
||||||
// cell::RefCell,
|
// cell::RefCell,
|
||||||
|
@ -44,24 +44,24 @@
|
||||||
// use theme2::{Theme, ThemeSettings};
|
// use theme2::{Theme, ThemeSettings};
|
||||||
// use util::truncate_and_remove_front;
|
// use util::truncate_and_remove_front;
|
||||||
|
|
||||||
// #[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
|
#[derive(PartialEq, Clone, Copy, Deserialize, Debug)]
|
||||||
// #[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
// pub enum SaveIntent {
|
pub enum SaveIntent {
|
||||||
// /// write all files (even if unchanged)
|
/// write all files (even if unchanged)
|
||||||
// /// prompt before overwriting on-disk changes
|
/// prompt before overwriting on-disk changes
|
||||||
// Save,
|
Save,
|
||||||
// /// write any files that have local changes
|
/// write any files that have local changes
|
||||||
// /// prompt before overwriting on-disk changes
|
/// prompt before overwriting on-disk changes
|
||||||
// SaveAll,
|
SaveAll,
|
||||||
// /// always prompt for a new path
|
/// always prompt for a new path
|
||||||
// SaveAs,
|
SaveAs,
|
||||||
// /// prompt "you have unsaved changes" before writing
|
/// prompt "you have unsaved changes" before writing
|
||||||
// Close,
|
Close,
|
||||||
// /// write all dirty files, don't prompt on conflict
|
/// write all dirty files, don't prompt on conflict
|
||||||
// Overwrite,
|
Overwrite,
|
||||||
// /// skip all save-related behavior
|
/// skip all save-related behavior
|
||||||
// Skip,
|
Skip,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// #[derive(Clone, Deserialize, PartialEq)]
|
// #[derive(Clone, Deserialize, PartialEq)]
|
||||||
// pub struct ActivateItem(pub usize);
|
// pub struct ActivateItem(pub usize);
|
||||||
|
@ -159,7 +159,10 @@ pub enum Event {
|
||||||
ZoomOut,
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::item::{ItemHandle, WeakItemHandle};
|
use crate::{
|
||||||
|
item::{ItemHandle, WeakItemHandle},
|
||||||
|
SplitDirection,
|
||||||
|
};
|
||||||
use collections::{HashMap, VecDeque};
|
use collections::{HashMap, VecDeque};
|
||||||
use gpui2::{Handle, ViewContext, WeakView};
|
use gpui2::{Handle, ViewContext, WeakView};
|
||||||
use project2::{Project, ProjectEntryId, ProjectPath};
|
use project2::{Project, ProjectEntryId, ProjectPath};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,13 +5,13 @@ pub mod model;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Context, Result};
|
use anyhow::{anyhow, bail, Context, Result};
|
||||||
use db::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql};
|
use db2::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql};
|
||||||
use gpui::{platform::WindowBounds, Axis};
|
use gpui2::WindowBounds;
|
||||||
|
|
||||||
use util::{unzip_option, ResultExt};
|
use util::{unzip_option, ResultExt};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::WorkspaceId;
|
use crate::{Axis, WorkspaceId};
|
||||||
|
|
||||||
use model::{
|
use model::{
|
||||||
GroupId, PaneId, SerializedItem, SerializedPane, SerializedPaneGroup, SerializedWorkspace,
|
GroupId, PaneId, SerializedItem, SerializedPane, SerializedPaneGroup, SerializedWorkspace,
|
||||||
|
@ -549,424 +549,425 @@ impl WorkspaceDb {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
// todo!()
|
||||||
mod tests {
|
// #[cfg(test)]
|
||||||
use super::*;
|
// mod tests {
|
||||||
use db::open_test_db;
|
// use super::*;
|
||||||
|
// use db::open_test_db;
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_next_id_stability() {
|
// async fn test_next_id_stability() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("test_next_id_stability").await);
|
// let db = WorkspaceDb(open_test_db("test_next_id_stability").await);
|
||||||
|
|
||||||
db.write(|conn| {
|
// db.write(|conn| {
|
||||||
conn.migrate(
|
// conn.migrate(
|
||||||
"test_table",
|
// "test_table",
|
||||||
&[sql!(
|
// &[sql!(
|
||||||
CREATE TABLE test_table(
|
// CREATE TABLE test_table(
|
||||||
text TEXT,
|
// text TEXT,
|
||||||
workspace_id INTEGER,
|
// workspace_id INTEGER,
|
||||||
FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
|
// FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
|
||||||
ON DELETE CASCADE
|
// ON DELETE CASCADE
|
||||||
) STRICT;
|
// ) STRICT;
|
||||||
)],
|
// )],
|
||||||
)
|
// )
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
})
|
// })
|
||||||
.await;
|
// .await;
|
||||||
|
|
||||||
let id = db.next_id().await.unwrap();
|
// let id = db.next_id().await.unwrap();
|
||||||
// Assert the empty row got inserted
|
// // Assert the empty row got inserted
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
Some(id),
|
// Some(id),
|
||||||
db.select_row_bound::<WorkspaceId, WorkspaceId>(sql!(
|
// db.select_row_bound::<WorkspaceId, WorkspaceId>(sql!(
|
||||||
SELECT workspace_id FROM workspaces WHERE workspace_id = ?
|
// SELECT workspace_id FROM workspaces WHERE workspace_id = ?
|
||||||
))
|
// ))
|
||||||
.unwrap()(id)
|
// .unwrap()(id)
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
);
|
// );
|
||||||
|
|
||||||
db.write(move |conn| {
|
// db.write(move |conn| {
|
||||||
conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
||||||
.unwrap()(("test-text-1", id))
|
// .unwrap()(("test-text-1", id))
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
})
|
// })
|
||||||
.await;
|
// .await;
|
||||||
|
|
||||||
let test_text_1 = db
|
// let test_text_1 = db
|
||||||
.select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
||||||
.unwrap()(1)
|
// .unwrap()(1)
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
assert_eq!(test_text_1, "test-text-1");
|
// assert_eq!(test_text_1, "test-text-1");
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_workspace_id_stability() {
|
// async fn test_workspace_id_stability() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("test_workspace_id_stability").await);
|
// let db = WorkspaceDb(open_test_db("test_workspace_id_stability").await);
|
||||||
|
|
||||||
db.write(|conn| {
|
// db.write(|conn| {
|
||||||
conn.migrate(
|
// conn.migrate(
|
||||||
"test_table",
|
// "test_table",
|
||||||
&[sql!(
|
// &[sql!(
|
||||||
CREATE TABLE test_table(
|
// CREATE TABLE test_table(
|
||||||
text TEXT,
|
// text TEXT,
|
||||||
workspace_id INTEGER,
|
// workspace_id INTEGER,
|
||||||
FOREIGN KEY(workspace_id)
|
// FOREIGN KEY(workspace_id)
|
||||||
REFERENCES workspaces(workspace_id)
|
// REFERENCES workspaces(workspace_id)
|
||||||
ON DELETE CASCADE
|
// ON DELETE CASCADE
|
||||||
) STRICT;)],
|
// ) STRICT;)],
|
||||||
)
|
// )
|
||||||
})
|
// })
|
||||||
.await
|
// .await
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
let mut workspace_1 = SerializedWorkspace {
|
// let mut workspace_1 = SerializedWorkspace {
|
||||||
id: 1,
|
// id: 1,
|
||||||
location: (["/tmp", "/tmp2"]).into(),
|
// location: (["/tmp", "/tmp2"]).into(),
|
||||||
center_group: Default::default(),
|
// center_group: Default::default(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
let workspace_2 = SerializedWorkspace {
|
// let workspace_2 = SerializedWorkspace {
|
||||||
id: 2,
|
// id: 2,
|
||||||
location: (["/tmp"]).into(),
|
// location: (["/tmp"]).into(),
|
||||||
center_group: Default::default(),
|
// center_group: Default::default(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
db.save_workspace(workspace_1.clone()).await;
|
// db.save_workspace(workspace_1.clone()).await;
|
||||||
|
|
||||||
db.write(|conn| {
|
// db.write(|conn| {
|
||||||
conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
||||||
.unwrap()(("test-text-1", 1))
|
// .unwrap()(("test-text-1", 1))
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
})
|
// })
|
||||||
.await;
|
// .await;
|
||||||
|
|
||||||
db.save_workspace(workspace_2.clone()).await;
|
// db.save_workspace(workspace_2.clone()).await;
|
||||||
|
|
||||||
db.write(|conn| {
|
// db.write(|conn| {
|
||||||
conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?)))
|
||||||
.unwrap()(("test-text-2", 2))
|
// .unwrap()(("test-text-2", 2))
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
})
|
// })
|
||||||
.await;
|
// .await;
|
||||||
|
|
||||||
workspace_1.location = (["/tmp", "/tmp3"]).into();
|
// workspace_1.location = (["/tmp", "/tmp3"]).into();
|
||||||
db.save_workspace(workspace_1.clone()).await;
|
// db.save_workspace(workspace_1.clone()).await;
|
||||||
db.save_workspace(workspace_1).await;
|
// db.save_workspace(workspace_1).await;
|
||||||
db.save_workspace(workspace_2).await;
|
// db.save_workspace(workspace_2).await;
|
||||||
|
|
||||||
let test_text_2 = db
|
// let test_text_2 = db
|
||||||
.select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
||||||
.unwrap()(2)
|
// .unwrap()(2)
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
assert_eq!(test_text_2, "test-text-2");
|
// assert_eq!(test_text_2, "test-text-2");
|
||||||
|
|
||||||
let test_text_1 = db
|
// let test_text_1 = db
|
||||||
.select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?))
|
||||||
.unwrap()(1)
|
// .unwrap()(1)
|
||||||
.unwrap()
|
// .unwrap()
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
assert_eq!(test_text_1, "test-text-1");
|
// assert_eq!(test_text_1, "test-text-1");
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn group(axis: gpui::Axis, children: Vec<SerializedPaneGroup>) -> SerializedPaneGroup {
|
// fn group(axis: gpui::Axis, children: Vec<SerializedPaneGroup>) -> SerializedPaneGroup {
|
||||||
SerializedPaneGroup::Group {
|
// SerializedPaneGroup::Group {
|
||||||
axis,
|
// axis,
|
||||||
flexes: None,
|
// flexes: None,
|
||||||
children,
|
// children,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_full_workspace_serialization() {
|
// async fn test_full_workspace_serialization() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("test_full_workspace_serialization").await);
|
// let db = WorkspaceDb(open_test_db("test_full_workspace_serialization").await);
|
||||||
|
|
||||||
// -----------------
|
// // -----------------
|
||||||
// | 1,2 | 5,6 |
|
// // | 1,2 | 5,6 |
|
||||||
// | - - - | |
|
// // | - - - | |
|
||||||
// | 3,4 | |
|
// // | 3,4 | |
|
||||||
// -----------------
|
// // -----------------
|
||||||
let center_group = group(
|
// let center_group = group(
|
||||||
gpui::Axis::Horizontal,
|
// gpui::Axis::Horizontal,
|
||||||
vec![
|
// vec![
|
||||||
group(
|
// group(
|
||||||
gpui::Axis::Vertical,
|
// gpui::Axis::Vertical,
|
||||||
vec![
|
// vec![
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 5, false),
|
// SerializedItem::new("Terminal", 5, false),
|
||||||
SerializedItem::new("Terminal", 6, true),
|
// SerializedItem::new("Terminal", 6, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 7, true),
|
// SerializedItem::new("Terminal", 7, true),
|
||||||
SerializedItem::new("Terminal", 8, false),
|
// SerializedItem::new("Terminal", 8, false),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 9, false),
|
// SerializedItem::new("Terminal", 9, false),
|
||||||
SerializedItem::new("Terminal", 10, true),
|
// SerializedItem::new("Terminal", 10, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
|
|
||||||
let workspace = SerializedWorkspace {
|
// let workspace = SerializedWorkspace {
|
||||||
id: 5,
|
// id: 5,
|
||||||
location: (["/tmp", "/tmp2"]).into(),
|
// location: (["/tmp", "/tmp2"]).into(),
|
||||||
center_group,
|
// center_group,
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
let round_trip_workspace = db.workspace_for_roots(&["/tmp2", "/tmp"]);
|
// let round_trip_workspace = db.workspace_for_roots(&["/tmp2", "/tmp"]);
|
||||||
|
|
||||||
assert_eq!(workspace, round_trip_workspace.unwrap());
|
// assert_eq!(workspace, round_trip_workspace.unwrap());
|
||||||
|
|
||||||
// Test guaranteed duplicate IDs
|
// // Test guaranteed duplicate IDs
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
|
|
||||||
let round_trip_workspace = db.workspace_for_roots(&["/tmp", "/tmp2"]);
|
// let round_trip_workspace = db.workspace_for_roots(&["/tmp", "/tmp2"]);
|
||||||
assert_eq!(workspace, round_trip_workspace.unwrap());
|
// assert_eq!(workspace, round_trip_workspace.unwrap());
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_workspace_assignment() {
|
// async fn test_workspace_assignment() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("test_basic_functionality").await);
|
// let db = WorkspaceDb(open_test_db("test_basic_functionality").await);
|
||||||
|
|
||||||
let workspace_1 = SerializedWorkspace {
|
// let workspace_1 = SerializedWorkspace {
|
||||||
id: 1,
|
// id: 1,
|
||||||
location: (["/tmp", "/tmp2"]).into(),
|
// location: (["/tmp", "/tmp2"]).into(),
|
||||||
center_group: Default::default(),
|
// center_group: Default::default(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
let mut workspace_2 = SerializedWorkspace {
|
// let mut workspace_2 = SerializedWorkspace {
|
||||||
id: 2,
|
// id: 2,
|
||||||
location: (["/tmp"]).into(),
|
// location: (["/tmp"]).into(),
|
||||||
center_group: Default::default(),
|
// center_group: Default::default(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
db.save_workspace(workspace_1.clone()).await;
|
// db.save_workspace(workspace_1.clone()).await;
|
||||||
db.save_workspace(workspace_2.clone()).await;
|
// db.save_workspace(workspace_2.clone()).await;
|
||||||
|
|
||||||
// Test that paths are treated as a set
|
// // Test that paths are treated as a set
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
||||||
workspace_1
|
// workspace_1
|
||||||
);
|
// );
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
db.workspace_for_roots(&["/tmp2", "/tmp"]).unwrap(),
|
// db.workspace_for_roots(&["/tmp2", "/tmp"]).unwrap(),
|
||||||
workspace_1
|
// workspace_1
|
||||||
);
|
// );
|
||||||
|
|
||||||
// Make sure that other keys work
|
// // Make sure that other keys work
|
||||||
assert_eq!(db.workspace_for_roots(&["/tmp"]).unwrap(), workspace_2);
|
// assert_eq!(db.workspace_for_roots(&["/tmp"]).unwrap(), workspace_2);
|
||||||
assert_eq!(db.workspace_for_roots(&["/tmp3", "/tmp2", "/tmp4"]), None);
|
// assert_eq!(db.workspace_for_roots(&["/tmp3", "/tmp2", "/tmp4"]), None);
|
||||||
|
|
||||||
// Test 'mutate' case of updating a pre-existing id
|
// // Test 'mutate' case of updating a pre-existing id
|
||||||
workspace_2.location = (["/tmp", "/tmp2"]).into();
|
// workspace_2.location = (["/tmp", "/tmp2"]).into();
|
||||||
|
|
||||||
db.save_workspace(workspace_2.clone()).await;
|
// db.save_workspace(workspace_2.clone()).await;
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
||||||
workspace_2
|
// workspace_2
|
||||||
);
|
// );
|
||||||
|
|
||||||
// Test other mechanism for mutating
|
// // Test other mechanism for mutating
|
||||||
let mut workspace_3 = SerializedWorkspace {
|
// let mut workspace_3 = SerializedWorkspace {
|
||||||
id: 3,
|
// id: 3,
|
||||||
location: (&["/tmp", "/tmp2"]).into(),
|
// location: (&["/tmp", "/tmp2"]).into(),
|
||||||
center_group: Default::default(),
|
// center_group: Default::default(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
};
|
// };
|
||||||
|
|
||||||
db.save_workspace(workspace_3.clone()).await;
|
// db.save_workspace(workspace_3.clone()).await;
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(),
|
||||||
workspace_3
|
// workspace_3
|
||||||
);
|
// );
|
||||||
|
|
||||||
// Make sure that updating paths differently also works
|
// // Make sure that updating paths differently also works
|
||||||
workspace_3.location = (["/tmp3", "/tmp4", "/tmp2"]).into();
|
// workspace_3.location = (["/tmp3", "/tmp4", "/tmp2"]).into();
|
||||||
db.save_workspace(workspace_3.clone()).await;
|
// db.save_workspace(workspace_3.clone()).await;
|
||||||
assert_eq!(db.workspace_for_roots(&["/tmp2", "tmp"]), None);
|
// assert_eq!(db.workspace_for_roots(&["/tmp2", "tmp"]), None);
|
||||||
assert_eq!(
|
// assert_eq!(
|
||||||
db.workspace_for_roots(&["/tmp2", "/tmp3", "/tmp4"])
|
// db.workspace_for_roots(&["/tmp2", "/tmp3", "/tmp4"])
|
||||||
.unwrap(),
|
// .unwrap(),
|
||||||
workspace_3
|
// workspace_3
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
use crate::persistence::model::SerializedWorkspace;
|
// use crate::persistence::model::SerializedWorkspace;
|
||||||
use crate::persistence::model::{SerializedItem, SerializedPane, SerializedPaneGroup};
|
// use crate::persistence::model::{SerializedItem, SerializedPane, SerializedPaneGroup};
|
||||||
|
|
||||||
fn default_workspace<P: AsRef<Path>>(
|
// fn default_workspace<P: AsRef<Path>>(
|
||||||
workspace_id: &[P],
|
// workspace_id: &[P],
|
||||||
center_group: &SerializedPaneGroup,
|
// center_group: &SerializedPaneGroup,
|
||||||
) -> SerializedWorkspace {
|
// ) -> SerializedWorkspace {
|
||||||
SerializedWorkspace {
|
// SerializedWorkspace {
|
||||||
id: 4,
|
// id: 4,
|
||||||
location: workspace_id.into(),
|
// location: workspace_id.into(),
|
||||||
center_group: center_group.clone(),
|
// center_group: center_group.clone(),
|
||||||
bounds: Default::default(),
|
// bounds: Default::default(),
|
||||||
display: Default::default(),
|
// display: Default::default(),
|
||||||
docks: Default::default(),
|
// docks: Default::default(),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_simple_split() {
|
// async fn test_simple_split() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("simple_split").await);
|
// let db = WorkspaceDb(open_test_db("simple_split").await);
|
||||||
|
|
||||||
// -----------------
|
// // -----------------
|
||||||
// | 1,2 | 5,6 |
|
// // | 1,2 | 5,6 |
|
||||||
// | - - - | |
|
// // | - - - | |
|
||||||
// | 3,4 | |
|
// // | 3,4 | |
|
||||||
// -----------------
|
// // -----------------
|
||||||
let center_pane = group(
|
// let center_pane = group(
|
||||||
gpui::Axis::Horizontal,
|
// gpui::Axis::Horizontal,
|
||||||
vec![
|
// vec![
|
||||||
group(
|
// group(
|
||||||
gpui::Axis::Vertical,
|
// gpui::Axis::Vertical,
|
||||||
vec![
|
// vec![
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 1, false),
|
// SerializedItem::new("Terminal", 1, false),
|
||||||
SerializedItem::new("Terminal", 2, true),
|
// SerializedItem::new("Terminal", 2, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 4, false),
|
// SerializedItem::new("Terminal", 4, false),
|
||||||
SerializedItem::new("Terminal", 3, true),
|
// SerializedItem::new("Terminal", 3, true),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 5, true),
|
// SerializedItem::new("Terminal", 5, true),
|
||||||
SerializedItem::new("Terminal", 6, false),
|
// SerializedItem::new("Terminal", 6, false),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
|
|
||||||
let workspace = default_workspace(&["/tmp"], ¢er_pane);
|
// let workspace = default_workspace(&["/tmp"], ¢er_pane);
|
||||||
|
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
|
|
||||||
let new_workspace = db.workspace_for_roots(&["/tmp"]).unwrap();
|
// let new_workspace = db.workspace_for_roots(&["/tmp"]).unwrap();
|
||||||
|
|
||||||
assert_eq!(workspace.center_group, new_workspace.center_group);
|
// assert_eq!(workspace.center_group, new_workspace.center_group);
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[gpui::test]
|
// #[gpui::test]
|
||||||
async fn test_cleanup_panes() {
|
// async fn test_cleanup_panes() {
|
||||||
env_logger::try_init().ok();
|
// env_logger::try_init().ok();
|
||||||
|
|
||||||
let db = WorkspaceDb(open_test_db("test_cleanup_panes").await);
|
// let db = WorkspaceDb(open_test_db("test_cleanup_panes").await);
|
||||||
|
|
||||||
let center_pane = group(
|
// let center_pane = group(
|
||||||
gpui::Axis::Horizontal,
|
// gpui::Axis::Horizontal,
|
||||||
vec![
|
// vec![
|
||||||
group(
|
// group(
|
||||||
gpui::Axis::Vertical,
|
// gpui::Axis::Vertical,
|
||||||
vec![
|
// vec![
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 1, false),
|
// SerializedItem::new("Terminal", 1, false),
|
||||||
SerializedItem::new("Terminal", 2, true),
|
// SerializedItem::new("Terminal", 2, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 4, false),
|
// SerializedItem::new("Terminal", 4, false),
|
||||||
SerializedItem::new("Terminal", 3, true),
|
// SerializedItem::new("Terminal", 3, true),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 5, false),
|
// SerializedItem::new("Terminal", 5, false),
|
||||||
SerializedItem::new("Terminal", 6, true),
|
// SerializedItem::new("Terminal", 6, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
|
|
||||||
let id = &["/tmp"];
|
// let id = &["/tmp"];
|
||||||
|
|
||||||
let mut workspace = default_workspace(id, ¢er_pane);
|
// let mut workspace = default_workspace(id, ¢er_pane);
|
||||||
|
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
|
|
||||||
workspace.center_group = group(
|
// workspace.center_group = group(
|
||||||
gpui::Axis::Vertical,
|
// gpui::Axis::Vertical,
|
||||||
vec![
|
// vec![
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 1, false),
|
// SerializedItem::new("Terminal", 1, false),
|
||||||
SerializedItem::new("Terminal", 2, true),
|
// SerializedItem::new("Terminal", 2, true),
|
||||||
],
|
// ],
|
||||||
false,
|
// false,
|
||||||
)),
|
// )),
|
||||||
SerializedPaneGroup::Pane(SerializedPane::new(
|
// SerializedPaneGroup::Pane(SerializedPane::new(
|
||||||
vec![
|
// vec![
|
||||||
SerializedItem::new("Terminal", 4, true),
|
// SerializedItem::new("Terminal", 4, true),
|
||||||
SerializedItem::new("Terminal", 3, false),
|
// SerializedItem::new("Terminal", 3, false),
|
||||||
],
|
// ],
|
||||||
true,
|
// true,
|
||||||
)),
|
// )),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
|
|
||||||
db.save_workspace(workspace.clone()).await;
|
// db.save_workspace(workspace.clone()).await;
|
||||||
|
|
||||||
let new_workspace = db.workspace_for_roots(id).unwrap();
|
// let new_workspace = db.workspace_for_roots(id).unwrap();
|
||||||
|
|
||||||
assert_eq!(workspace.center_group, new_workspace.center_group);
|
// assert_eq!(workspace.center_group, new_workspace.center_group);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
|
use crate::{
|
||||||
|
item::ItemHandle, Axis, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
|
||||||
|
};
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
use db::sqlez::{
|
use db2::sqlez::{
|
||||||
bindable::{Bind, Column, StaticColumnCount},
|
bindable::{Bind, Column, StaticColumnCount},
|
||||||
statement::Statement,
|
statement::Statement,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui2::{AsyncAppContext, Handle, Task, View, WeakView, WindowBounds};
|
||||||
platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle, WeakViewHandle,
|
use project2::Project;
|
||||||
};
|
|
||||||
use project::Project;
|
|
||||||
use std::{
|
use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
@ -151,15 +151,11 @@ impl SerializedPaneGroup {
|
||||||
#[async_recursion(?Send)]
|
#[async_recursion(?Send)]
|
||||||
pub(crate) async fn deserialize(
|
pub(crate) async fn deserialize(
|
||||||
self,
|
self,
|
||||||
project: &ModelHandle<Project>,
|
project: &Handle<Project>,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
workspace: &WeakViewHandle<Workspace>,
|
workspace: &WeakView<Workspace>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Option<(
|
) -> Option<(Member, Option<View<Pane>>, Vec<Option<Box<dyn ItemHandle>>>)> {
|
||||||
Member,
|
|
||||||
Option<ViewHandle<Pane>>,
|
|
||||||
Vec<Option<Box<dyn ItemHandle>>>,
|
|
||||||
)> {
|
|
||||||
match self {
|
match self {
|
||||||
SerializedPaneGroup::Group {
|
SerializedPaneGroup::Group {
|
||||||
axis,
|
axis,
|
||||||
|
@ -208,10 +204,10 @@ impl SerializedPaneGroup {
|
||||||
.read_with(cx, |pane, _| pane.items_len() != 0)
|
.read_with(cx, |pane, _| pane.items_len() != 0)
|
||||||
.log_err()?
|
.log_err()?
|
||||||
{
|
{
|
||||||
let pane = pane.upgrade(cx)?;
|
let pane = pane.upgrade()?;
|
||||||
Some((Member::Pane(pane.clone()), active.then(|| pane), new_items))
|
Some((Member::Pane(pane.clone()), active.then(|| pane), new_items))
|
||||||
} else {
|
} else {
|
||||||
let pane = pane.upgrade(cx)?;
|
let pane = pane.upgrade()?;
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| workspace.force_remove_pane(&pane, cx))
|
.update(cx, |workspace, cx| workspace.force_remove_pane(&pane, cx))
|
||||||
.log_err()?;
|
.log_err()?;
|
||||||
|
@ -235,10 +231,10 @@ impl SerializedPane {
|
||||||
|
|
||||||
pub async fn deserialize_to(
|
pub async fn deserialize_to(
|
||||||
&self,
|
&self,
|
||||||
project: &ModelHandle<Project>,
|
project: &Handle<Project>,
|
||||||
pane: &WeakViewHandle<Pane>,
|
pane: &WeakView<Pane>,
|
||||||
workspace_id: WorkspaceId,
|
workspace_id: WorkspaceId,
|
||||||
workspace: &WeakViewHandle<Workspace>,
|
workspace: &WeakView<Workspace>,
|
||||||
cx: &mut AsyncAppContext,
|
cx: &mut AsyncAppContext,
|
||||||
) -> Result<Vec<Option<Box<dyn ItemHandle>>>> {
|
) -> Result<Vec<Option<Box<dyn ItemHandle>>>> {
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
use crate::ItemHandle;
|
use crate::ItemHandle;
|
||||||
use gpui::{
|
use gpui2::{AppContext, EventEmitter, View, ViewContext, WindowContext};
|
||||||
elements::*, AnyElement, AnyViewHandle, AppContext, Entity, View, ViewContext, ViewHandle,
|
|
||||||
WindowContext,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub trait ToolbarItemView: View {
|
pub trait ToolbarItemView: EventEmitter + Sized {
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn crate::ItemHandle>,
|
active_pane_item: Option<&dyn crate::ItemHandle>,
|
||||||
|
@ -32,7 +29,7 @@ pub trait ToolbarItemView: View {
|
||||||
|
|
||||||
trait ToolbarItemViewHandle {
|
trait ToolbarItemViewHandle {
|
||||||
fn id(&self) -> usize;
|
fn id(&self) -> usize;
|
||||||
fn as_any(&self) -> &AnyViewHandle;
|
// fn as_any(&self) -> &AnyViewHandle; todo!()
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&self,
|
&self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
|
@ -57,84 +54,81 @@ pub struct Toolbar {
|
||||||
items: Vec<(Box<dyn ToolbarItemViewHandle>, ToolbarItemLocation)>,
|
items: Vec<(Box<dyn ToolbarItemViewHandle>, ToolbarItemLocation)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Toolbar {
|
// todo!()
|
||||||
type Event = ();
|
// impl View for Toolbar {
|
||||||
}
|
// fn ui_name() -> &'static str {
|
||||||
|
// "Toolbar"
|
||||||
|
// }
|
||||||
|
|
||||||
impl View for Toolbar {
|
// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
||||||
fn ui_name() -> &'static str {
|
// let theme = &theme::current(cx).workspace.toolbar;
|
||||||
"Toolbar"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
|
// let mut primary_left_items = Vec::new();
|
||||||
let theme = &theme::current(cx).workspace.toolbar;
|
// let mut primary_right_items = Vec::new();
|
||||||
|
// let mut secondary_item = None;
|
||||||
|
// let spacing = theme.item_spacing;
|
||||||
|
// let mut primary_items_row_count = 1;
|
||||||
|
|
||||||
let mut primary_left_items = Vec::new();
|
// for (item, position) in &self.items {
|
||||||
let mut primary_right_items = Vec::new();
|
// match *position {
|
||||||
let mut secondary_item = None;
|
// ToolbarItemLocation::Hidden => {}
|
||||||
let spacing = theme.item_spacing;
|
|
||||||
let mut primary_items_row_count = 1;
|
|
||||||
|
|
||||||
for (item, position) in &self.items {
|
// ToolbarItemLocation::PrimaryLeft { flex } => {
|
||||||
match *position {
|
// primary_items_row_count = primary_items_row_count.max(item.row_count(cx));
|
||||||
ToolbarItemLocation::Hidden => {}
|
// let left_item = ChildView::new(item.as_any(), cx).aligned();
|
||||||
|
// if let Some((flex, expanded)) = flex {
|
||||||
|
// primary_left_items.push(left_item.flex(flex, expanded).into_any());
|
||||||
|
// } else {
|
||||||
|
// primary_left_items.push(left_item.into_any());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
ToolbarItemLocation::PrimaryLeft { flex } => {
|
// ToolbarItemLocation::PrimaryRight { flex } => {
|
||||||
primary_items_row_count = primary_items_row_count.max(item.row_count(cx));
|
// primary_items_row_count = primary_items_row_count.max(item.row_count(cx));
|
||||||
let left_item = ChildView::new(item.as_any(), cx).aligned();
|
// let right_item = ChildView::new(item.as_any(), cx).aligned().flex_float();
|
||||||
if let Some((flex, expanded)) = flex {
|
// if let Some((flex, expanded)) = flex {
|
||||||
primary_left_items.push(left_item.flex(flex, expanded).into_any());
|
// primary_right_items.push(right_item.flex(flex, expanded).into_any());
|
||||||
} else {
|
// } else {
|
||||||
primary_left_items.push(left_item.into_any());
|
// primary_right_items.push(right_item.into_any());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
ToolbarItemLocation::PrimaryRight { flex } => {
|
// ToolbarItemLocation::Secondary => {
|
||||||
primary_items_row_count = primary_items_row_count.max(item.row_count(cx));
|
// secondary_item = Some(
|
||||||
let right_item = ChildView::new(item.as_any(), cx).aligned().flex_float();
|
// ChildView::new(item.as_any(), cx)
|
||||||
if let Some((flex, expanded)) = flex {
|
// .constrained()
|
||||||
primary_right_items.push(right_item.flex(flex, expanded).into_any());
|
// .with_height(theme.height * item.row_count(cx) as f32)
|
||||||
} else {
|
// .into_any(),
|
||||||
primary_right_items.push(right_item.into_any());
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
ToolbarItemLocation::Secondary => {
|
// let container_style = theme.container;
|
||||||
secondary_item = Some(
|
// let height = theme.height * primary_items_row_count as f32;
|
||||||
ChildView::new(item.as_any(), cx)
|
|
||||||
.constrained()
|
|
||||||
.with_height(theme.height * item.row_count(cx) as f32)
|
|
||||||
.into_any(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let container_style = theme.container;
|
// let mut primary_items = Flex::row().with_spacing(spacing);
|
||||||
let height = theme.height * primary_items_row_count as f32;
|
// primary_items.extend(primary_left_items);
|
||||||
|
// primary_items.extend(primary_right_items);
|
||||||
|
|
||||||
let mut primary_items = Flex::row().with_spacing(spacing);
|
// let mut toolbar = Flex::column();
|
||||||
primary_items.extend(primary_left_items);
|
// if !primary_items.is_empty() {
|
||||||
primary_items.extend(primary_right_items);
|
// toolbar.add_child(primary_items.constrained().with_height(height));
|
||||||
|
// }
|
||||||
|
// if let Some(secondary_item) = secondary_item {
|
||||||
|
// toolbar.add_child(secondary_item);
|
||||||
|
// }
|
||||||
|
|
||||||
let mut toolbar = Flex::column();
|
// if toolbar.is_empty() {
|
||||||
if !primary_items.is_empty() {
|
// toolbar.into_any_named("toolbar")
|
||||||
toolbar.add_child(primary_items.constrained().with_height(height));
|
// } else {
|
||||||
}
|
// toolbar
|
||||||
if let Some(secondary_item) = secondary_item {
|
// .contained()
|
||||||
toolbar.add_child(secondary_item);
|
// .with_style(container_style)
|
||||||
}
|
// .into_any_named("toolbar")
|
||||||
|
// }
|
||||||
if toolbar.is_empty() {
|
// }
|
||||||
toolbar.into_any_named("toolbar")
|
// }
|
||||||
} else {
|
|
||||||
toolbar
|
|
||||||
.contained()
|
|
||||||
.with_style(container_style)
|
|
||||||
.into_any_named("toolbar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// <<<<<<< HEAD
|
// <<<<<<< HEAD
|
||||||
// =======
|
// =======
|
||||||
|
@ -206,7 +200,7 @@ impl Toolbar {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_item<T>(&mut self, item: ViewHandle<T>, cx: &mut ViewContext<Self>)
|
pub fn add_item<T>(&mut self, item: View<T>, cx: &mut ViewContext<Self>)
|
||||||
where
|
where
|
||||||
T: 'static + ToolbarItemView,
|
T: 'static + ToolbarItemView,
|
||||||
{
|
{
|
||||||
|
@ -252,7 +246,7 @@ impl Toolbar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_of_type<T: ToolbarItemView>(&self) -> Option<ViewHandle<T>> {
|
pub fn item_of_type<T: ToolbarItemView>(&self) -> Option<View<T>> {
|
||||||
self.items
|
self.items
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(item, _)| item.as_any().clone().downcast())
|
.find_map(|(item, _)| item.as_any().clone().downcast())
|
||||||
|
@ -263,14 +257,15 @@ impl Toolbar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
impl<T: ToolbarItemView> ToolbarItemViewHandle for View<T> {
|
||||||
fn id(&self) -> usize {
|
fn id(&self) -> usize {
|
||||||
self.id()
|
self.id()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&self) -> &AnyViewHandle {
|
// todo!()
|
||||||
self
|
// fn as_any(&self) -> &AnyViewHandle {
|
||||||
}
|
// self
|
||||||
|
// }
|
||||||
|
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&self,
|
&self,
|
||||||
|
@ -294,8 +289,9 @@ impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&dyn ToolbarItemViewHandle> for AnyViewHandle {
|
// todo!()
|
||||||
fn from(val: &dyn ToolbarItemViewHandle) -> Self {
|
// impl From<&dyn ToolbarItemViewHandle> for AnyViewHandle {
|
||||||
val.as_any().clone()
|
// fn from(val: &dyn ToolbarItemViewHandle) -> Self {
|
||||||
}
|
// val.as_any().clone()
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
|
@ -3,12 +3,12 @@ pub mod item;
|
||||||
// pub mod notifications;
|
// pub mod notifications;
|
||||||
pub mod pane;
|
pub mod pane;
|
||||||
pub mod pane_group;
|
pub mod pane_group;
|
||||||
// mod persistence;
|
mod persistence;
|
||||||
pub mod searchable;
|
pub mod searchable;
|
||||||
// pub mod shared_screen;
|
// pub mod shared_screen;
|
||||||
// mod status_bar;
|
// mod status_bar;
|
||||||
mod toolbar;
|
mod toolbar;
|
||||||
// mod workspace_settings;
|
mod workspace_settings;
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
// use call2::ActiveCall;
|
// use call2::ActiveCall;
|
||||||
|
@ -36,13 +36,14 @@ use anyhow::{anyhow, Result};
|
||||||
// },
|
// },
|
||||||
// AnyModelHandle, AnyViewHandle, AnyWeakViewHandle, AnyWindowHandle, AppContext, AsyncAppContext,
|
// AnyModelHandle, AnyViewHandle, AnyWeakViewHandle, AnyWindowHandle, AppContext, AsyncAppContext,
|
||||||
// Entity, ModelContext, ModelHandle, SizeConstraint, Subscription, Task, View, ViewContext,
|
// Entity, ModelContext, ModelHandle, SizeConstraint, Subscription, Task, View, ViewContext,
|
||||||
// ViewHandle, WeakViewHandle, WindowContext, WindowHandle,
|
// View, WeakViewHandle, WindowContext, WindowHandle,
|
||||||
// };
|
// };
|
||||||
// use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
|
// use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
|
||||||
// use itertools::Itertools;
|
// use itertools::Itertools;
|
||||||
// use language2::{LanguageRegistry, Rope};
|
// use language2::{LanguageRegistry, Rope};
|
||||||
// use node_runtime::NodeRuntime;// //
|
// use node_runtime::NodeRuntime;// //
|
||||||
|
|
||||||
|
use futures::channel::oneshot;
|
||||||
// use crate::{
|
// use crate::{
|
||||||
// notifications::{simple_message_notification::MessageNotification, NotificationTracker},
|
// notifications::{simple_message_notification::MessageNotification, NotificationTracker},
|
||||||
// persistence::model::{
|
// persistence::model::{
|
||||||
|
@ -91,7 +92,7 @@ pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
||||||
// fn has_focus(&self, cx: &WindowContext) -> bool;
|
// fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl<T: Modal> ModalHandle for ViewHandle<T> {
|
// impl<T: Modal> ModalHandle for View<T> {
|
||||||
// fn as_any(&self) -> &AnyViewHandle {
|
// fn as_any(&self) -> &AnyViewHandle {
|
||||||
// self
|
// self
|
||||||
// }
|
// }
|
||||||
|
@ -376,61 +377,61 @@ pub fn register_project_item<I: ProjectItem>(cx: &mut AppContext) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// type FollowableItemBuilder = fn(
|
type FollowableItemBuilder = fn(
|
||||||
// ViewHandle<Pane>,
|
View<Pane>,
|
||||||
// ViewHandle<Workspace>,
|
View<Workspace>,
|
||||||
// ViewId,
|
ViewId,
|
||||||
// &mut Option<proto::view::Variant>,
|
&mut Option<proto::view::Variant>,
|
||||||
// &mut AppContext,
|
&mut AppContext,
|
||||||
// ) -> Option<Task<Result<Box<dyn FollowableItemHandle>>>>;
|
) -> Option<Task<Result<Box<dyn FollowableItemHandle>>>>;
|
||||||
// type FollowableItemBuilders = HashMap<
|
type FollowableItemBuilders = HashMap<
|
||||||
// TypeId,
|
TypeId,
|
||||||
// (
|
(
|
||||||
// FollowableItemBuilder,
|
FollowableItemBuilder,
|
||||||
// fn(&AnyViewHandle) -> Box<dyn FollowableItemHandle>,
|
fn(&AnyView) -> Box<dyn FollowableItemHandle>,
|
||||||
// ),
|
),
|
||||||
// >;
|
>;
|
||||||
// pub fn register_followable_item<I: FollowableItem>(cx: &mut AppContext) {
|
pub fn register_followable_item<I: FollowableItem>(cx: &mut AppContext) {
|
||||||
// cx.update_default_global(|builders: &mut FollowableItemBuilders, _| {
|
cx.update_default_global(|builders: &mut FollowableItemBuilders, _| {
|
||||||
// builders.insert(
|
builders.insert(
|
||||||
// TypeId::of::<I>(),
|
TypeId::of::<I>(),
|
||||||
// (
|
(
|
||||||
// |pane, workspace, id, state, cx| {
|
|pane, workspace, id, state, cx| {
|
||||||
// I::from_state_proto(pane, workspace, id, state, cx).map(|task| {
|
I::from_state_proto(pane, workspace, id, state, cx).map(|task| {
|
||||||
// cx.foreground()
|
cx.foreground()
|
||||||
// .spawn(async move { Ok(Box::new(task.await?) as Box<_>) })
|
.spawn(async move { Ok(Box::new(task.await?) as Box<_>) })
|
||||||
// })
|
})
|
||||||
// },
|
},
|
||||||
// |this| Box::new(this.clone().downcast::<I>().unwrap()),
|
|this| Box::new(this.clone().downcast::<I>().unwrap()),
|
||||||
// ),
|
),
|
||||||
// );
|
);
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// type ItemDeserializers = HashMap<
|
type ItemDeserializers = HashMap<
|
||||||
// Arc<str>,
|
Arc<str>,
|
||||||
// fn(
|
fn(
|
||||||
// ModelHandle<Project>,
|
Handle<Project>,
|
||||||
// WeakViewHandle<Workspace>,
|
WeakView<Workspace>,
|
||||||
// WorkspaceId,
|
WorkspaceId,
|
||||||
// ItemId,
|
ItemId,
|
||||||
// &mut ViewContext<Pane>,
|
&mut ViewContext<Pane>,
|
||||||
// ) -> Task<Result<Box<dyn ItemHandle>>>,
|
) -> Task<Result<Box<dyn ItemHandle>>>,
|
||||||
// >;
|
>;
|
||||||
// pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) {
|
pub fn register_deserializable_item<I: Item>(cx: &mut AppContext) {
|
||||||
// cx.update_default_global(|deserializers: &mut ItemDeserializers, _cx| {
|
cx.update_default_global(|deserializers: &mut ItemDeserializers, _cx| {
|
||||||
// if let Some(serialized_item_kind) = I::serialized_item_kind() {
|
if let Some(serialized_item_kind) = I::serialized_item_kind() {
|
||||||
// deserializers.insert(
|
deserializers.insert(
|
||||||
// Arc::from(serialized_item_kind),
|
Arc::from(serialized_item_kind),
|
||||||
// |project, workspace, workspace_id, item_id, cx| {
|
|project, workspace, workspace_id, item_id, cx| {
|
||||||
// let task = I::deserialize(project, workspace, workspace_id, item_id, cx);
|
let task = I::deserialize(project, workspace, workspace_id, item_id, cx);
|
||||||
// cx.foreground()
|
cx.foreground()
|
||||||
// .spawn(async { Ok(Box::new(task.await?) as Box<_>) })
|
.spawn(async { Ok(Box::new(task.await?) as Box<_>) })
|
||||||
// },
|
},
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub languages: Arc<LanguageRegistry>,
|
pub languages: Arc<LanguageRegistry>,
|
||||||
|
@ -493,54 +494,54 @@ struct Follower {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// struct DelayedDebouncedEditAction {
|
struct DelayedDebouncedEditAction {
|
||||||
// task: Option<Task<()>>,
|
task: Option<Task<()>>,
|
||||||
// cancel_channel: Option<oneshot::Sender<()>>,
|
cancel_channel: Option<oneshot::Sender<()>>,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// impl DelayedDebouncedEditAction {
|
impl DelayedDebouncedEditAction {
|
||||||
// fn new() -> DelayedDebouncedEditAction {
|
fn new() -> DelayedDebouncedEditAction {
|
||||||
// DelayedDebouncedEditAction {
|
DelayedDebouncedEditAction {
|
||||||
// task: None,
|
task: None,
|
||||||
// cancel_channel: None,
|
cancel_channel: None,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Workspace>, func: F)
|
fn fire_new<F>(&mut self, delay: Duration, cx: &mut ViewContext<Workspace>, func: F)
|
||||||
// where
|
where
|
||||||
// F: 'static + FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> Task<Result<()>>,
|
F: 'static + FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> Task<Result<()>>,
|
||||||
// {
|
{
|
||||||
// if let Some(channel) = self.cancel_channel.take() {
|
if let Some(channel) = self.cancel_channel.take() {
|
||||||
// _ = channel.send(());
|
_ = channel.send(());
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let (sender, mut receiver) = oneshot::channel::<()>();
|
let (sender, mut receiver) = oneshot::channel::<()>();
|
||||||
// self.cancel_channel = Some(sender);
|
self.cancel_channel = Some(sender);
|
||||||
|
|
||||||
// let previous_task = self.task.take();
|
let previous_task = self.task.take();
|
||||||
// self.task = Some(cx.spawn(|workspace, mut cx| async move {
|
self.task = Some(cx.spawn(|workspace, mut cx| async move {
|
||||||
// let mut timer = cx.background().timer(delay).fuse();
|
let mut timer = cx.background().timer(delay).fuse();
|
||||||
// if let Some(previous_task) = previous_task {
|
if let Some(previous_task) = previous_task {
|
||||||
// previous_task.await;
|
previous_task.await;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// futures::select_biased! {
|
futures::select_biased! {
|
||||||
// _ = receiver => return,
|
_ = receiver => return,
|
||||||
// _ = timer => {}
|
_ = timer => {}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if let Some(result) = workspace
|
if let Some(result) = workspace
|
||||||
// .update(&mut cx, |workspace, cx| (func)(workspace, cx))
|
.update(&mut cx, |workspace, cx| (func)(workspace, cx))
|
||||||
// .log_err()
|
.log_err()
|
||||||
// {
|
{
|
||||||
// result.await.log_err();
|
result.await.log_err();
|
||||||
// }
|
}
|
||||||
// }));
|
}));
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// pub enum Event {
|
// pub enum Event {
|
||||||
// PaneAdded(ViewHandle<Pane>),
|
// PaneAdded(View<Pane>),
|
||||||
// ContactRequestedJoin(u64),
|
// ContactRequestedJoin(u64),
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -550,19 +551,19 @@ pub struct Workspace {
|
||||||
// zoomed: Option<AnyWeakViewHandle>,
|
// zoomed: Option<AnyWeakViewHandle>,
|
||||||
// zoomed_position: Option<DockPosition>,
|
// zoomed_position: Option<DockPosition>,
|
||||||
// center: PaneGroup,
|
// center: PaneGroup,
|
||||||
// left_dock: ViewHandle<Dock>,
|
// left_dock: View<Dock>,
|
||||||
// bottom_dock: ViewHandle<Dock>,
|
// bottom_dock: View<Dock>,
|
||||||
// right_dock: ViewHandle<Dock>,
|
// right_dock: View<Dock>,
|
||||||
panes: Vec<View<Pane>>,
|
panes: Vec<View<Pane>>,
|
||||||
// panes_by_item: HashMap<usize, WeakViewHandle<Pane>>,
|
// panes_by_item: HashMap<usize, WeakViewHandle<Pane>>,
|
||||||
// active_pane: ViewHandle<Pane>,
|
// active_pane: View<Pane>,
|
||||||
last_active_center_pane: Option<WeakView<Pane>>,
|
last_active_center_pane: Option<WeakView<Pane>>,
|
||||||
// last_active_view_id: Option<proto::ViewId>,
|
// last_active_view_id: Option<proto::ViewId>,
|
||||||
// status_bar: ViewHandle<StatusBar>,
|
// status_bar: View<StatusBar>,
|
||||||
// titlebar_item: Option<AnyViewHandle>,
|
// titlebar_item: Option<AnyViewHandle>,
|
||||||
// notifications: Vec<(TypeId, usize, Box<dyn NotificationHandle>)>,
|
// notifications: Vec<(TypeId, usize, Box<dyn NotificationHandle>)>,
|
||||||
project: Handle<Project>,
|
project: Handle<Project>,
|
||||||
// follower_states: HashMap<ViewHandle<Pane>, FollowerState>,
|
// follower_states: HashMap<View<Pane>, FollowerState>,
|
||||||
// last_leaders_by_pane: HashMap<WeakViewHandle<Pane>, PeerId>,
|
// last_leaders_by_pane: HashMap<WeakViewHandle<Pane>, PeerId>,
|
||||||
// window_edited: bool,
|
// window_edited: bool,
|
||||||
// active_call: Option<(ModelHandle<ActiveCall>, Vec<Subscription>)>,
|
// active_call: Option<(ModelHandle<ActiveCall>, Vec<Subscription>)>,
|
||||||
|
@ -930,19 +931,19 @@ impl Workspace {
|
||||||
// self.weak_self.clone()
|
// self.weak_self.clone()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn left_dock(&self) -> &ViewHandle<Dock> {
|
// pub fn left_dock(&self) -> &View<Dock> {
|
||||||
// &self.left_dock
|
// &self.left_dock
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn bottom_dock(&self) -> &ViewHandle<Dock> {
|
// pub fn bottom_dock(&self) -> &View<Dock> {
|
||||||
// &self.bottom_dock
|
// &self.bottom_dock
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn right_dock(&self) -> &ViewHandle<Dock> {
|
// pub fn right_dock(&self) -> &View<Dock> {
|
||||||
// &self.right_dock
|
// &self.right_dock
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn add_panel<T: Panel>(&mut self, panel: ViewHandle<T>, cx: &mut ViewContext<Self>)
|
// pub fn add_panel<T: Panel>(&mut self, panel: View<T>, cx: &mut ViewContext<Self>)
|
||||||
// where
|
// where
|
||||||
// T::Event: std::fmt::Debug,
|
// T::Event: std::fmt::Debug,
|
||||||
// {
|
// {
|
||||||
|
@ -951,12 +952,12 @@ impl Workspace {
|
||||||
|
|
||||||
// pub fn add_panel_with_extra_event_handler<T: Panel, F>(
|
// pub fn add_panel_with_extra_event_handler<T: Panel, F>(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// panel: ViewHandle<T>,
|
// panel: View<T>,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// handler: F,
|
// handler: F,
|
||||||
// ) where
|
// ) where
|
||||||
// T::Event: std::fmt::Debug,
|
// T::Event: std::fmt::Debug,
|
||||||
// F: Fn(&mut Self, &ViewHandle<T>, &T::Event, &mut ViewContext<Self>) + 'static,
|
// F: Fn(&mut Self, &View<T>, &T::Event, &mut ViewContext<Self>) + 'static,
|
||||||
// {
|
// {
|
||||||
// let dock = match panel.position(cx) {
|
// let dock = match panel.position(cx) {
|
||||||
// DockPosition::Left => &self.left_dock,
|
// DockPosition::Left => &self.left_dock,
|
||||||
|
@ -1033,7 +1034,7 @@ impl Workspace {
|
||||||
// dock.update(cx, |dock, cx| dock.add_panel(panel, cx));
|
// dock.update(cx, |dock, cx| dock.add_panel(panel, cx));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn status_bar(&self) -> &ViewHandle<StatusBar> {
|
// pub fn status_bar(&self) -> &View<StatusBar> {
|
||||||
// &self.status_bar
|
// &self.status_bar
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -1617,10 +1618,10 @@ impl Workspace {
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// add_view: F,
|
// add_view: F,
|
||||||
// ) -> Option<ViewHandle<V>>
|
// ) -> Option<View<V>>
|
||||||
// where
|
// where
|
||||||
// V: 'static + Modal,
|
// V: 'static + Modal,
|
||||||
// F: FnOnce(&mut Self, &mut ViewContext<Self>) -> ViewHandle<V>,
|
// F: FnOnce(&mut Self, &mut ViewContext<Self>) -> View<V>,
|
||||||
// {
|
// {
|
||||||
// cx.notify();
|
// cx.notify();
|
||||||
// // Whatever modal was visible is getting clobbered. If its the same type as V, then return
|
// // Whatever modal was visible is getting clobbered. If its the same type as V, then return
|
||||||
|
@ -1649,7 +1650,7 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn modal<V: 'static + View>(&self) -> Option<ViewHandle<V>> {
|
// pub fn modal<V: 'static + View>(&self) -> Option<View<V>> {
|
||||||
// self.modal
|
// self.modal
|
||||||
// .as_ref()
|
// .as_ref()
|
||||||
// .and_then(|modal| modal.view.as_any().clone().downcast::<V>())
|
// .and_then(|modal| modal.view.as_any().clone().downcast::<V>())
|
||||||
|
@ -1676,14 +1677,14 @@ impl Workspace {
|
||||||
// self.panes.iter().flat_map(|pane| pane.read(cx).items())
|
// self.panes.iter().flat_map(|pane| pane.read(cx).items())
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn item_of_type<T: Item>(&self, cx: &AppContext) -> Option<ViewHandle<T>> {
|
// pub fn item_of_type<T: Item>(&self, cx: &AppContext) -> Option<View<T>> {
|
||||||
// self.items_of_type(cx).max_by_key(|item| item.id())
|
// self.items_of_type(cx).max_by_key(|item| item.id())
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn items_of_type<'a, T: Item>(
|
// pub fn items_of_type<'a, T: Item>(
|
||||||
// &'a self,
|
// &'a self,
|
||||||
// cx: &'a AppContext,
|
// cx: &'a AppContext,
|
||||||
// ) -> impl 'a + Iterator<Item = ViewHandle<T>> {
|
// ) -> impl 'a + Iterator<Item = View<T>> {
|
||||||
// self.panes
|
// self.panes
|
||||||
// .iter()
|
// .iter()
|
||||||
// .flat_map(|pane| pane.read(cx).items_of_type())
|
// .flat_map(|pane| pane.read(cx).items_of_type())
|
||||||
|
@ -1834,7 +1835,7 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// /// Transfer focus to the panel of the given type.
|
// /// Transfer focus to the panel of the given type.
|
||||||
// pub fn focus_panel<T: Panel>(&mut self, cx: &mut ViewContext<Self>) -> Option<ViewHandle<T>> {
|
// pub fn focus_panel<T: Panel>(&mut self, cx: &mut ViewContext<Self>) -> Option<View<T>> {
|
||||||
// self.focus_or_unfocus_panel::<T>(cx, |_, _| true)?
|
// self.focus_or_unfocus_panel::<T>(cx, |_, _| true)?
|
||||||
// .as_any()
|
// .as_any()
|
||||||
// .clone()
|
// .clone()
|
||||||
|
@ -1888,7 +1889,7 @@ impl Workspace {
|
||||||
// None
|
// None
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn panel<T: Panel>(&self, cx: &WindowContext) -> Option<ViewHandle<T>> {
|
// pub fn panel<T: Panel>(&self, cx: &WindowContext) -> Option<View<T>> {
|
||||||
// for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
|
// for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
|
||||||
// let dock = dock.read(cx);
|
// let dock = dock.read(cx);
|
||||||
// if let Some(panel) = dock.panel::<T>() {
|
// if let Some(panel) = dock.panel::<T>() {
|
||||||
|
@ -1956,7 +1957,7 @@ impl Workspace {
|
||||||
// cx.notify();
|
// cx.notify();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> ViewHandle<Pane> {
|
// fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> View<Pane> {
|
||||||
// let pane = cx.add_view(|cx| {
|
// let pane = cx.add_view(|cx| {
|
||||||
// Pane::new(
|
// Pane::new(
|
||||||
// self.weak_handle(),
|
// self.weak_handle(),
|
||||||
|
@ -2138,7 +2139,7 @@ impl Workspace {
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// project_item: ModelHandle<T::Item>,
|
// project_item: ModelHandle<T::Item>,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> ViewHandle<T>
|
// ) -> View<T>
|
||||||
// where
|
// where
|
||||||
// T: ProjectItem,
|
// T: ProjectItem,
|
||||||
// {
|
// {
|
||||||
|
@ -2162,7 +2163,7 @@ impl Workspace {
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// project_item: ModelHandle<T::Item>,
|
// project_item: ModelHandle<T::Item>,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> ViewHandle<T>
|
// ) -> View<T>
|
||||||
// where
|
// where
|
||||||
// T: ProjectItem,
|
// T: ProjectItem,
|
||||||
// {
|
// {
|
||||||
|
@ -2259,7 +2260,7 @@ impl Workspace {
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// direction: SplitDirection,
|
// direction: SplitDirection,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> Option<&ViewHandle<Pane>> {
|
// ) -> Option<&View<Pane>> {
|
||||||
// let Some(bounding_box) = self.center.bounding_box_for_pane(&self.active_pane) else {
|
// let Some(bounding_box) = self.center.bounding_box_for_pane(&self.active_pane) else {
|
||||||
// return None;
|
// return None;
|
||||||
// };
|
// };
|
||||||
|
@ -2280,7 +2281,7 @@ impl Workspace {
|
||||||
// self.center.pane_at_pixel_position(target)
|
// self.center.pane_at_pixel_position(target)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn handle_pane_focused(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
|
// fn handle_pane_focused(&mut self, pane: View<Pane>, cx: &mut ViewContext<Self>) {
|
||||||
// if self.active_pane != pane {
|
// if self.active_pane != pane {
|
||||||
// self.active_pane = pane.clone();
|
// self.active_pane = pane.clone();
|
||||||
// self.status_bar.update(cx, |status_bar, cx| {
|
// self.status_bar.update(cx, |status_bar, cx| {
|
||||||
|
@ -2304,7 +2305,7 @@ impl Workspace {
|
||||||
|
|
||||||
// fn handle_pane_event(
|
// fn handle_pane_event(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// pane: ViewHandle<Pane>,
|
// pane: View<Pane>,
|
||||||
// event: &pane::Event,
|
// event: &pane::Event,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) {
|
// ) {
|
||||||
|
@ -2363,10 +2364,10 @@ impl Workspace {
|
||||||
|
|
||||||
// pub fn split_pane(
|
// pub fn split_pane(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// pane_to_split: ViewHandle<Pane>,
|
// pane_to_split: View<Pane>,
|
||||||
// split_direction: SplitDirection,
|
// split_direction: SplitDirection,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> ViewHandle<Pane> {
|
// ) -> View<Pane> {
|
||||||
// let new_pane = self.add_pane(cx);
|
// let new_pane = self.add_pane(cx);
|
||||||
// self.center
|
// self.center
|
||||||
// .split(&pane_to_split, &new_pane, split_direction)
|
// .split(&pane_to_split, &new_pane, split_direction)
|
||||||
|
@ -2377,10 +2378,10 @@ impl Workspace {
|
||||||
|
|
||||||
// pub fn split_and_clone(
|
// pub fn split_and_clone(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// pane: ViewHandle<Pane>,
|
// pane: View<Pane>,
|
||||||
// direction: SplitDirection,
|
// direction: SplitDirection,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> Option<ViewHandle<Pane>> {
|
// ) -> Option<View<Pane>> {
|
||||||
// let item = pane.read(cx).active_item()?;
|
// let item = pane.read(cx).active_item()?;
|
||||||
// let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
|
// let maybe_pane_handle = if let Some(clone) = item.clone_on_split(self.database_id(), cx) {
|
||||||
// let new_pane = self.add_pane(cx);
|
// let new_pane = self.add_pane(cx);
|
||||||
|
@ -2440,8 +2441,8 @@ impl Workspace {
|
||||||
|
|
||||||
// pub fn move_item(
|
// pub fn move_item(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// source: ViewHandle<Pane>,
|
// source: View<Pane>,
|
||||||
// destination: ViewHandle<Pane>,
|
// destination: View<Pane>,
|
||||||
// item_id_to_move: usize,
|
// item_id_to_move: usize,
|
||||||
// destination_index: usize,
|
// destination_index: usize,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
|
@ -2473,7 +2474,7 @@ impl Workspace {
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
|
// fn remove_pane(&mut self, pane: View<Pane>, cx: &mut ViewContext<Self>) {
|
||||||
// if self.center.remove(&pane).unwrap() {
|
// if self.center.remove(&pane).unwrap() {
|
||||||
// self.force_remove_pane(&pane, cx);
|
// self.force_remove_pane(&pane, cx);
|
||||||
// self.unfollow(&pane, cx);
|
// self.unfollow(&pane, cx);
|
||||||
|
@ -2488,11 +2489,11 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn panes(&self) -> &[ViewHandle<Pane>] {
|
// pub fn panes(&self) -> &[View<Pane>] {
|
||||||
// &self.panes
|
// &self.panes
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn active_pane(&self) -> &ViewHandle<Pane> {
|
// pub fn active_pane(&self) -> &View<Pane> {
|
||||||
// &self.active_pane
|
// &self.active_pane
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -2651,7 +2652,7 @@ impl Workspace {
|
||||||
|
|
||||||
// pub fn unfollow(
|
// pub fn unfollow(
|
||||||
// &mut self,
|
// &mut self,
|
||||||
// pane: &ViewHandle<Pane>,
|
// pane: &View<Pane>,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> Option<PeerId> {
|
// ) -> Option<PeerId> {
|
||||||
// let state = self.follower_states.remove(pane)?;
|
// let state = self.follower_states.remove(pane)?;
|
||||||
|
@ -2959,7 +2960,7 @@ impl Workspace {
|
||||||
// async fn add_views_from_leader(
|
// async fn add_views_from_leader(
|
||||||
// this: WeakViewHandle<Self>,
|
// this: WeakViewHandle<Self>,
|
||||||
// leader_id: PeerId,
|
// leader_id: PeerId,
|
||||||
// panes: Vec<ViewHandle<Pane>>,
|
// panes: Vec<View<Pane>>,
|
||||||
// views: Vec<proto::View>,
|
// views: Vec<proto::View>,
|
||||||
// cx: &mut AsyncAppContext,
|
// cx: &mut AsyncAppContext,
|
||||||
// ) -> Result<()> {
|
// ) -> Result<()> {
|
||||||
|
@ -3060,7 +3061,7 @@ impl Workspace {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// pub fn leader_for_pane(&self, pane: &ViewHandle<Pane>) -> Option<PeerId> {
|
// pub fn leader_for_pane(&self, pane: &View<Pane>) -> Option<PeerId> {
|
||||||
// self.follower_states.get(pane).map(|state| state.leader_id)
|
// self.follower_states.get(pane).map(|state| state.leader_id)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -3133,9 +3134,9 @@ impl Workspace {
|
||||||
// fn shared_screen_for_peer(
|
// fn shared_screen_for_peer(
|
||||||
// &self,
|
// &self,
|
||||||
// peer_id: PeerId,
|
// peer_id: PeerId,
|
||||||
// pane: &ViewHandle<Pane>,
|
// pane: &View<Pane>,
|
||||||
// cx: &mut ViewContext<Self>,
|
// cx: &mut ViewContext<Self>,
|
||||||
// ) -> Option<ViewHandle<SharedScreen>> {
|
// ) -> Option<View<SharedScreen>> {
|
||||||
// let call = self.active_call()?;
|
// let call = self.active_call()?;
|
||||||
// let room = call.read(cx).room()?.read(cx);
|
// let room = call.read(cx).room()?.read(cx);
|
||||||
// let participant = room.remote_participant_for_peer_id(peer_id)?;
|
// let participant = room.remote_participant_for_peer_id(peer_id)?;
|
||||||
|
@ -3229,7 +3230,7 @@ impl Workspace {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// fn force_remove_pane(&mut self, pane: &ViewHandle<Pane>, cx: &mut ViewContext<Workspace>) {
|
// fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
|
||||||
// self.panes.retain(|p| p != pane);
|
// self.panes.retain(|p| p != pane);
|
||||||
// cx.focus(self.panes.last().unwrap());
|
// cx.focus(self.panes.last().unwrap());
|
||||||
// if self.last_active_center_pane == Some(pane.downgrade()) {
|
// if self.last_active_center_pane == Some(pane.downgrade()) {
|
||||||
|
@ -3248,7 +3249,7 @@ impl Workspace {
|
||||||
|
|
||||||
// fn serialize_workspace(&self, cx: &ViewContext<Self>) {
|
// fn serialize_workspace(&self, cx: &ViewContext<Self>) {
|
||||||
// fn serialize_pane_handle(
|
// fn serialize_pane_handle(
|
||||||
// pane_handle: &ViewHandle<Pane>,
|
// pane_handle: &View<Pane>,
|
||||||
// cx: &AppContext,
|
// cx: &AppContext,
|
||||||
// ) -> SerializedPane {
|
// ) -> SerializedPane {
|
||||||
// let (items, active) = {
|
// let (items, active) = {
|
||||||
|
@ -4075,7 +4076,7 @@ impl Workspace {
|
||||||
// fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath>;
|
// fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath>;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// impl WorkspaceHandle for ViewHandle<Workspace> {
|
// impl WorkspaceHandle for View<Workspace> {
|
||||||
// fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath> {
|
// fn file_project_paths(&self, cx: &AppContext) -> Vec<ProjectPath> {
|
||||||
// self.read(cx)
|
// self.read(cx)
|
||||||
// .worktrees(cx)
|
// .worktrees(cx)
|
||||||
|
@ -4320,13 +4321,16 @@ pub async fn activate_workspace_for_project(
|
||||||
// None
|
// None
|
||||||
// }
|
// }
|
||||||
|
|
||||||
use client2::{proto::PeerId, Client, UserStore};
|
use client2::{
|
||||||
|
proto::{self, PeerId, ViewId},
|
||||||
|
Client, UserStore,
|
||||||
|
};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use gpui2::{
|
use gpui2::{
|
||||||
AnyHandle, AppContext, AsyncAppContext, DisplayId, Handle, MainThread, Task, View, ViewContext,
|
AnyHandle, AnyView, AppContext, AsyncAppContext, DisplayId, Handle, MainThread, Task, View,
|
||||||
WeakHandle, WeakView, WindowBounds, WindowHandle, WindowOptions,
|
ViewContext, WeakHandle, WeakView, WindowBounds, WindowHandle, WindowOptions,
|
||||||
};
|
};
|
||||||
use item::{ItemHandle, ProjectItem};
|
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
|
||||||
use language2::LanguageRegistry;
|
use language2::LanguageRegistry;
|
||||||
use node_runtime::NodeRuntime;
|
use node_runtime::NodeRuntime;
|
||||||
use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
|
use project2::{Project, ProjectEntryId, ProjectPath, Worktree};
|
||||||
|
@ -4334,6 +4338,7 @@ use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::Setting;
|
use settings2::Settings;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct WorkspaceSettings {
|
pub struct WorkspaceSettings {
|
||||||
|
@ -41,7 +41,7 @@ pub enum GitGutterSetting {
|
||||||
Hide,
|
Hide,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Setting for WorkspaceSettings {
|
impl Settings for WorkspaceSettings {
|
||||||
const KEY: Option<&'static str> = None;
|
const KEY: Option<&'static str> = None;
|
||||||
|
|
||||||
type FileContent = WorkspaceSettingsContent;
|
type FileContent = WorkspaceSettingsContent;
|
||||||
|
@ -49,7 +49,7 @@ impl Setting for WorkspaceSettings {
|
||||||
fn load(
|
fn load(
|
||||||
default_value: &Self::FileContent,
|
default_value: &Self::FileContent,
|
||||||
user_values: &[&Self::FileContent],
|
user_values: &[&Self::FileContent],
|
||||||
_: &gpui::AppContext,
|
_: &gpui2::AppContext,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
Self::load_via_json_merge(default_value, user_values)
|
Self::load_via_json_merge(default_value, user_values)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue