Detailed changes
@@ -204,6 +204,9 @@ core-graphics = { git = "https://github.com/servo/core-foundation-rs", rev = "07
[profile.dev]
split-debuginfo = "unpacked"
+[profile.dev.package.taffy]
+opt-level = 3
+
[profile.release]
debug = true
lto = "thin"
@@ -220,7 +220,6 @@ impl TestServer {
languages: Arc::new(language_registry),
fs: fs.clone(),
build_window_options: |_, _, _| Default::default(),
- initialize_workspace: |_, _, _, _| gpui::Task::ready(Ok(())),
node_runtime: FakeNodeRuntime::new(),
});
@@ -153,17 +153,20 @@ actions!(
// channel_id: ChannelId,
// }
-// const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
+const COLLABORATION_PANEL_KEY: &'static str = "CollaborationPanel";
use std::sync::Arc;
+use db::kvp::KEY_VALUE_STORE;
use gpui::{
- actions, div, AppContext, AsyncWindowContext, Div, EventEmitter, FocusHandle, Focusable,
- InteractiveComponent, ParentComponent, Render, Task, View, ViewContext, VisualContext,
- WeakView,
+ actions, div, serde_json, AppContext, AsyncWindowContext, Div, EventEmitter, FocusHandle,
+ Focusable, FocusableView, InteractiveComponent, ParentComponent, Render, View, ViewContext,
+ VisualContext, WeakView,
};
use project::Fs;
+use serde_derive::{Deserialize, Serialize};
use settings::Settings;
+use util::ResultExt;
use workspace::{
dock::{DockPosition, Panel, PanelEvent},
Workspace,
@@ -317,11 +320,11 @@ pub struct CollabPanel {
// Channel(ChannelId),
// }
-// #[derive(Serialize, Deserialize)]
-// struct SerializedCollabPanel {
-// width: Option<f32>,
-// collapsed_channels: Option<Vec<ChannelId>>,
-// }
+#[derive(Serialize, Deserialize)]
+struct SerializedCollabPanel {
+ width: Option<f32>,
+ collapsed_channels: Option<Vec<u64>>,
+}
// #[derive(Debug)]
// pub enum Event {
@@ -660,43 +663,34 @@ impl CollabPanel {
})
}
- pub fn load(
+ pub async fn load(
workspace: WeakView<Workspace>,
- cx: AsyncWindowContext,
- ) -> Task<anyhow::Result<View<Self>>> {
- cx.spawn(|mut cx| async move {
- // todo!()
- // let serialized_panel = if let Some(panel) = cx
- // .background()
- // .spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
- // .await
- // .log_err()
- // .flatten()
- // {
- // match serde_json::from_str::<SerializedCollabPanel>(&panel) {
- // Ok(panel) => Some(panel),
- // Err(err) => {
- // log::error!("Failed to deserialize collaboration panel: {}", err);
- // None
- // }
- // }
- // } else {
- // None
- // };
-
- workspace.update(&mut cx, |workspace, cx| {
- let panel = CollabPanel::new(workspace, cx);
- // if let Some(serialized_panel) = serialized_panel {
- // panel.update(cx, |panel, cx| {
- // panel.width = serialized_panel.width;
- // panel.collapsed_channels = serialized_panel
- // .collapsed_channels
- // .unwrap_or_else(|| Vec::new());
- // cx.notify();
- // });
- // }
- panel
- })
+ mut cx: AsyncWindowContext,
+ ) -> anyhow::Result<View<Self>> {
+ let serialized_panel = cx
+ .background_executor()
+ .spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
+ .await
+ .map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
+ .log_err()
+ .flatten()
+ .map(|panel| serde_json::from_str::<SerializedCollabPanel>(&panel))
+ .transpose()
+ .log_err()
+ .flatten();
+
+ workspace.update(&mut cx, |workspace, cx| {
+ let panel = CollabPanel::new(workspace, cx);
+ if let Some(serialized_panel) = serialized_panel {
+ panel.update(cx, |panel, cx| {
+ panel.width = serialized_panel.width;
+ // panel.collapsed_channels = serialized_panel
+ // .collapsed_channels
+ // .unwrap_or_else(|| Vec::new());
+ cx.notify();
+ });
+ }
+ panel
})
}
@@ -3454,11 +3448,13 @@ impl Panel for CollabPanel {
self.focus_handle.contains_focused(cx)
}
- fn persistent_name(&self) -> &'static str {
- "Collaboration Panel"
+ fn persistent_name() -> &'static str {
+ "CollabPanel"
}
+}
- fn focus_handle(&self, _cx: &ui::prelude::WindowContext) -> gpui::FocusHandle {
+impl FocusableView for CollabPanel {
+ fn focus_handle(&self, _cx: &AppContext) -> gpui::FocusHandle {
self.focus_handle.clone()
}
}
@@ -41,8 +41,8 @@ use git::diff_hunk_to_display;
use gpui::{
action, actions, div, point, prelude::*, px, relative, rems, size, uniform_list, AnyElement,
AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
- EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla,
- InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels, Render, Styled,
+ EventEmitter, FocusHandle, FocusableView, FontFeatures, FontStyle, FontWeight, HighlightStyle,
+ Hsla, InputHandler, KeyContext, Model, MouseButton, ParentComponent, Pixels, Render, Styled,
Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext,
WeakView, WindowContext,
};
@@ -9367,6 +9367,12 @@ pub struct EditorReleased(pub WeakView<Editor>);
//
impl EventEmitter<Event> for Editor {}
+impl FocusableView for Editor {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
+ self.focus_handle.clone()
+ }
+}
+
impl Render for Editor {
type Element = EditorElement;
@@ -527,10 +527,6 @@ fn deserialize_anchor(buffer: &MultiBufferSnapshot, anchor: proto::EditorAnchor)
}
impl Item for Editor {
- fn focus_handle(&self) -> FocusHandle {
- self.focus_handle.clone()
- }
-
fn navigate(&mut self, data: Box<dyn std::any::Any>, cx: &mut ViewContext<Self>) -> bool {
todo!();
// if let Ok(data) = data.downcast::<NavigationData>() {
@@ -68,7 +68,7 @@ pub trait Action: std::fmt::Debug + 'static {
// Types become actions by satisfying a list of trait bounds.
impl<A> Action for A
where
- A: for<'a> Deserialize<'a> + PartialEq + Clone + Default + std::fmt::Debug + 'static,
+ A: for<'a> Deserialize<'a> + PartialEq + Default + Clone + std::fmt::Debug + 'static,
{
fn qualified_name() -> SharedString {
let name = type_name::<A>();
@@ -1,7 +1,7 @@
use crate::{
- AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, ForegroundExecutor,
- Model, ModelContext, Render, Result, Task, View, ViewContext, VisualContext, WindowContext,
- WindowHandle,
+ AnyView, AnyWindowHandle, AppCell, AppContext, BackgroundExecutor, Context, FocusableView,
+ ForegroundExecutor, Model, ModelContext, Render, Result, Task, View, ViewContext,
+ VisualContext, WindowContext, WindowHandle,
};
use anyhow::{anyhow, Context as _};
use derive_more::{Deref, DerefMut};
@@ -307,4 +307,13 @@ impl VisualContext for AsyncWindowContext {
self.window
.update(self, |_, cx| cx.replace_root_view(build_view))
}
+
+ fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
+ where
+ V: FocusableView,
+ {
+ self.window.update(self, |_, cx| {
+ view.read(cx).focus_handle(cx).clone().focus(cx);
+ })
+ }
}
@@ -68,6 +68,7 @@ impl EntityMap {
}
/// Move an entity to the stack.
+ #[track_caller]
pub fn lease<'a, T>(&mut self, model: &'a Model<T>) -> Lease<'a, T> {
self.assert_valid_context(model);
let entity = Some(
@@ -562,6 +562,14 @@ impl<'a> VisualContext for VisualTestContext<'a> {
.update(self.cx, |_, cx| cx.replace_root_view(build_view))
.unwrap()
}
+
+ fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
+ self.window
+ .update(self.cx, |_, cx| {
+ view.read(cx).focus_handle(cx).clone().focus(cx)
+ })
+ .unwrap()
+ }
}
impl AnyWindowHandle {
@@ -135,6 +135,10 @@ pub trait VisualContext: Context {
) -> Self::Result<View<V>>
where
V: Render;
+
+ fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
+ where
+ V: FocusableView;
}
pub trait Entity<T>: Sealed {
@@ -1,7 +1,8 @@
use crate::{
private::Sealed, AnyBox, AnyElement, AnyModel, AnyWeakModel, AppContext, AvailableSpace,
- BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, LayoutId,
- Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel, WindowContext,
+ BorrowWindow, Bounds, Component, Element, ElementId, Entity, EntityId, Flatten, FocusHandle,
+ FocusableView, LayoutId, Model, Pixels, Point, Size, ViewContext, VisualContext, WeakModel,
+ WindowContext,
};
use anyhow::{Context, Result};
use std::{
@@ -73,6 +74,13 @@ impl<V: 'static> View<V> {
component: Some(component),
}
}
+
+ pub fn focus_handle(&self, cx: &AppContext) -> FocusHandle
+ where
+ V: FocusableView,
+ {
+ self.read(cx).focus_handle(cx)
+ }
}
impl<V> Clone for View<V> {
@@ -185,6 +185,10 @@ impl Drop for FocusHandle {
}
}
+pub trait FocusableView: Render {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
+}
+
// Holds the state for a specific window.
pub struct Window {
pub(crate) handle: AnyWindowHandle,
@@ -1546,6 +1550,12 @@ impl VisualContext for WindowContext<'_> {
self.window.root_view = Some(view.clone().into());
view
}
+
+ fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
+ self.update_view(view, |view, cx| {
+ view.focus_handle(cx).clone().focus(cx);
+ })
+ }
}
impl<'a> std::ops::Deref for WindowContext<'a> {
@@ -2219,9 +2229,7 @@ impl<'a, V: 'static> ViewContext<'a, V> {
.set_input_handler(Box::new(input_handler));
}
}
-}
-impl<V> ViewContext<'_, V> {
pub fn emit<Evt>(&mut self, event: Evt)
where
Evt: 'static,
@@ -2234,6 +2242,13 @@ impl<V> ViewContext<'_, V> {
event: Box::new(event),
});
}
+
+ pub fn focus_self(&mut self)
+ where
+ V: FocusableView,
+ {
+ self.defer(|view, cx| view.focus_handle(cx).focus(cx))
+ }
}
impl<V> Context for ViewContext<'_, V> {
@@ -2309,6 +2324,10 @@ impl<V: 'static> VisualContext for ViewContext<'_, V> {
{
self.window_cx.replace_root_view(build_view)
}
+
+ fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
+ self.window_cx.focus_view(view)
+ }
}
impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
@@ -9,10 +9,10 @@ use file_associations::FileAssociations;
use anyhow::{anyhow, Result};
use gpui::{
actions, div, px, uniform_list, Action, AppContext, AssetSource, AsyncWindowContext,
- ClipboardItem, Component, Div, EventEmitter, FocusHandle, Focusable, InteractiveComponent,
- Model, MouseButton, ParentComponent, Pixels, Point, PromptLevel, Render, Stateful,
- StatefulInteractiveComponent, Styled, Task, UniformListScrollHandle, View, ViewContext,
- VisualContext as _, WeakView, WindowContext,
+ ClipboardItem, Component, Div, EventEmitter, FocusHandle, Focusable, FocusableView,
+ InteractiveComponent, Model, MouseButton, ParentComponent, Pixels, Point, PromptLevel, Render,
+ Stateful, StatefulInteractiveComponent, Styled, Task, UniformListScrollHandle, View,
+ ViewContext, VisualContext as _, WeakView, WindowContext,
};
use menu::{Confirm, SelectNext, SelectPrev};
use project::{
@@ -32,7 +32,7 @@ use std::{
use theme::ActiveTheme as _;
use ui::{h_stack, v_stack, IconElement, Label};
use unicase::UniCase;
-use util::{maybe, TryFutureExt};
+use util::{maybe, ResultExt, TryFutureExt};
use workspace::{
dock::{DockPosition, PanelEvent},
Workspace,
@@ -310,32 +310,31 @@ impl ProjectPanel {
project_panel
}
- pub fn load(
+ pub async fn load(
workspace: WeakView<Workspace>,
- cx: AsyncWindowContext,
- ) -> Task<Result<View<Self>>> {
- cx.spawn(|mut cx| async move {
- // let serialized_panel = if let Some(panel) = cx
- // .background_executor()
- // .spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
- // .await
- // .log_err()
- // .flatten()
- // {
- // Some(serde_json::from_str::<SerializedProjectPanel>(&panel)?)
- // } else {
- // None
- // };
- workspace.update(&mut cx, |workspace, cx| {
- let panel = ProjectPanel::new(workspace, cx);
- // if let Some(serialized_panel) = serialized_panel {
- // panel.update(cx, |panel, cx| {
- // panel.width = serialized_panel.width;
- // cx.notify();
- // });
- // }
- panel
- })
+ mut cx: AsyncWindowContext,
+ ) -> Result<View<Self>> {
+ let serialized_panel = cx
+ .background_executor()
+ .spawn(async move { KEY_VALUE_STORE.read_kvp(PROJECT_PANEL_KEY) })
+ .await
+ .map_err(|e| anyhow!("Failed to load project panel: {}", e))
+ .log_err()
+ .flatten()
+ .map(|panel| serde_json::from_str::<SerializedProjectPanel>(&panel))
+ .transpose()
+ .log_err()
+ .flatten();
+
+ workspace.update(&mut cx, |workspace, cx| {
+ let panel = ProjectPanel::new(workspace, cx);
+ if let Some(serialized_panel) = serialized_panel {
+ panel.update(cx, |panel, cx| {
+ panel.width = serialized_panel.width;
+ cx.notify();
+ });
+ }
+ panel
})
}
@@ -1531,25 +1530,19 @@ impl workspace::dock::Panel for ProjectPanel {
Box::new(ToggleFocus)
}
- // fn should_change_position_on_event(event: &Self::Event) -> bool {
- // matches!(event, Event::DockPositionChanged)
- // }
-
fn has_focus(&self, _: &WindowContext) -> bool {
self.has_focus
}
- fn persistent_name(&self) -> &'static str {
+ fn persistent_name() -> &'static str {
"Project Panel"
}
+}
- fn focus_handle(&self, _cx: &WindowContext) -> FocusHandle {
+impl FocusableView for ProjectPanel {
+ fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
self.focus_handle.clone()
}
-
- // fn is_focus_event(event: &Self::Event) -> bool {
- // matches!(event, Event::Focus)
- // }
}
impl ClipboardEntry {
@@ -9,7 +9,7 @@ use schemars::{
};
use serde::Deserialize;
use serde_json::Value;
-use util::asset_str;
+use util::{asset_str, ResultExt};
#[derive(Debug, Deserialize, Default, Clone, JsonSchema)]
#[serde(transparent)]
@@ -86,9 +86,7 @@ impl KeymapFile {
"invalid binding value for keystroke {keystroke}, context {context:?}"
)
})
- // todo!()
- .ok()
- // .log_err()
+ .log_err()
.map(|action| KeyBinding::load(&keystroke, action, context.as_deref()))
})
.collect::<Result<Vec<_>>>()?;
@@ -1,8 +1,8 @@
use crate::{status_bar::StatusItemView, Axis, Workspace};
use gpui::{
div, px, Action, AnyView, AppContext, Component, Div, Entity, EntityId, EventEmitter,
- FocusHandle, ParentComponent, Render, Styled, Subscription, View, ViewContext, WeakView,
- WindowContext,
+ FocusHandle, FocusableView, ParentComponent, Render, Styled, Subscription, View, ViewContext,
+ WeakView, WindowContext,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -18,8 +18,8 @@ pub enum PanelEvent {
Focus,
}
-pub trait Panel: Render + EventEmitter<PanelEvent> {
- fn persistent_name(&self) -> &'static str;
+pub trait Panel: FocusableView + EventEmitter<PanelEvent> {
+ fn persistent_name() -> &'static str;
fn position(&self, cx: &WindowContext) -> DockPosition;
fn position_is_valid(&self, position: DockPosition) -> bool;
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
@@ -36,12 +36,11 @@ pub trait Panel: Render + EventEmitter<PanelEvent> {
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {}
fn set_active(&mut self, _active: bool, _cx: &mut ViewContext<Self>) {}
fn has_focus(&self, cx: &WindowContext) -> bool;
- fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
}
pub trait PanelHandle: Send + Sync {
fn id(&self) -> EntityId;
- fn persistent_name(&self, cx: &WindowContext) -> &'static str;
+ fn persistent_name(&self) -> &'static str;
fn position(&self, cx: &WindowContext) -> DockPosition;
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
fn set_position(&self, position: DockPosition, cx: &mut WindowContext);
@@ -54,7 +53,7 @@ pub trait PanelHandle: Send + Sync {
fn toggle_action(&self, cx: &WindowContext) -> Box<dyn Action>;
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
fn has_focus(&self, cx: &WindowContext) -> bool;
- fn focus_handle(&self, cx: &WindowContext) -> FocusHandle;
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
fn to_any(&self) -> AnyView;
}
@@ -66,8 +65,8 @@ where
self.entity_id()
}
- fn persistent_name(&self, cx: &WindowContext) -> &'static str {
- self.read(cx).persistent_name()
+ fn persistent_name(&self) -> &'static str {
+ T::persistent_name()
}
fn position(&self, cx: &WindowContext) -> DockPosition {
@@ -122,7 +121,7 @@ where
self.clone().into()
}
- fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
self.read(cx).focus_handle(cx).clone()
}
}
@@ -140,6 +139,14 @@ pub struct Dock {
active_panel_index: usize,
}
+impl FocusableView for Dock {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
+ self.panel_entries[self.active_panel_index]
+ .panel
+ .focus_handle(cx)
+ }
+}
+
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum DockPosition {
@@ -221,12 +228,14 @@ impl Dock {
.position(|entry| entry.panel.to_any().downcast::<T>().is_ok())
}
- pub fn panel_index_for_ui_name(&self, _ui_name: &str, _cx: &AppContext) -> Option<usize> {
- todo!()
- // self.panel_entries.iter().position(|entry| {
- // let panel = entry.panel.as_any();
- // cx.view_ui_name(panel.window(), panel.id()) == Some(ui_name)
- // })
+ pub fn panel_index_for_persistent_name(
+ &self,
+ ui_name: &str,
+ _cx: &AppContext,
+ ) -> Option<usize> {
+ self.panel_entries
+ .iter()
+ .position(|entry| entry.panel.persistent_name() == ui_name)
}
pub fn active_panel_index(&self) -> usize {
@@ -654,11 +663,11 @@ impl Render for PanelButtons {
.enumerate()
.filter_map(|(i, panel)| {
let icon = panel.panel.icon(cx)?;
- let name = panel.panel.persistent_name(cx);
+ let name = panel.panel.persistent_name();
let action = panel.panel.toggle_action(cx);
let action2 = action.boxed_clone();
- let mut button = IconButton::new(panel.panel.persistent_name(cx), icon)
+ let mut button = IconButton::new(panel.panel.persistent_name(), icon)
.when(i == active_index, |el| el.state(InteractionState::Active))
.on_click(move |this, cx| cx.dispatch_action(action.boxed_clone()))
.tooltip(move |_, cx| Tooltip::for_action(name, &*action2, cx));
@@ -717,7 +726,7 @@ pub mod test {
}
impl Panel for TestPanel {
- fn persistent_name(&self) -> &'static str {
+ fn persistent_name() -> &'static str {
"TestPanel"
}
@@ -765,8 +774,10 @@ pub mod test {
fn has_focus(&self, _cx: &WindowContext) -> bool {
self.has_focus
}
+ }
- fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
+ impl FocusableView for TestPanel {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
unimplemented!()
}
}
@@ -12,8 +12,9 @@ use client2::{
Client,
};
use gpui::{
- AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, HighlightStyle,
- Model, Pixels, Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext,
+ AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, FocusHandle, FocusableView,
+ HighlightStyle, Model, Pixels, Point, SharedString, Task, View, ViewContext, WeakView,
+ WindowContext,
};
use project2::{Project, ProjectEntryId, ProjectPath};
use schemars::JsonSchema;
@@ -91,8 +92,7 @@ pub struct BreadcrumbText {
pub highlights: Option<Vec<(Range<usize>, HighlightStyle)>>,
}
-pub trait Item: Render + EventEmitter<ItemEvent> {
- fn focus_handle(&self) -> FocusHandle;
+pub trait Item: FocusableView + EventEmitter<ItemEvent> {
fn 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 {
@@ -286,7 +286,7 @@ impl dyn ItemHandle {
impl<T: Item> ItemHandle for View<T> {
fn focus_handle(&self, cx: &WindowContext) -> FocusHandle {
- self.read(cx).focus_handle()
+ self.focus_handle(cx)
}
fn subscribe_to_item_events(
@@ -8,8 +8,8 @@ use anyhow::Result;
use collections::{HashMap, HashSet, VecDeque};
use gpui::{
actions, prelude::*, register_action, AppContext, AsyncWindowContext, Component, Div, EntityId,
- EventEmitter, FocusHandle, Focusable, Model, PromptLevel, Render, Task, View, ViewContext,
- VisualContext, WeakView, WindowContext,
+ EventEmitter, FocusHandle, Focusable, FocusableView, Model, PromptLevel, Render, Task, View,
+ ViewContext, VisualContext, WeakView, WindowContext,
};
use parking_lot::Mutex;
use project2::{Project, ProjectEntryId, ProjectPath};
@@ -125,10 +125,6 @@ pub fn init(cx: &mut AppContext) {
// cx.add_async_action(Pane::close_items_to_the_left);
// cx.add_async_action(Pane::close_items_to_the_right);
// cx.add_async_action(Pane::close_all_items);
- // cx.add_action(|pane: &mut Pane, _: &SplitLeft, cx| pane.split(SplitDirection::Left, cx));
- // cx.add_action(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx));
- // cx.add_action(|pane: &mut Pane, _: &SplitRight, cx| pane.split(SplitDirection::Right, cx));
- // cx.add_action(|pane: &mut Pane, _: &SplitDown, cx| pane.split(SplitDirection::Down, cx));
}
pub enum Event {
@@ -1195,9 +1191,9 @@ impl Pane {
}
}
- // pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
- // cx.emit(Event::Split(direction));
- // }
+ pub fn split(&mut self, direction: SplitDirection, cx: &mut ViewContext<Self>) {
+ cx.emit(Event::Split(direction));
+ }
// fn deploy_split_menu(&mut self, cx: &mut ViewContext<Self>) {
// self.tab_bar_context_menu.handle.update(cx, |menu, cx| {
@@ -1398,6 +1394,7 @@ impl Pane {
.when_some(item.tab_tooltip_text(cx), |div, text| {
div.tooltip(move |_, cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
})
+ .on_click(move |v: &mut Self, e, cx| v.activate_item(ix, true, true, cx))
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
// .on_drop(|_view, state: View<DraggedTab>, cx| {
@@ -1430,32 +1427,22 @@ impl Pane {
.items_center()
.gap_1()
.text_color(text_color)
- .children(if item.has_conflict(cx) {
- Some(
- IconElement::new(Icon::ExclamationTriangle)
- .size(ui::IconSize::Small)
- .color(TextColor::Warning),
- )
- } else if item.is_dirty(cx) {
- Some(
- IconElement::new(Icon::ExclamationTriangle)
- .size(ui::IconSize::Small)
- .color(TextColor::Info),
- )
- } else {
- None
- })
- .children(if !close_right {
- Some(close_icon())
- } else {
- None
- })
+ .children(
+ item.has_conflict(cx)
+ .then(|| {
+ IconElement::new(Icon::ExclamationTriangle)
+ .size(ui::IconSize::Small)
+ .color(TextColor::Warning)
+ })
+ .or(item.is_dirty(cx).then(|| {
+ IconElement::new(Icon::ExclamationTriangle)
+ .size(ui::IconSize::Small)
+ .color(TextColor::Info)
+ })),
+ )
+ .children((!close_right).then(|| close_icon()))
.child(label)
- .children(if close_right {
- Some(close_icon())
- } else {
- None
- }),
+ .children(close_right.then(|| close_icon())),
)
}
@@ -1912,9 +1899,11 @@ impl Pane {
}
}
-// impl Entity for Pane {
-// type Event = Event;
-// }
+impl FocusableView for Pane {
+ fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
+ self.focus_handle.clone()
+ }
+}
impl Render for Pane {
type Element = Focusable<Self, Div<Self>>;
@@ -1923,6 +1912,10 @@ impl Render for Pane {
v_stack()
.key_context("Pane")
.track_focus(&self.focus_handle)
+ .on_action(|pane: &mut Pane, _: &SplitLeft, cx| pane.split(SplitDirection::Left, cx))
+ .on_action(|pane: &mut Pane, _: &SplitUp, cx| pane.split(SplitDirection::Up, cx))
+ .on_action(|pane: &mut Pane, _: &SplitRight, cx| pane.split(SplitDirection::Right, cx))
+ .on_action(|pane: &mut Pane, _: &SplitDown, cx| pane.split(SplitDirection::Down, cx))
.size_full()
.on_action(|pane: &mut Self, action, cx| {
pane.close_active_item(action, cx)
@@ -148,6 +148,10 @@ impl PaneGroup {
self.root.collect_panes(&mut panes);
panes
}
+
+ pub(crate) fn first_pane(&self) -> View<Pane> {
+ self.root.first_pane()
+ }
}
#[derive(Clone, PartialEq)]
@@ -181,6 +185,13 @@ impl Member {
}
}
+ fn first_pane(&self) -> View<Pane> {
+ match self {
+ Member::Axis(axis) => axis.members[0].first_pane(),
+ Member::Pane(pane) => pane.clone(),
+ }
+ }
+
pub fn render(
&self,
project: &Model<Project>,
@@ -551,7 +562,32 @@ impl PaneAxis {
) -> AnyElement<Workspace> {
debug_assert!(self.members.len() == self.flexes.lock().len());
- todo!()
+ div()
+ .flex()
+ .flex_auto()
+ .map(|s| match self.axis {
+ Axis::Vertical => s.flex_col(),
+ Axis::Horizontal => s.flex_row(),
+ })
+ .children(self.members.iter().enumerate().map(|(ix, member)| {
+ match member {
+ Member::Axis(axis) => axis
+ .render(
+ project,
+ basis,
+ follower_states,
+ active_call,
+ active_pane,
+ zoomed,
+ app_state,
+ cx,
+ )
+ .render(),
+ Member::Pane(pane) => pane.clone().render(),
+ }
+ }))
+ .render()
+
// let mut pane_axis = PaneAxisElement::new(
// self.axis,
// basis,
@@ -68,41 +68,6 @@ impl StatusBar {
}
}
-// todo!()
-// impl View for StatusBar {
-// fn ui_name() -> &'static str {
-// "StatusBar"
-// }
-
-// fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
-// let theme = &theme::current(cx).workspace.status_bar;
-
-// StatusBarElement {
-// left: Flex::row()
-// .with_children(self.left_items.iter().map(|i| {
-// ChildView::new(i.as_any(), cx)
-// .aligned()
-// .contained()
-// .with_margin_right(theme.item_spacing)
-// }))
-// .into_any(),
-// right: Flex::row()
-// .with_children(self.right_items.iter().rev().map(|i| {
-// ChildView::new(i.as_any(), cx)
-// .aligned()
-// .contained()
-// .with_margin_left(theme.item_spacing)
-// }))
-// .into_any(),
-// }
-// .contained()
-// .with_style(theme.container)
-// .constrained()
-// .with_height(theme.height)
-// .into_any()
-// }
-// }
-
impl StatusBar {
pub fn new(active_pane: &View<Pane>, cx: &mut ViewContext<Self>) -> Self {
let mut this = Self {
@@ -222,80 +187,3 @@ impl From<&dyn StatusItemViewHandle> for AnyView {
val.to_any().clone()
}
}
-
-// todo!()
-// struct StatusBarElement {
-// left: AnyElement<StatusBar>,
-// right: AnyElement<StatusBar>,
-// }
-
-// todo!()
-// impl Element<StatusBar> for StatusBarElement {
-// type LayoutState = ();
-// type PaintState = ();
-
-// fn layout(
-// &mut self,
-// mut constraint: SizeConstraint,
-// view: &mut StatusBar,
-// cx: &mut ViewContext<StatusBar>,
-// ) -> (Vector2F, Self::LayoutState) {
-// let max_width = constraint.max.x();
-// constraint.min = vec2f(0., constraint.min.y());
-
-// let right_size = self.right.layout(constraint, view, cx);
-// let constraint = SizeConstraint::new(
-// vec2f(0., constraint.min.y()),
-// vec2f(max_width - right_size.x(), constraint.max.y()),
-// );
-
-// self.left.layout(constraint, view, cx);
-
-// (vec2f(max_width, right_size.y()), ())
-// }
-
-// fn paint(
-// &mut self,
-// bounds: RectF,
-// visible_bounds: RectF,
-// _: &mut Self::LayoutState,
-// view: &mut StatusBar,
-// cx: &mut ViewContext<StatusBar>,
-// ) -> Self::PaintState {
-// let origin_y = bounds.upper_right().y();
-// let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
-
-// let left_origin = vec2f(bounds.lower_left().x(), origin_y);
-// self.left.paint(left_origin, visible_bounds, view, cx);
-
-// let right_origin = vec2f(bounds.upper_right().x() - self.right.size().x(), origin_y);
-// self.right.paint(right_origin, visible_bounds, view, cx);
-// }
-
-// fn rect_for_text_range(
-// &self,
-// _: Range<usize>,
-// _: RectF,
-// _: RectF,
-// _: &Self::LayoutState,
-// _: &Self::PaintState,
-// _: &StatusBar,
-// _: &ViewContext<StatusBar>,
-// ) -> Option<RectF> {
-// None
-// }
-
-// fn debug(
-// &self,
-// bounds: RectF,
-// _: &Self::LayoutState,
-// _: &Self::PaintState,
-// _: &StatusBar,
-// _: &ViewContext<StatusBar>,
-// ) -> serde_json::Value {
-// json!({
-// "type": "StatusBarElement",
-// "bounds": bounds.to_json()
-// })
-// }
-// }
@@ -37,9 +37,10 @@ use futures::{
};
use gpui::{
actions, div, point, prelude::*, size, Action, AnyModel, AnyView, AnyWeakView, AppContext,
- AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, GlobalPixels,
- KeyContext, Model, ModelContext, ParentComponent, Point, Render, Size, Styled, Subscription,
- Task, View, ViewContext, WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions,
+ AsyncAppContext, AsyncWindowContext, Bounds, Div, Entity, EntityId, EventEmitter, FocusHandle,
+ FocusableView, GlobalPixels, KeyContext, Model, ModelContext, ParentComponent, Point, Render,
+ Size, Styled, Subscription, Task, View, ViewContext, WeakView, WindowBounds, WindowContext,
+ WindowHandle, WindowOptions,
};
use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem};
use itertools::Itertools;
@@ -319,12 +320,6 @@ pub struct AppState {
pub fs: Arc<dyn fs2::Fs>,
pub build_window_options:
fn(Option<WindowBounds>, Option<Uuid>, &mut AppContext) -> WindowOptions,
- pub initialize_workspace: fn(
- WeakView<Workspace>,
- bool,
- Arc<AppState>,
- AsyncWindowContext,
- ) -> Task<anyhow::Result<()>>,
pub node_runtime: Arc<dyn NodeRuntime>,
}
@@ -370,7 +365,6 @@ impl AppState {
user_store,
workspace_store,
node_runtime: FakeNodeRuntime::new(),
- initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
build_window_options: |_, _, _| Default::default(),
})
}
@@ -682,7 +676,7 @@ impl Workspace {
fn new_local(
abs_paths: Vec<PathBuf>,
app_state: Arc<AppState>,
- _requesting_window: Option<WindowHandle<Workspace>>,
+ requesting_window: Option<WindowHandle<Workspace>>,
cx: &mut AppContext,
) -> Task<
anyhow::Result<(
@@ -700,7 +694,8 @@ impl Workspace {
);
cx.spawn(|mut cx| async move {
- let serialized_workspace: Option<SerializedWorkspace> = None; //persistence::DB.workspace_for_roots(&abs_paths.as_slice());
+ let serialized_workspace: Option<SerializedWorkspace> =
+ persistence::DB.workspace_for_roots(&abs_paths.as_slice());
let paths_to_open = Arc::new(abs_paths);
@@ -729,15 +724,14 @@ impl Workspace {
DB.next_id().await.unwrap_or(0)
};
- // todo!()
- let window = /*if let Some(window) = requesting_window {
+ let window = if let Some(window) = requesting_window {
cx.update_window(window.into(), |old_workspace, cx| {
cx.replace_root_view(|cx| {
Workspace::new(workspace_id, project_handle.clone(), app_state.clone(), cx)
});
- });
+ })?;
window
- } else */ {
+ } else {
let window_bounds_override = window_bounds_env_override(&cx);
let (bounds, display) = if let Some(bounds) = window_bounds_override {
(Some(bounds), None)
@@ -751,12 +745,13 @@ impl Workspace {
// Stored bounds are relative to the containing display.
// So convert back to global coordinates if that screen still exists
if let WindowBounds::Fixed(mut window_bounds) = bounds {
- let screen =
- cx.update(|cx|
- cx.displays()
- .into_iter()
- .find(|display| display.uuid().ok() == Some(serialized_display))
- ).ok()??;
+ let screen = cx
+ .update(|cx| {
+ cx.displays().into_iter().find(|display| {
+ display.uuid().ok() == Some(serialized_display)
+ })
+ })
+ .ok()??;
let screen_bounds = screen.bounds();
window_bounds.origin.x += screen_bounds.origin.x;
window_bounds.origin.y += screen_bounds.origin.y;
@@ -785,17 +780,17 @@ impl Workspace {
};
// todo!() Ask how to do this
- let weak_view = window.update(&mut cx, |_, cx| cx.view().downgrade())?;
- let async_cx = window.update(&mut cx, |_, cx| cx.to_async())?;
-
- (app_state.initialize_workspace)(
- weak_view,
- serialized_workspace.is_some(),
- app_state.clone(),
- async_cx,
- )
- .await
- .log_err();
+ // let weak_view = window.update(&mut cx, |_, cx| cx.view().downgrade())?;
+ // let async_cx = window.update(&mut cx, |_, cx| cx.to_async())?;
+
+ // (app_state.initialize_workspace)(
+ // weak_view,
+ // serialized_workspace.is_some(),
+ // app_state.clone(),
+ // async_cx,
+ // )
+ // .await
+ // .log_err();
window
.update(&mut cx, |_, cx| cx.activate_window())
@@ -804,12 +799,7 @@ impl Workspace {
notify_if_database_failed(window, &mut cx);
let opened_items = window
.update(&mut cx, |_workspace, cx| {
- open_items(
- serialized_workspace,
- project_paths,
- app_state,
- cx,
- )
+ open_items(serialized_workspace, project_paths, app_state, cx)
})?
.await
.unwrap_or_default();
@@ -2970,13 +2960,15 @@ impl Workspace {
cx.notify();
}
- // fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) {
- // self._schedule_serialize = Some(cx.spawn(|this, cx| async move {
- // cx.background().timer(Duration::from_millis(100)).await;
- // this.read_with(&cx, |this, cx| this.serialize_workspace(cx))
- // .ok();
- // }));
- // }
+ fn schedule_serialize(&mut self, cx: &mut ViewContext<Self>) {
+ self._schedule_serialize = Some(cx.spawn(|this, mut cx| async move {
+ cx.background_executor()
+ .timer(Duration::from_millis(100))
+ .await;
+ this.update(&mut cx, |this, cx| this.serialize_workspace(cx))
+ .log_err();
+ }));
+ }
fn serialize_workspace(&self, cx: &mut ViewContext<Self>) {
fn serialize_pane_handle(pane_handle: &View<Pane>, cx: &WindowContext) -> SerializedPane {
@@ -3032,7 +3024,7 @@ impl Workspace {
let left_visible = left_dock.is_open();
let left_active_panel = left_dock
.visible_panel()
- .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
+ .and_then(|panel| Some(panel.persistent_name().to_string()));
let left_dock_zoom = left_dock
.visible_panel()
.map(|panel| panel.is_zoomed(cx))
@@ -3042,7 +3034,7 @@ impl Workspace {
let right_visible = right_dock.is_open();
let right_active_panel = right_dock
.visible_panel()
- .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
+ .and_then(|panel| Some(panel.persistent_name().to_string()));
let right_dock_zoom = right_dock
.visible_panel()
.map(|panel| panel.is_zoomed(cx))
@@ -3052,7 +3044,7 @@ impl Workspace {
let bottom_visible = bottom_dock.is_open();
let bottom_active_panel = bottom_dock
.visible_panel()
- .and_then(|panel| Some(panel.persistent_name(cx).to_string()));
+ .and_then(|panel| Some(panel.persistent_name().to_string()));
let bottom_dock_zoom = bottom_dock
.visible_panel()
.map(|panel| panel.is_zoomed(cx))
@@ -3158,45 +3150,34 @@ impl Workspace {
// Swap workspace center group
workspace.center = PaneGroup::with_root(center_group);
-
- // Change the focus to the workspace first so that we retrigger focus in on the pane.
- // todo!()
- // cx.focus_self();
- // if let Some(active_pane) = active_pane {
- // cx.focus(&active_pane);
- // } else {
- // cx.focus(workspace.panes.last().unwrap());
- // }
- } else {
- // todo!()
- // let old_center_handle = old_center_pane.and_then(|weak| weak.upgrade());
- // if let Some(old_center_handle) = old_center_handle {
- // cx.focus(&old_center_handle)
- // } else {
- // cx.focus_self()
- // }
+ workspace.last_active_center_pane = active_pane.as_ref().map(|p| p.downgrade());
+ if let Some(active_pane) = active_pane {
+ workspace.active_pane = active_pane;
+ cx.focus_self();
+ } else {
+ workspace.active_pane = workspace.center.first_pane().clone();
+ }
}
let docks = serialized_workspace.docks;
workspace.left_dock.update(cx, |dock, cx| {
dock.set_open(docks.left.visible, cx);
if let Some(active_panel) = docks.left.active_panel {
- if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
+ if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
dock.activate_panel(ix, cx);
}
}
dock.active_panel()
.map(|panel| panel.set_zoomed(docks.left.zoom, cx));
if docks.left.visible && docks.left.zoom {
- // todo!()
- // cx.focus_self()
+ cx.focus_self()
}
});
// TODO: I think the bug is that setting zoom or active undoes the bottom zoom or something
workspace.right_dock.update(cx, |dock, cx| {
dock.set_open(docks.right.visible, cx);
if let Some(active_panel) = docks.right.active_panel {
- if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
+ if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
dock.activate_panel(ix, cx);
}
}
@@ -3204,14 +3185,13 @@ impl Workspace {
.map(|panel| panel.set_zoomed(docks.right.zoom, cx));
if docks.right.visible && docks.right.zoom {
- // todo!()
- // cx.focus_self()
+ cx.focus_self()
}
});
workspace.bottom_dock.update(cx, |dock, cx| {
dock.set_open(docks.bottom.visible, cx);
if let Some(active_panel) = docks.bottom.active_panel {
- if let Some(ix) = dock.panel_index_for_ui_name(&active_panel, cx) {
+ if let Some(ix) = dock.panel_index_for_persistent_name(&active_panel, cx) {
dock.activate_panel(ix, cx);
}
}
@@ -3220,8 +3200,7 @@ impl Workspace {
.map(|panel| panel.set_zoomed(docks.bottom.zoom, cx));
if docks.bottom.visible && docks.bottom.zoom {
- // todo!()
- // cx.focus_self()
+ cx.focus_self()
}
});
@@ -3283,7 +3262,6 @@ impl Workspace {
// },
// );
.on_action(|this, e: &ToggleLeftDock, cx| {
- println!("TOGGLING DOCK");
this.toggle_dock(DockPosition::Left, cx);
})
// cx.add_action(|workspace: &mut Workspace, _: &ToggleRightDock, cx| {
@@ -3347,7 +3325,6 @@ impl Workspace {
user_store,
fs: project.read(cx).fs().clone(),
build_window_options: |_, _, _| Default::default(),
- initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
node_runtime: FakeNodeRuntime::new(),
});
let workspace = Self::new(0, project, app_state, cx);
@@ -3626,6 +3603,12 @@ fn notify_if_database_failed(workspace: WindowHandle<Workspace>, cx: &mut AsyncA
impl EventEmitter<Event> for Workspace {}
+impl FocusableView for Workspace {
+ fn focus_handle(&self, cx: &AppContext) -> FocusHandle {
+ self.active_pane.focus_handle(cx)
+ }
+}
+
impl Render for Workspace {
type Element = Div<Self>;
@@ -50,8 +50,8 @@ use util::{
use uuid::Uuid;
use workspace::{AppState, WorkspaceStore};
use zed2::{
- build_window_options, ensure_only_instance, handle_cli_connection, init_zed_actions,
- initialize_workspace, languages, Assets, IsOnlyInstance, OpenListener, OpenRequest,
+ build_window_options, ensure_only_instance, handle_cli_connection, initialize_workspace,
+ languages, Assets, IsOnlyInstance, OpenListener, OpenRequest,
};
mod open_listener;
@@ -176,7 +176,6 @@ fn main() {
user_store,
fs,
build_window_options,
- initialize_workspace,
// background_actions: todo!("ask Mikayla"),
workspace_store,
node_runtime,
@@ -213,7 +212,7 @@ fn main() {
// zed::init(&app_state, cx);
// cx.set_menus(menus::menus());
- init_zed_actions(app_state.clone(), cx);
+ initialize_workspace(app_state.clone(), cx);
if stdout_is_a_pty() {
cx.activate(true);
@@ -10,13 +10,13 @@ pub use assets::*;
use collections::VecDeque;
use editor::{Editor, MultiBuffer};
use gpui::{
- actions, point, px, AppContext, AsyncWindowContext, Context, PromptLevel, Task,
- TitlebarOptions, ViewContext, VisualContext, WeakView, WindowBounds, WindowKind, WindowOptions,
+ actions, point, px, AppContext, Context, PromptLevel, TitlebarOptions, ViewContext,
+ VisualContext, WindowBounds, WindowKind, WindowOptions,
};
pub use only_instance::*;
pub use open_listener::*;
-use anyhow::{anyhow, Context as _, Result};
+use anyhow::{anyhow, Context as _};
use project_panel::ProjectPanel;
use settings::{initial_local_settings_content, Settings};
use std::{borrow::Cow, ops::Deref, sync::Arc};
@@ -86,8 +86,147 @@ pub fn build_window_options(
}
}
-pub fn init_zed_actions(app_state: Arc<AppState>, cx: &mut AppContext) {
- cx.observe_new_views(move |workspace: &mut Workspace, _cx| {
+pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
+ cx.observe_new_views(move |workspace: &mut Workspace, cx| {
+ let workspace_handle = cx.view().clone();
+ cx.subscribe(&workspace_handle, {
+ move |workspace, _, event, cx| {
+ if let workspace::Event::PaneAdded(pane) = event {
+ pane.update(cx, |pane, cx| {
+ pane.toolbar().update(cx, |toolbar, cx| {
+ // todo!()
+ // let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
+ // toolbar.add_item(breadcrumbs, cx);
+ // let buffer_search_bar = cx.add_view(BufferSearchBar::new);
+ // toolbar.add_item(buffer_search_bar.clone(), cx);
+ // let quick_action_bar = cx.add_view(|_| {
+ // QuickActionBar::new(buffer_search_bar, workspace)
+ // });
+ // toolbar.add_item(quick_action_bar, cx);
+ // let diagnostic_editor_controls =
+ // cx.add_view(|_| diagnostics2::ToolbarControls::new());
+ // toolbar.add_item(diagnostic_editor_controls, cx);
+ // let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
+ // toolbar.add_item(project_search_bar, cx);
+ // let submit_feedback_button =
+ // cx.add_view(|_| SubmitFeedbackButton::new());
+ // toolbar.add_item(submit_feedback_button, cx);
+ // let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
+ // toolbar.add_item(feedback_info_text, cx);
+ // let lsp_log_item =
+ // cx.add_view(|_| language_tools::LspLogToolbarItemView::new());
+ // toolbar.add_item(lsp_log_item, cx);
+ // let syntax_tree_item = cx
+ // .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
+ // toolbar.add_item(syntax_tree_item, cx);
+ })
+ });
+ }
+ }
+ })
+ .detach();
+
+ // cx.emit(workspace2::Event::PaneAdded(
+ // workspace.active_pane().clone(),
+ // ));
+
+ // let collab_titlebar_item =
+ // cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
+ // workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
+
+ // let copilot =
+ // cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
+ // let diagnostic_summary =
+ // cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
+ // let activity_indicator = activity_indicator::ActivityIndicator::new(
+ // workspace,
+ // app_state.languages.clone(),
+ // cx,
+ // );
+ // let active_buffer_language =
+ // cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
+ // let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
+ // let feedback_button = cx.add_view(|_| {
+ // feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
+ // });
+ // let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
+ workspace.status_bar().update(cx, |status_bar, cx| {
+ // status_bar.add_left_item(diagnostic_summary, cx);
+ // status_bar.add_left_item(activity_indicator, cx);
+
+ // status_bar.add_right_item(feedback_button, cx);
+ // status_bar.add_right_item(copilot, cx);
+ // status_bar.add_right_item(active_buffer_language, cx);
+ // status_bar.add_right_item(vim_mode_indicator, cx);
+ // status_bar.add_right_item(cursor_position, cx);
+ });
+
+ // auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
+
+ // vim::observe_keystrokes(cx);
+
+ // cx.on_window_should_close(|workspace, cx| {
+ // if let Some(task) = workspace.close(&Default::default(), cx) {
+ // task.detach_and_log_err(cx);
+ // }
+ // false
+ // });
+
+ cx.spawn(|workspace_handle, mut cx| async move {
+ let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
+ // let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
+ // let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
+ let channels_panel =
+ collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
+ // let chat_panel =
+ // collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
+ // let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
+ // workspace_handle.clone(),
+ // cx.clone(),
+ // );
+ let (
+ project_panel,
+ // terminal_panel,
+ // assistant_panel,
+ channels_panel,
+ // chat_panel,
+ // notification_panel,
+ ) = futures::try_join!(
+ project_panel,
+ // terminal_panel,
+ // assistant_panel,
+ channels_panel,
+ // chat_panel,
+ // notification_panel,
+ )?;
+
+ workspace_handle.update(&mut cx, |workspace, cx| {
+ let project_panel_position = project_panel.position(cx);
+ workspace.add_panel(project_panel, cx);
+ // workspace.add_panel(terminal_panel, cx);
+ // workspace.add_panel(assistant_panel, cx);
+ workspace.add_panel(channels_panel, cx);
+ // workspace.add_panel(chat_panel, cx);
+ // workspace.add_panel(notification_panel, cx);
+
+ // if !was_deserialized
+ // && workspace
+ // .project()
+ // .read(cx)
+ // .visible_worktrees(cx)
+ // .any(|tree| {
+ // tree.read(cx)
+ // .root_entry()
+ // .map_or(false, |entry| entry.is_dir())
+ // })
+ // {
+ // workspace.toggle_dock(project_panel_position, cx);
+ // }
+ // cx.focus_self();
+ })
+ })
+ .detach();
+
workspace
.register_action(about)
.register_action(|_, _: &Hide, cx| {
@@ -291,150 +430,6 @@ pub fn init_zed_actions(app_state: Arc<AppState>, cx: &mut AppContext) {
.detach();
}
-pub fn initialize_workspace(
- workspace_handle: WeakView<Workspace>,
- was_deserialized: bool,
- app_state: Arc<AppState>,
- cx: AsyncWindowContext,
-) -> Task<Result<()>> {
- cx.spawn(|mut cx| async move {
- workspace_handle.update(&mut cx, |workspace, cx| {
- let workspace_handle = cx.view().clone();
- cx.subscribe(&workspace_handle, {
- move |workspace, _, event, cx| {
- if let workspace::Event::PaneAdded(pane) = event {
- pane.update(cx, |pane, cx| {
- pane.toolbar().update(cx, |toolbar, cx| {
- // todo!()
- // let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
- // toolbar.add_item(breadcrumbs, cx);
- // let buffer_search_bar = cx.add_view(BufferSearchBar::new);
- // toolbar.add_item(buffer_search_bar.clone(), cx);
- // let quick_action_bar = cx.add_view(|_| {
- // QuickActionBar::new(buffer_search_bar, workspace)
- // });
- // toolbar.add_item(quick_action_bar, cx);
- // let diagnostic_editor_controls =
- // cx.add_view(|_| diagnostics2::ToolbarControls::new());
- // toolbar.add_item(diagnostic_editor_controls, cx);
- // let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
- // toolbar.add_item(project_search_bar, cx);
- // let submit_feedback_button =
- // cx.add_view(|_| SubmitFeedbackButton::new());
- // toolbar.add_item(submit_feedback_button, cx);
- // let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
- // toolbar.add_item(feedback_info_text, cx);
- // let lsp_log_item =
- // cx.add_view(|_| language_tools::LspLogToolbarItemView::new());
- // toolbar.add_item(lsp_log_item, cx);
- // let syntax_tree_item = cx
- // .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
- // toolbar.add_item(syntax_tree_item, cx);
- })
- });
- }
- }
- })
- .detach();
-
- // cx.emit(workspace2::Event::PaneAdded(
- // workspace.active_pane().clone(),
- // ));
-
- // let copilot =
- // cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
- // let diagnostic_summary =
- // cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
- // let activity_indicator = activity_indicator::ActivityIndicator::new(
- // workspace,
- // app_state.languages.clone(),
- // cx,
- // );
- // let active_buffer_language =
- // cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
- // let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
- // let feedback_button = cx.add_view(|_| {
- // feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
- // });
- // let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
- workspace.status_bar().update(cx, |status_bar, cx| {
- // status_bar.add_left_item(diagnostic_summary, cx);
- // status_bar.add_left_item(activity_indicator, cx);
-
- // status_bar.add_right_item(feedback_button, cx);
- // status_bar.add_right_item(copilot, cx);
- // status_bar.add_right_item(active_buffer_language, cx);
- // status_bar.add_right_item(vim_mode_indicator, cx);
- // status_bar.add_right_item(cursor_position, cx);
- });
-
- // auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
-
- // vim::observe_keystrokes(cx);
-
- // cx.on_window_should_close(|workspace, cx| {
- // if let Some(task) = workspace.close(&Default::default(), cx) {
- // task.detach_and_log_err(cx);
- // }
- // false
- // });
- })?;
-
- let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
- // let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
- // let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
- let channels_panel =
- collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
- // let chat_panel =
- // collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
- // let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
- // workspace_handle.clone(),
- // cx.clone(),
- // );
- let (
- project_panel,
- // terminal_panel,
- // assistant_panel,
- channels_panel,
- // chat_panel,
- // notification_panel,
- ) = futures::try_join!(
- project_panel,
- // terminal_panel,
- // assistant_panel,
- channels_panel,
- // chat_panel,
- // notification_panel,/
- )?;
-
- workspace_handle.update(&mut cx, |workspace, cx| {
- let project_panel_position = project_panel.position(cx);
- workspace.add_panel(project_panel, cx);
- // workspace.add_panel(terminal_panel, cx);
- // workspace.add_panel(assistant_panel, cx);
- workspace.add_panel(channels_panel, cx);
- // workspace.add_panel(chat_panel, cx);
- // workspace.add_panel(notification_panel, cx);
-
- // if !was_deserialized
- // && workspace
- // .project()
- // .read(cx)
- // .visible_worktrees(cx)
- // .any(|tree| {
- // tree.read(cx)
- // .root_entry()
- // .map_or(false, |entry| entry.is_dir())
- // })
- // {
- workspace.toggle_dock(project_panel_position, cx);
- // }
- // cx.focus_self();
- })?;
- Ok(())
- })
-}
-
fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
let app_name = cx.global::<ReleaseChannel>().display_name();
let version = env!("CARGO_PKG_VERSION");