diff --git a/Cargo.lock b/Cargo.lock index 17d19258e4..ea80c92376 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4232,7 +4232,7 @@ dependencies = [ "settings2", "shellexpand", "util", - "workspace", + "workspace2", ] [[package]] diff --git a/crates/journal2/Cargo.toml b/crates/journal2/Cargo.toml index f43d90fc85..72da3deb69 100644 --- a/crates/journal2/Cargo.toml +++ b/crates/journal2/Cargo.toml @@ -12,7 +12,7 @@ doctest = false editor = { path = "../editor" } gpui = { package = "gpui2", path = "../gpui2" } util = { path = "../util" } -workspace = { path = "../workspace" } +workspace2 = { path = "../workspace2" } settings2 = { path = "../settings2" } anyhow.workspace = true diff --git a/crates/journal2/src/journal2.rs b/crates/journal2/src/journal2.rs index fa6e05cca7..20d520e36e 100644 --- a/crates/journal2/src/journal2.rs +++ b/crates/journal2/src/journal2.rs @@ -9,7 +9,7 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use workspace::AppState; +use workspace2::AppState; // use zed::AppState; // todo!(); @@ -59,7 +59,7 @@ pub fn init(_: Arc, cx: &mut AppContext) { // cx.add_global_action(move |_: &NewJournalEntry, cx| new_journal_entry(app_state.clone(), cx)); } -pub fn new_journal_entry(_: Arc, cx: &mut AppContext) { +pub fn new_journal_entry(app_state: Arc, cx: &mut AppContext) { let settings = JournalSettings::get_global(cx); let journal_dir = match journal_dir(settings.path.as_ref().unwrap()) { Some(journal_dir) => journal_dir, @@ -77,7 +77,7 @@ pub fn new_journal_entry(_: Arc, cx: &mut AppContext) { let now = now.time(); let _entry_heading = heading_entry(now, &settings.hour_format); - let _create_entry = cx.background_executor().spawn(async move { + let create_entry = cx.background_executor().spawn(async move { std::fs::create_dir_all(month_dir)?; OpenOptions::new() .create(true) @@ -86,37 +86,38 @@ pub fn new_journal_entry(_: Arc, cx: &mut AppContext) { Ok::<_, std::io::Error>((journal_dir, entry_path)) }); - // todo!("workspace") - // cx.spawn(|cx| async move { - // let (journal_dir, entry_path) = create_entry.await?; - // let (workspace, _) = - // cx.update(|cx| workspace::open_paths(&[journal_dir], &app_state, None, cx))?; + cx.spawn(|mut cx| async move { + let (journal_dir, entry_path) = create_entry.await?; + let (workspace, _) = cx + .update(|cx| workspace2::open_paths(&[journal_dir], &app_state, None, cx))? + .await?; - // let opened = workspace - // .update(&mut cx, |workspace, cx| { - // workspace.open_paths(vec![entry_path], true, cx) - // })? - // .await; + let _opened = workspace + .update(&mut cx, |workspace, cx| { + workspace.open_paths(vec![entry_path], true, cx) + })? + .await; - // if let Some(Some(Ok(item))) = opened.first() { - // if let Some(editor) = item.downcast::().map(|editor| editor.downgrade()) { - // editor.update(&mut cx, |editor, cx| { - // let len = editor.buffer().read(cx).len(cx); - // editor.change_selections(Some(Autoscroll::center()), cx, |s| { - // s.select_ranges([len..len]) - // }); - // if len > 0 { - // editor.insert("\n\n", cx); - // } - // editor.insert(&entry_heading, cx); - // editor.insert("\n\n", cx); - // })?; - // } - // } + // todo!("editor") + // if let Some(Some(Ok(item))) = opened.first() { + // if let Some(editor) = item.downcast::().map(|editor| editor.downgrade()) { + // editor.update(&mut cx, |editor, cx| { + // let len = editor.buffer().read(cx).len(cx); + // editor.change_selections(Some(Autoscroll::center()), cx, |s| { + // s.select_ranges([len..len]) + // }); + // if len > 0 { + // editor.insert("\n\n", cx); + // } + // editor.insert(&entry_heading, cx); + // editor.insert("\n\n", cx); + // })?; + // } + // } - // anyhow::Ok(()) - // }) - // .detach_and_log_err(cx); + anyhow::Ok(()) + }) + .detach_and_log_err(cx); } fn journal_dir(path: &str) -> Option { diff --git a/crates/language2/src/syntax_map.rs b/crates/language2/src/syntax_map.rs index 4abb9afe7e..18f2e9b264 100644 --- a/crates/language2/src/syntax_map.rs +++ b/crates/language2/src/syntax_map.rs @@ -234,7 +234,6 @@ impl SyntaxMap { self.snapshot.interpolate(text); } - #[allow(dead_code)] // todo!() #[cfg(test)] pub fn reparse(&mut self, language: Arc, text: &BufferSnapshot) { self.snapshot @@ -786,7 +785,6 @@ impl SyntaxSnapshot { ) } - #[allow(dead_code)] // todo!() #[cfg(test)] pub fn layers<'a>(&'a self, buffer: &'a BufferSnapshot) -> Vec { self.layers_for_range(0..buffer.len(), buffer).collect() diff --git a/crates/semantic_index/src/semantic_index_tests.rs b/crates/semantic_index/src/semantic_index_tests.rs index 044ded2682..2145d1f9e0 100644 --- a/crates/semantic_index/src/semantic_index_tests.rs +++ b/crates/semantic_index/src/semantic_index_tests.rs @@ -289,12 +289,12 @@ async fn test_code_context_retrieval_rust() { impl E { // This is also a preceding comment pub fn function_1() -> Option<()> { - todo!(); + unimplemented!(); } // This is a preceding comment fn function_2() -> Result<()> { - todo!(); + unimplemented!(); } } @@ -344,7 +344,7 @@ async fn test_code_context_retrieval_rust() { " // This is also a preceding comment pub fn function_1() -> Option<()> { - todo!(); + unimplemented!(); }" .unindent(), text.find("pub fn function_1").unwrap(), @@ -353,7 +353,7 @@ async fn test_code_context_retrieval_rust() { " // This is a preceding comment fn function_2() -> Result<()> { - todo!(); + unimplemented!(); }" .unindent(), text.find("fn function_2").unwrap(), diff --git a/crates/workspace2/Cargo.toml b/crates/workspace2/Cargo.toml index 5072f2b8f9..f3f10d2015 100644 --- a/crates/workspace2/Cargo.toml +++ b/crates/workspace2/Cargo.toml @@ -14,7 +14,7 @@ test-support = [ "client2/test-support", "project2/test-support", "settings2/test-support", - "gpui2/test-support", + "gpui/test-support", "fs2/test-support" ] @@ -25,7 +25,7 @@ client2 = { path = "../client2" } collections = { path = "../collections" } # context_menu = { path = "../context_menu" } fs2 = { path = "../fs2" } -gpui2 = { path = "../gpui2" } +gpui = { package = "gpui2", path = "../gpui2" } install_cli2 = { path = "../install_cli2" } language2 = { path = "../language2" } #menu = { path = "../menu" } @@ -56,7 +56,7 @@ uuid.workspace = true [dev-dependencies] call2 = { path = "../call2", features = ["test-support"] } client2 = { path = "../client2", features = ["test-support"] } -gpui2 = { path = "../gpui2", features = ["test-support"] } +gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] } project2 = { path = "../project2", features = ["test-support"] } settings2 = { path = "../settings2", features = ["test-support"] } fs2 = { path = "../fs2", features = ["test-support"] } diff --git a/crates/workspace2/src/dock.rs b/crates/workspace2/src/dock.rs index 9da9123a2f..e6b6c7561d 100644 --- a/crates/workspace2/src/dock.rs +++ b/crates/workspace2/src/dock.rs @@ -1,5 +1,5 @@ use crate::{status_bar::StatusItemView, Axis, Workspace}; -use gpui2::{ +use gpui::{ div, Action, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, ParentElement, Render, Subscription, View, ViewContext, WeakView, WindowContext, }; @@ -226,9 +226,9 @@ impl Dock { // }) } - // pub fn active_panel_index(&self) -> usize { - // self.active_panel_index - // } + pub fn active_panel_index(&self) -> usize { + self.active_panel_index + } pub(crate) fn set_open(&mut self, open: bool, cx: &mut ViewContext) { if open != self.is_open { @@ -241,84 +241,87 @@ impl Dock { } } - // pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext) { - // for entry in &mut self.panel_entries { - // if entry.panel.as_any() == panel { - // if zoomed != entry.panel.is_zoomed(cx) { - // entry.panel.set_zoomed(zoomed, cx); - // } - // } else if entry.panel.is_zoomed(cx) { - // entry.panel.set_zoomed(false, cx); - // } - // } - - // cx.notify(); - // } - - // pub fn zoom_out(&mut self, cx: &mut ViewContext) { - // for entry in &mut self.panel_entries { - // if entry.panel.is_zoomed(cx) { - // entry.panel.set_zoomed(false, cx); + // todo!() + // pub fn set_panel_zoomed(&mut self, panel: &AnyView, zoomed: bool, cx: &mut ViewContext) { + // for entry in &mut self.panel_entries { + // if entry.panel.as_any() == panel { + // if zoomed != entry.panel.is_zoomed(cx) { + // entry.panel.set_zoomed(zoomed, cx); // } + // } else if entry.panel.is_zoomed(cx) { + // entry.panel.set_zoomed(false, cx); // } // } - // pub(crate) fn add_panel(&mut self, panel: View, cx: &mut ViewContext) { - // let subscriptions = [ - // cx.observe(&panel, |_, _, cx| cx.notify()), - // cx.subscribe(&panel, |this, panel, event, cx| { - // if T::should_activate_on_event(event) { - // if let Some(ix) = this - // .panel_entries - // .iter() - // .position(|entry| entry.panel.id() == panel.id()) - // { - // this.set_open(true, cx); - // this.activate_panel(ix, cx); - // cx.focus(&panel); - // } - // } else if T::should_close_on_event(event) - // && this.visible_panel().map_or(false, |p| p.id() == panel.id()) - // { - // this.set_open(false, cx); - // } - // }), - // ]; + // cx.notify(); + // } - // let dock_view_id = cx.view_id(); - // self.panel_entries.push(PanelEntry { - // panel: Arc::new(panel), - // // todo!() - // // context_menu: cx.add_view(|cx| { - // // let mut menu = ContextMenu::new(dock_view_id, cx); - // // menu.set_position_mode(OverlayPositionMode::Local); - // // menu - // // }), - // _subscriptions: subscriptions, - // }); - // cx.notify() - // } + pub fn zoom_out(&mut self, cx: &mut ViewContext) { + for entry in &mut self.panel_entries { + if entry.panel.is_zoomed(cx) { + entry.panel.set_zoomed(false, cx); + } + } + } - // pub fn remove_panel(&mut self, panel: &View, cx: &mut ViewContext) { - // if let Some(panel_ix) = self - // .panel_entries - // .iter() - // .position(|entry| entry.panel.id() == panel.id()) - // { - // if panel_ix == self.active_panel_index { - // self.active_panel_index = 0; - // self.set_open(false, cx); - // } else if panel_ix < self.active_panel_index { - // self.active_panel_index -= 1; - // } - // self.panel_entries.remove(panel_ix); - // cx.notify(); - // } - // } + pub(crate) fn add_panel(&mut self, panel: View, cx: &mut ViewContext) { + let subscriptions = [ + cx.observe(&panel, |_, _, cx| cx.notify()), + cx.subscribe(&panel, |this, panel, event, cx| { + if T::should_activate_on_event(event) { + if let Some(ix) = this + .panel_entries + .iter() + .position(|entry| entry.panel.id() == panel.id()) + { + this.set_open(true, cx); + this.activate_panel(ix, cx); + // todo!() + // cx.focus(&panel); + } + } else if T::should_close_on_event(event) + && this.visible_panel().map_or(false, |p| p.id() == panel.id()) + { + this.set_open(false, cx); + } + }), + ]; - // pub fn panels_len(&self) -> usize { - // self.panel_entries.len() - // } + // todo!() + // let dock_view_id = cx.view_id(); + self.panel_entries.push(PanelEntry { + panel: Arc::new(panel), + // todo!() + // context_menu: cx.add_view(|cx| { + // let mut menu = ContextMenu::new(dock_view_id, cx); + // menu.set_position_mode(OverlayPositionMode::Local); + // menu + // }), + _subscriptions: subscriptions, + }); + cx.notify() + } + + pub fn remove_panel(&mut self, panel: &View, cx: &mut ViewContext) { + if let Some(panel_ix) = self + .panel_entries + .iter() + .position(|entry| entry.panel.id() == panel.id()) + { + if panel_ix == self.active_panel_index { + self.active_panel_index = 0; + self.set_open(false, cx); + } else if panel_ix < self.active_panel_index { + self.active_panel_index -= 1; + } + self.panel_entries.remove(panel_ix); + cx.notify(); + } + } + + pub fn panels_len(&self) -> usize { + self.panel_entries.len() + } pub fn activate_panel(&mut self, panel_ix: usize, cx: &mut ViewContext) { if panel_ix != self.active_panel_index { @@ -352,38 +355,38 @@ impl Dock { } } - // pub fn zoomed_panel(&self, cx: &WindowContext) -> Option> { - // let entry = self.visible_entry()?; - // if entry.panel.is_zoomed(cx) { - // Some(entry.panel.clone()) - // } else { - // None - // } - // } + pub fn zoomed_panel(&self, cx: &WindowContext) -> Option> { + let entry = self.visible_entry()?; + if entry.panel.is_zoomed(cx) { + Some(entry.panel.clone()) + } else { + None + } + } - // pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { - // self.panel_entries - // .iter() - // .find(|entry| entry.panel.id() == panel.id()) - // .map(|entry| entry.panel.size(cx)) - // } + pub fn panel_size(&self, panel: &dyn PanelHandle, cx: &WindowContext) -> Option { + self.panel_entries + .iter() + .find(|entry| entry.panel.id() == panel.id()) + .map(|entry| entry.panel.size(cx)) + } - // pub fn active_panel_size(&self, cx: &WindowContext) -> Option { - // if self.is_open { - // self.panel_entries - // .get(self.active_panel_index) - // .map(|entry| entry.panel.size(cx)) - // } else { - // None - // } - // } + pub fn active_panel_size(&self, cx: &WindowContext) -> Option { + if self.is_open { + self.panel_entries + .get(self.active_panel_index) + .map(|entry| entry.panel.size(cx)) + } else { + None + } + } - // pub fn resize_active_panel(&mut self, size: Option, cx: &mut ViewContext) { - // if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) { - // entry.panel.set_size(size, cx); - // cx.notify(); - // } - // } + pub fn resize_active_panel(&mut self, size: Option, cx: &mut ViewContext) { + if let Some(entry) = self.panel_entries.get_mut(self.active_panel_index) { + entry.panel.set_size(size, cx); + cx.notify(); + } + } // pub fn render_placeholder(&self, cx: &WindowContext) -> AnyElement { // todo!() @@ -629,7 +632,7 @@ impl StatusItemView for PanelButtons { #[cfg(any(test, feature = "test-support"))] pub mod test { use super::*; - use gpui2::{div, Div, ViewContext, WindowContext}; + use gpui::{div, Div, ViewContext, WindowContext}; #[derive(Debug)] pub enum TestPanelEvent { @@ -678,7 +681,7 @@ pub mod test { "TestPanel" } - fn position(&self, _: &gpui2::WindowContext) -> super::DockPosition { + fn position(&self, _: &gpui::WindowContext) -> super::DockPosition { self.position } diff --git a/crates/workspace2/src/item.rs b/crates/workspace2/src/item.rs index c2d5c25781..15b387cbed 100644 --- a/crates/workspace2/src/item.rs +++ b/crates/workspace2/src/item.rs @@ -11,7 +11,7 @@ use client2::{ proto::{self, PeerId}, Client, }; -use gpui2::{ +use gpui::{ AnyElement, AnyView, AppContext, Entity, EntityId, EventEmitter, HighlightStyle, Model, Pixels, Point, Render, SharedString, Task, View, ViewContext, WeakView, WindowContext, }; @@ -212,7 +212,7 @@ pub trait ItemHandle: 'static + Send { &self, cx: &mut WindowContext, handler: Box, - ) -> gpui2::Subscription; + ) -> gpui::Subscription; fn tab_tooltip_text(&self, cx: &AppContext) -> Option; fn tab_description(&self, detail: usize, cx: &AppContext) -> Option; fn tab_content(&self, detail: Option, cx: &AppContext) -> AnyElement; @@ -256,7 +256,7 @@ pub trait ItemHandle: 'static + Send { &mut self, cx: &mut AppContext, callback: Box, - ) -> gpui2::Subscription; + ) -> gpui::Subscription; fn to_searchable_item_handle(&self, cx: &AppContext) -> Option>; fn breadcrumb_location(&self, cx: &AppContext) -> ToolbarItemLocation; fn breadcrumbs(&self, theme: &ThemeVariant, cx: &AppContext) -> Option>; @@ -286,7 +286,7 @@ impl ItemHandle for View { &self, cx: &mut WindowContext, handler: Box, - ) -> gpui2::Subscription { + ) -> gpui::Subscription { cx.subscribe(self, move |_, event, cx| { for item_event in T::to_item_events(event) { handler(item_event, cx) @@ -573,7 +573,7 @@ impl ItemHandle for View { &mut self, cx: &mut AppContext, callback: Box, - ) -> gpui2::Subscription { + ) -> gpui::Subscription { cx.observe_release(self, move |_, cx| callback(cx)) } @@ -747,7 +747,7 @@ impl FollowableItemHandle for View { // pub mod test { // use super::{Item, ItemEvent}; // use crate::{ItemId, ItemNavHistory, Pane, Workspace, WorkspaceId}; -// use gpui2::{ +// use gpui::{ // elements::Empty, AnyElement, AppContext, Element, Entity, Model, Task, View, // ViewContext, View, WeakViewHandle, // }; diff --git a/crates/workspace2/src/notifications.rs b/crates/workspace2/src/notifications.rs index 9922bcdd26..5dd5b2c7ae 100644 --- a/crates/workspace2/src/notifications.rs +++ b/crates/workspace2/src/notifications.rs @@ -1,6 +1,6 @@ use crate::{Toast, Workspace}; use collections::HashMap; -use gpui2::{AnyView, AppContext, Entity, EntityId, EventEmitter, Render, View, ViewContext}; +use gpui::{AnyView, AppContext, Entity, EntityId, EventEmitter, Render, View, ViewContext}; use std::{any::TypeId, ops::DerefMut}; pub fn init(cx: &mut AppContext) { @@ -160,7 +160,7 @@ impl Workspace { pub mod simple_message_notification { use super::Notification; - use gpui2::{AnyElement, AppContext, Div, EventEmitter, Render, TextStyle, ViewContext}; + use gpui::{AnyElement, AppContext, Div, EventEmitter, Render, TextStyle, ViewContext}; use serde::Deserialize; use std::{borrow::Cow, sync::Arc}; @@ -220,36 +220,36 @@ pub mod simple_message_notification { } } + pub fn new_element( + message: fn(TextStyle, &AppContext) -> AnyElement, + ) -> MessageNotification { + Self { + message: NotificationMessage::Element(message), + on_click: None, + click_message: None, + } + } + + pub fn with_click_message(mut self, message: S) -> Self + where + S: Into>, + { + self.click_message = Some(message.into()); + self + } + + pub fn on_click(mut self, on_click: F) -> Self + where + F: 'static + Send + Sync + Fn(&mut ViewContext), + { + self.on_click = Some(Arc::new(on_click)); + self + } + // todo!() - // pub fn new_element( - // message: fn(TextStyle, &AppContext) -> AnyElement, - // ) -> MessageNotification { - // Self { - // message: NotificationMessage::Element(message), - // on_click: None, - // click_message: None, - // } - // } - - // pub fn with_click_message(mut self, message: S) -> Self - // where - // S: Into>, - // { - // self.click_message = Some(message.into()); - // self - // } - - // pub fn on_click(mut self, on_click: F) -> Self - // where - // F: 'static + Fn(&mut ViewContext), - // { - // self.on_click = Some(Arc::new(on_click)); - // self - // } - - // pub fn dismiss(&mut self, _: &CancelMessageNotification, cx: &mut ViewContext) { - // cx.emit(MessageNotificationEvent::Dismiss); - // } + // pub fn dismiss(&mut self, _: &CancelMessageNotification, cx: &mut ViewContext) { + // cx.emit(MessageNotificationEvent::Dismiss); + // } } impl Render for MessageNotification { @@ -265,7 +265,7 @@ pub mod simple_message_notification { // "MessageNotification" // } - // fn render(&mut self, cx: &mut gpui2::ViewContext) -> gpui::AnyElement { + // fn render(&mut self, cx: &mut gpui::ViewContext) -> gpui::AnyElement { // let theme = theme2::current(cx).clone(); // let theme = &theme.simple_message_notification; diff --git a/crates/workspace2/src/pane.rs b/crates/workspace2/src/pane.rs index b30ec0b7f8..16dbfda361 100644 --- a/crates/workspace2/src/pane.rs +++ b/crates/workspace2/src/pane.rs @@ -8,7 +8,7 @@ use crate::{ }; use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; -use gpui2::{ +use gpui::{ AppContext, AsyncWindowContext, Component, Div, EntityId, EventEmitter, Model, PromptLevel, Render, Task, View, ViewContext, VisualContext, WeakView, WindowContext, }; @@ -416,17 +416,17 @@ impl Pane { } } - // pub(crate) fn workspace(&self) -> &WeakView { - // &self.workspace - // } + pub(crate) fn workspace(&self) -> &WeakView { + &self.workspace + } pub fn has_focus(&self) -> bool { self.has_focus } - // pub fn active_item_index(&self) -> usize { - // self.active_item_index - // } + pub fn active_item_index(&self) -> usize { + self.active_item_index + } // pub fn on_can_drop(&mut self, can_drop: F) // where @@ -1865,14 +1865,14 @@ impl Pane { // .into_any() // } - // pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext) { - // self.zoomed = zoomed; - // cx.notify(); - // } + pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext) { + self.zoomed = zoomed; + cx.notify(); + } - // pub fn is_zoomed(&self) -> bool { - // self.zoomed - // } + pub fn is_zoomed(&self) -> bool { + self.zoomed + } } // impl Entity for Pane { @@ -2907,6 +2907,6 @@ impl Render for DraggedTab { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Self::Element { - div().w_8().h_4().bg(gpui2::red()) + div().w_8().h_4().bg(gpui::red()) } } diff --git a/crates/workspace2/src/pane/dragged_item_receiver.rs b/crates/workspace2/src/pane/dragged_item_receiver.rs index 292529e787..d8e967dd75 100644 --- a/crates/workspace2/src/pane/dragged_item_receiver.rs +++ b/crates/workspace2/src/pane/dragged_item_receiver.rs @@ -1,6 +1,6 @@ use super::DraggedItem; use crate::{Pane, SplitDirection, Workspace}; -use gpui2::{ +use gpui::{ color::Color, elements::{Canvas, MouseEventHandler, ParentElement, Stack}, geometry::{rect::RectF, vector::Vector2F}, diff --git a/crates/workspace2/src/pane_group.rs b/crates/workspace2/src/pane_group.rs index e521c51bda..441aef21f5 100644 --- a/crates/workspace2/src/pane_group.rs +++ b/crates/workspace2/src/pane_group.rs @@ -6,9 +6,7 @@ use db2::sqlez::{ bindable::{Bind, Column, StaticColumnCount}, statement::Statement, }; -use gpui2::{ - point, size, AnyElement, AnyWeakView, Bounds, Model, Pixels, Point, View, ViewContext, -}; +use gpui::{point, size, AnyElement, AnyWeakView, Bounds, Model, Pixels, Point, View, ViewContext}; use parking_lot::Mutex; use project2::Project; use serde::Deserialize; diff --git a/crates/workspace2/src/persistence.rs b/crates/workspace2/src/persistence.rs index 435518271d..9790495087 100644 --- a/crates/workspace2/src/persistence.rs +++ b/crates/workspace2/src/persistence.rs @@ -6,7 +6,7 @@ use std::path::Path; use anyhow::{anyhow, bail, Context, Result}; use db2::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql}; -use gpui2::WindowBounds; +use gpui::WindowBounds; use util::{unzip_option, ResultExt}; use uuid::Uuid; @@ -549,425 +549,425 @@ impl WorkspaceDb { } } -// todo!() -// #[cfg(test)] -// mod tests { -// use super::*; -// use db::open_test_db; +#[cfg(test)] +mod tests { + use super::*; + use db2::open_test_db; + use gpui; -// #[gpui::test] -// async fn test_next_id_stability() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_next_id_stability() { + 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| { -// conn.migrate( -// "test_table", -// &[sql!( -// CREATE TABLE test_table( -// text TEXT, -// workspace_id INTEGER, -// FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) -// ON DELETE CASCADE -// ) STRICT; -// )], -// ) -// .unwrap(); -// }) -// .await; + db.write(|conn| { + conn.migrate( + "test_table", + &[sql!( + CREATE TABLE test_table( + text TEXT, + workspace_id INTEGER, + FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) + ON DELETE CASCADE + ) STRICT; + )], + ) + .unwrap(); + }) + .await; -// let id = db.next_id().await.unwrap(); -// // Assert the empty row got inserted -// assert_eq!( -// Some(id), -// db.select_row_bound::(sql!( -// SELECT workspace_id FROM workspaces WHERE workspace_id = ? -// )) -// .unwrap()(id) -// .unwrap() -// ); + let id = db.next_id().await.unwrap(); + // Assert the empty row got inserted + assert_eq!( + Some(id), + db.select_row_bound::(sql!( + SELECT workspace_id FROM workspaces WHERE workspace_id = ? + )) + .unwrap()(id) + .unwrap() + ); -// db.write(move |conn| { -// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) -// .unwrap()(("test-text-1", id)) -// .unwrap() -// }) -// .await; + db.write(move |conn| { + conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) + .unwrap()(("test-text-1", id)) + .unwrap() + }) + .await; -// let test_text_1 = db -// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) -// .unwrap()(1) -// .unwrap() -// .unwrap(); -// assert_eq!(test_text_1, "test-text-1"); -// } + let test_text_1 = db + .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) + .unwrap()(1) + .unwrap() + .unwrap(); + assert_eq!(test_text_1, "test-text-1"); + } -// #[gpui::test] -// async fn test_workspace_id_stability() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_workspace_id_stability() { + 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| { -// conn.migrate( -// "test_table", -// &[sql!( -// CREATE TABLE test_table( -// text TEXT, -// workspace_id INTEGER, -// FOREIGN KEY(workspace_id) -// REFERENCES workspaces(workspace_id) -// ON DELETE CASCADE -// ) STRICT;)], -// ) -// }) -// .await -// .unwrap(); + db.write(|conn| { + conn.migrate( + "test_table", + &[sql!( + CREATE TABLE test_table( + text TEXT, + workspace_id INTEGER, + FOREIGN KEY(workspace_id) + REFERENCES workspaces(workspace_id) + ON DELETE CASCADE + ) STRICT;)], + ) + }) + .await + .unwrap(); -// let mut workspace_1 = SerializedWorkspace { -// id: 1, -// location: (["/tmp", "/tmp2"]).into(), -// center_group: Default::default(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + let mut workspace_1 = SerializedWorkspace { + id: 1, + location: (["/tmp", "/tmp2"]).into(), + center_group: Default::default(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// let workspace_2 = SerializedWorkspace { -// id: 2, -// location: (["/tmp"]).into(), -// center_group: Default::default(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + let workspace_2 = SerializedWorkspace { + id: 2, + location: (["/tmp"]).into(), + center_group: Default::default(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// db.save_workspace(workspace_1.clone()).await; + db.save_workspace(workspace_1.clone()).await; -// db.write(|conn| { -// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) -// .unwrap()(("test-text-1", 1)) -// .unwrap(); -// }) -// .await; + db.write(|conn| { + conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) + .unwrap()(("test-text-1", 1)) + .unwrap(); + }) + .await; -// db.save_workspace(workspace_2.clone()).await; + db.save_workspace(workspace_2.clone()).await; -// db.write(|conn| { -// conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) -// .unwrap()(("test-text-2", 2)) -// .unwrap(); -// }) -// .await; + db.write(|conn| { + conn.exec_bound(sql!(INSERT INTO test_table(text, workspace_id) VALUES (?, ?))) + .unwrap()(("test-text-2", 2)) + .unwrap(); + }) + .await; -// workspace_1.location = (["/tmp", "/tmp3"]).into(); -// db.save_workspace(workspace_1.clone()).await; -// db.save_workspace(workspace_1).await; -// db.save_workspace(workspace_2).await; + workspace_1.location = (["/tmp", "/tmp3"]).into(); + db.save_workspace(workspace_1.clone()).await; + db.save_workspace(workspace_1).await; + db.save_workspace(workspace_2).await; -// let test_text_2 = db -// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) -// .unwrap()(2) -// .unwrap() -// .unwrap(); -// assert_eq!(test_text_2, "test-text-2"); + let test_text_2 = db + .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) + .unwrap()(2) + .unwrap() + .unwrap(); + assert_eq!(test_text_2, "test-text-2"); -// let test_text_1 = db -// .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) -// .unwrap()(1) -// .unwrap() -// .unwrap(); -// assert_eq!(test_text_1, "test-text-1"); -// } + let test_text_1 = db + .select_row_bound::<_, String>(sql!(SELECT text FROM test_table WHERE workspace_id = ?)) + .unwrap()(1) + .unwrap() + .unwrap(); + assert_eq!(test_text_1, "test-text-1"); + } -// fn group(axis: gpui::Axis, children: Vec) -> SerializedPaneGroup { -// SerializedPaneGroup::Group { -// axis, -// flexes: None, -// children, -// } -// } + fn group(axis: Axis, children: Vec) -> SerializedPaneGroup { + SerializedPaneGroup::Group { + axis, + flexes: None, + children, + } + } -// #[gpui::test] -// async fn test_full_workspace_serialization() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_full_workspace_serialization() { + 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 | -// // | - - - | | -// // | 3,4 | | -// // ----------------- -// let center_group = group( -// gpui::Axis::Horizontal, -// vec![ -// group( -// gpui::Axis::Vertical, -// vec![ -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 5, false), -// SerializedItem::new("Terminal", 6, true), -// ], -// false, -// )), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 7, true), -// SerializedItem::new("Terminal", 8, false), -// ], -// false, -// )), -// ], -// ), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 9, false), -// SerializedItem::new("Terminal", 10, true), -// ], -// false, -// )), -// ], -// ); + // ----------------- + // | 1,2 | 5,6 | + // | - - - | | + // | 3,4 | | + // ----------------- + let center_group = group( + Axis::Horizontal, + vec![ + group( + Axis::Vertical, + vec![ + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 5, false), + SerializedItem::new("Terminal", 6, true), + ], + false, + )), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 7, true), + SerializedItem::new("Terminal", 8, false), + ], + false, + )), + ], + ), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 9, false), + SerializedItem::new("Terminal", 10, true), + ], + false, + )), + ], + ); -// let workspace = SerializedWorkspace { -// id: 5, -// location: (["/tmp", "/tmp2"]).into(), -// center_group, -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + let workspace = SerializedWorkspace { + id: 5, + location: (["/tmp", "/tmp2"]).into(), + center_group, + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// db.save_workspace(workspace.clone()).await; -// let round_trip_workspace = db.workspace_for_roots(&["/tmp2", "/tmp"]); + db.save_workspace(workspace.clone()).await; + 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 -// db.save_workspace(workspace.clone()).await; -// db.save_workspace(workspace.clone()).await; + // Test guaranteed duplicate IDs + db.save_workspace(workspace.clone()).await; + db.save_workspace(workspace.clone()).await; -// let round_trip_workspace = db.workspace_for_roots(&["/tmp", "/tmp2"]); -// assert_eq!(workspace, round_trip_workspace.unwrap()); -// } + let round_trip_workspace = db.workspace_for_roots(&["/tmp", "/tmp2"]); + assert_eq!(workspace, round_trip_workspace.unwrap()); + } -// #[gpui::test] -// async fn test_workspace_assignment() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_workspace_assignment() { + 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 { -// id: 1, -// location: (["/tmp", "/tmp2"]).into(), -// center_group: Default::default(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + let workspace_1 = SerializedWorkspace { + id: 1, + location: (["/tmp", "/tmp2"]).into(), + center_group: Default::default(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// let mut workspace_2 = SerializedWorkspace { -// id: 2, -// location: (["/tmp"]).into(), -// center_group: Default::default(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + let mut workspace_2 = SerializedWorkspace { + id: 2, + location: (["/tmp"]).into(), + center_group: Default::default(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// db.save_workspace(workspace_1.clone()).await; -// db.save_workspace(workspace_2.clone()).await; + db.save_workspace(workspace_1.clone()).await; + db.save_workspace(workspace_2.clone()).await; -// // Test that paths are treated as a set -// assert_eq!( -// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), -// workspace_1 -// ); -// assert_eq!( -// db.workspace_for_roots(&["/tmp2", "/tmp"]).unwrap(), -// workspace_1 -// ); + // Test that paths are treated as a set + assert_eq!( + db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), + workspace_1 + ); + assert_eq!( + db.workspace_for_roots(&["/tmp2", "/tmp"]).unwrap(), + workspace_1 + ); -// // Make sure that other keys work -// assert_eq!(db.workspace_for_roots(&["/tmp"]).unwrap(), workspace_2); -// assert_eq!(db.workspace_for_roots(&["/tmp3", "/tmp2", "/tmp4"]), None); + // Make sure that other keys work + assert_eq!(db.workspace_for_roots(&["/tmp"]).unwrap(), workspace_2); + assert_eq!(db.workspace_for_roots(&["/tmp3", "/tmp2", "/tmp4"]), None); -// // Test 'mutate' case of updating a pre-existing id -// workspace_2.location = (["/tmp", "/tmp2"]).into(); + // Test 'mutate' case of updating a pre-existing id + workspace_2.location = (["/tmp", "/tmp2"]).into(); -// db.save_workspace(workspace_2.clone()).await; -// assert_eq!( -// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), -// workspace_2 -// ); + db.save_workspace(workspace_2.clone()).await; + assert_eq!( + db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), + workspace_2 + ); -// // Test other mechanism for mutating -// let mut workspace_3 = SerializedWorkspace { -// id: 3, -// location: (&["/tmp", "/tmp2"]).into(), -// center_group: Default::default(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// }; + // Test other mechanism for mutating + let mut workspace_3 = SerializedWorkspace { + id: 3, + location: (&["/tmp", "/tmp2"]).into(), + center_group: Default::default(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + }; -// db.save_workspace(workspace_3.clone()).await; -// assert_eq!( -// db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), -// workspace_3 -// ); + db.save_workspace(workspace_3.clone()).await; + assert_eq!( + db.workspace_for_roots(&["/tmp", "/tmp2"]).unwrap(), + workspace_3 + ); -// // Make sure that updating paths differently also works -// workspace_3.location = (["/tmp3", "/tmp4", "/tmp2"]).into(); -// db.save_workspace(workspace_3.clone()).await; -// assert_eq!(db.workspace_for_roots(&["/tmp2", "tmp"]), None); -// assert_eq!( -// db.workspace_for_roots(&["/tmp2", "/tmp3", "/tmp4"]) -// .unwrap(), -// workspace_3 -// ); -// } + // Make sure that updating paths differently also works + workspace_3.location = (["/tmp3", "/tmp4", "/tmp2"]).into(); + db.save_workspace(workspace_3.clone()).await; + assert_eq!(db.workspace_for_roots(&["/tmp2", "tmp"]), None); + assert_eq!( + db.workspace_for_roots(&["/tmp2", "/tmp3", "/tmp4"]) + .unwrap(), + workspace_3 + ); + } -// use crate::persistence::model::SerializedWorkspace; -// use crate::persistence::model::{SerializedItem, SerializedPane, SerializedPaneGroup}; + use crate::persistence::model::SerializedWorkspace; + use crate::persistence::model::{SerializedItem, SerializedPane, SerializedPaneGroup}; -// fn default_workspace>( -// workspace_id: &[P], -// center_group: &SerializedPaneGroup, -// ) -> SerializedWorkspace { -// SerializedWorkspace { -// id: 4, -// location: workspace_id.into(), -// center_group: center_group.clone(), -// bounds: Default::default(), -// display: Default::default(), -// docks: Default::default(), -// } -// } + fn default_workspace>( + workspace_id: &[P], + center_group: &SerializedPaneGroup, + ) -> SerializedWorkspace { + SerializedWorkspace { + id: 4, + location: workspace_id.into(), + center_group: center_group.clone(), + bounds: Default::default(), + display: Default::default(), + docks: Default::default(), + } + } -// #[gpui::test] -// async fn test_simple_split() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_simple_split() { + 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 | -// // | - - - | | -// // | 3,4 | | -// // ----------------- -// let center_pane = group( -// gpui::Axis::Horizontal, -// vec![ -// group( -// gpui::Axis::Vertical, -// vec![ -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 1, false), -// SerializedItem::new("Terminal", 2, true), -// ], -// false, -// )), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 4, false), -// SerializedItem::new("Terminal", 3, true), -// ], -// true, -// )), -// ], -// ), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 5, true), -// SerializedItem::new("Terminal", 6, false), -// ], -// false, -// )), -// ], -// ); + // ----------------- + // | 1,2 | 5,6 | + // | - - - | | + // | 3,4 | | + // ----------------- + let center_pane = group( + Axis::Horizontal, + vec![ + group( + Axis::Vertical, + vec![ + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 1, false), + SerializedItem::new("Terminal", 2, true), + ], + false, + )), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 4, false), + SerializedItem::new("Terminal", 3, true), + ], + true, + )), + ], + ), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 5, true), + SerializedItem::new("Terminal", 6, 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] -// async fn test_cleanup_panes() { -// env_logger::try_init().ok(); + #[gpui::test] + async fn test_cleanup_panes() { + 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( -// gpui::Axis::Horizontal, -// vec![ -// group( -// gpui::Axis::Vertical, -// vec![ -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 1, false), -// SerializedItem::new("Terminal", 2, true), -// ], -// false, -// )), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 4, false), -// SerializedItem::new("Terminal", 3, true), -// ], -// true, -// )), -// ], -// ), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 5, false), -// SerializedItem::new("Terminal", 6, true), -// ], -// false, -// )), -// ], -// ); + let center_pane = group( + Axis::Horizontal, + vec![ + group( + Axis::Vertical, + vec![ + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 1, false), + SerializedItem::new("Terminal", 2, true), + ], + false, + )), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 4, false), + SerializedItem::new("Terminal", 3, true), + ], + true, + )), + ], + ), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 5, false), + SerializedItem::new("Terminal", 6, true), + ], + 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( -// gpui::Axis::Vertical, -// vec![ -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 1, false), -// SerializedItem::new("Terminal", 2, true), -// ], -// false, -// )), -// SerializedPaneGroup::Pane(SerializedPane::new( -// vec![ -// SerializedItem::new("Terminal", 4, true), -// SerializedItem::new("Terminal", 3, false), -// ], -// true, -// )), -// ], -// ); + workspace.center_group = group( + Axis::Vertical, + vec![ + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 1, false), + SerializedItem::new("Terminal", 2, true), + ], + false, + )), + SerializedPaneGroup::Pane(SerializedPane::new( + vec![ + SerializedItem::new("Terminal", 4, true), + SerializedItem::new("Terminal", 3, false), + ], + 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); + } +} diff --git a/crates/workspace2/src/persistence/model.rs b/crates/workspace2/src/persistence/model.rs index de4518f68e..2b8ec94bd4 100644 --- a/crates/workspace2/src/persistence/model.rs +++ b/crates/workspace2/src/persistence/model.rs @@ -7,7 +7,7 @@ use db2::sqlez::{ bindable::{Bind, Column, StaticColumnCount}, statement::Statement, }; -use gpui2::{AsyncWindowContext, Model, Task, View, WeakView, WindowBounds}; +use gpui::{AsyncWindowContext, Model, Task, View, WeakView, WindowBounds}; use project2::Project; use std::{ path::{Path, PathBuf}, @@ -55,7 +55,7 @@ impl Column for WorkspaceLocation { } } -#[derive(PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone)] pub struct SerializedWorkspace { pub id: WorkspaceId, pub location: WorkspaceLocation, @@ -127,7 +127,7 @@ impl Bind for DockData { } } -#[derive(PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone)] pub enum SerializedPaneGroup { Group { axis: Axis, @@ -286,15 +286,15 @@ pub struct SerializedItem { pub active: bool, } -// impl SerializedItem { -// pub fn new(kind: impl AsRef, item_id: ItemId, active: bool) -> Self { -// Self { -// kind: Arc::from(kind.as_ref()), -// item_id, -// active, -// } -// } -// } +impl SerializedItem { + pub fn new(kind: impl AsRef, item_id: ItemId, active: bool) -> Self { + Self { + kind: Arc::from(kind.as_ref()), + item_id, + active, + } + } +} #[cfg(test)] impl Default for SerializedItem { diff --git a/crates/workspace2/src/searchable.rs b/crates/workspace2/src/searchable.rs index 3935423635..2b870c2944 100644 --- a/crates/workspace2/src/searchable.rs +++ b/crates/workspace2/src/searchable.rs @@ -1,6 +1,6 @@ use std::{any::Any, sync::Arc}; -use gpui2::{AnyView, AppContext, Subscription, Task, View, ViewContext, WindowContext}; +use gpui::{AnyView, AppContext, Subscription, Task, View, ViewContext, WindowContext}; use project2::search::SearchQuery; use crate::{ diff --git a/crates/workspace2/src/status_bar.rs b/crates/workspace2/src/status_bar.rs index c2f78d9ad6..ca4ebcdb13 100644 --- a/crates/workspace2/src/status_bar.rs +++ b/crates/workspace2/src/status_bar.rs @@ -1,7 +1,7 @@ use std::any::TypeId; use crate::{ItemHandle, Pane}; -use gpui2::{ +use gpui::{ div, AnyView, Component, Div, ParentElement, Render, Styled, Subscription, View, ViewContext, WindowContext, }; diff --git a/crates/workspace2/src/toolbar.rs b/crates/workspace2/src/toolbar.rs index c3d1e520c7..80503ad7bb 100644 --- a/crates/workspace2/src/toolbar.rs +++ b/crates/workspace2/src/toolbar.rs @@ -1,5 +1,5 @@ use crate::ItemHandle; -use gpui2::{ +use gpui::{ AnyView, AppContext, Entity, EntityId, EventEmitter, Render, View, ViewContext, WindowContext, }; diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 3d9b86a051..bb9cb7e527 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -8,6 +8,7 @@ pub mod pane; pub mod pane_group; mod persistence; pub mod searchable; +// todo!() // pub mod shared_screen; mod status_bar; mod toolbar; @@ -23,14 +24,14 @@ use client2::{ proto::{self, PeerId}, Client, TypedEnvelope, UserStore, }; -use collections::{HashMap, HashSet}; +use collections::{hash_map, HashMap, HashSet}; use dock::{Dock, DockPosition, PanelButtons}; use futures::{ channel::{mpsc, oneshot}, future::try_join_all, Future, FutureExt, StreamExt, }; -use gpui2::{ +use gpui::{ div, point, size, AnyModel, AnyView, AnyWeakView, AppContext, AsyncAppContext, AsyncWindowContext, Bounds, Component, Div, EntityId, EventEmitter, GlobalPixels, Model, ModelContext, ParentElement, Point, Render, Size, StatefulInteractive, Styled, Subscription, @@ -38,6 +39,7 @@ use gpui2::{ WindowOptions, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem}; +use itertools::Itertools; use language2::LanguageRegistry; use lazy_static::lazy_static; use node_runtime::NodeRuntime; @@ -174,42 +176,42 @@ pub struct Toast { on_click: Option<(Cow<'static, str>, Arc)>, } -// impl Toast { -// pub fn new>>(id: usize, msg: I) -> Self { -// Toast { -// id, -// msg: msg.into(), -// on_click: None, -// } -// } +impl Toast { + pub fn new>>(id: usize, msg: I) -> Self { + Toast { + id, + msg: msg.into(), + on_click: None, + } + } -// pub fn on_click(mut self, message: M, on_click: F) -> Self -// where -// M: Into>, -// F: Fn(&mut WindowContext) + 'static, -// { -// self.on_click = Some((message.into(), Arc::new(on_click))); -// self -// } -// } + pub fn on_click(mut self, message: M, on_click: F) -> Self + where + M: Into>, + F: Fn(&mut WindowContext) + 'static, + { + self.on_click = Some((message.into(), Arc::new(on_click))); + self + } +} -// impl PartialEq for Toast { -// fn eq(&self, other: &Self) -> bool { -// self.id == other.id -// && self.msg == other.msg -// && self.on_click.is_some() == other.on_click.is_some() -// } -// } +impl PartialEq for Toast { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + && self.msg == other.msg + && self.on_click.is_some() == other.on_click.is_some() + } +} -// impl Clone for Toast { -// fn clone(&self) -> Self { -// Toast { -// id: self.id, -// msg: self.msg.to_owned(), -// on_click: self.on_click.clone(), -// } -// } -// } +impl Clone for Toast { + fn clone(&self) -> Self { + Toast { + id: self.id, + msg: self.msg.to_owned(), + on_click: self.on_click.clone(), + } + } +} // #[derive(Clone, Deserialize, PartialEq)] // pub struct OpenTerminal { @@ -460,7 +462,7 @@ struct Follower { impl AppState { #[cfg(any(test, feature = "test-support"))] pub fn test(cx: &mut AppContext) -> Arc { - use gpui2::Context; + use gpui::Context; use node_runtime::FakeNodeRuntime; use settings2::SettingsStore; @@ -476,8 +478,7 @@ impl AppState { let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http_client, cx)); let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx)); - // todo!() - // theme::init((), cx); + theme2::init(cx); client2::init(&client, cx); crate::init_settings(cx); @@ -549,7 +550,7 @@ pub struct Workspace { weak_self: WeakView, // modal: Option, zoomed: Option, - // zoomed_position: Option, + zoomed_position: Option, center: PaneGroup, left_dock: View, bottom_dock: View, @@ -626,7 +627,7 @@ impl Workspace { } project2::Event::Closed => { - // cx.remove_window(); + cx.remove_window(); } project2::Event::DeletedEntry(entry_id) => { @@ -768,7 +769,7 @@ impl Workspace { weak_self: weak_handle.clone(), // modal: None, zoomed: None, - // zoomed_position: None, + zoomed_position: None, center: PaneGroup::new(center_pane.clone()), panes: vec![center_pane.clone()], panes_by_item: Default::default(), @@ -1059,183 +1060,185 @@ impl Workspace { &self.project } - // pub fn recent_navigation_history( - // &self, - // limit: Option, - // cx: &AppContext, - // ) -> Vec<(ProjectPath, Option)> { - // let mut abs_paths_opened: HashMap> = HashMap::default(); - // let mut history: HashMap, usize)> = HashMap::default(); - // for pane in &self.panes { - // let pane = pane.read(cx); - // pane.nav_history() - // .for_each_entry(cx, |entry, (project_path, fs_path)| { - // if let Some(fs_path) = &fs_path { - // abs_paths_opened - // .entry(fs_path.clone()) - // .or_default() - // .insert(project_path.clone()); - // } - // let timestamp = entry.timestamp; - // match history.entry(project_path) { - // hash_map::Entry::Occupied(mut entry) => { - // let (_, old_timestamp) = entry.get(); - // if ×tamp > old_timestamp { - // entry.insert((fs_path, timestamp)); - // } - // } - // hash_map::Entry::Vacant(entry) => { - // entry.insert((fs_path, timestamp)); - // } - // } - // }); - // } + pub fn recent_navigation_history( + &self, + limit: Option, + cx: &AppContext, + ) -> Vec<(ProjectPath, Option)> { + let mut abs_paths_opened: HashMap> = HashMap::default(); + let mut history: HashMap, usize)> = HashMap::default(); + for pane in &self.panes { + let pane = pane.read(cx); + pane.nav_history() + .for_each_entry(cx, |entry, (project_path, fs_path)| { + if let Some(fs_path) = &fs_path { + abs_paths_opened + .entry(fs_path.clone()) + .or_default() + .insert(project_path.clone()); + } + let timestamp = entry.timestamp; + match history.entry(project_path) { + hash_map::Entry::Occupied(mut entry) => { + let (_, old_timestamp) = entry.get(); + if ×tamp > old_timestamp { + entry.insert((fs_path, timestamp)); + } + } + hash_map::Entry::Vacant(entry) => { + entry.insert((fs_path, timestamp)); + } + } + }); + } - // history - // .into_iter() - // .sorted_by_key(|(_, (_, timestamp))| *timestamp) - // .map(|(project_path, (fs_path, _))| (project_path, fs_path)) - // .rev() - // .filter(|(history_path, abs_path)| { - // let latest_project_path_opened = abs_path - // .as_ref() - // .and_then(|abs_path| abs_paths_opened.get(abs_path)) - // .and_then(|project_paths| { - // project_paths - // .iter() - // .max_by(|b1, b2| b1.worktree_id.cmp(&b2.worktree_id)) - // }); + history + .into_iter() + .sorted_by_key(|(_, (_, timestamp))| *timestamp) + .map(|(project_path, (fs_path, _))| (project_path, fs_path)) + .rev() + .filter(|(history_path, abs_path)| { + let latest_project_path_opened = abs_path + .as_ref() + .and_then(|abs_path| abs_paths_opened.get(abs_path)) + .and_then(|project_paths| { + project_paths + .iter() + .max_by(|b1, b2| b1.worktree_id.cmp(&b2.worktree_id)) + }); - // match latest_project_path_opened { - // Some(latest_project_path_opened) => latest_project_path_opened == history_path, - // None => true, - // } - // }) - // .take(limit.unwrap_or(usize::MAX)) - // .collect() - // } + match latest_project_path_opened { + Some(latest_project_path_opened) => latest_project_path_opened == history_path, + None => true, + } + }) + .take(limit.unwrap_or(usize::MAX)) + .collect() + } - // fn navigate_history( - // &mut self, - // pane: WeakView, - // mode: NavigationMode, - // cx: &mut ViewContext, - // ) -> Task> { - // let to_load = if let Some(pane) = pane.upgrade(cx) { - // cx.focus(&pane); + fn navigate_history( + &mut self, + pane: WeakView, + mode: NavigationMode, + cx: &mut ViewContext, + ) -> Task> { + let to_load = if let Some(pane) = pane.upgrade() { + // todo!("focus") + // cx.focus(&pane); - // pane.update(cx, |pane, cx| { - // loop { - // // Retrieve the weak item handle from the history. - // let entry = pane.nav_history_mut().pop(mode, cx)?; + pane.update(cx, |pane, cx| { + loop { + // Retrieve the weak item handle from the history. + let entry = pane.nav_history_mut().pop(mode, cx)?; - // // If the item is still present in this pane, then activate it. - // if let Some(index) = entry - // .item - // .upgrade(cx) - // .and_then(|v| pane.index_for_item(v.as_ref())) - // { - // let prev_active_item_index = pane.active_item_index(); - // pane.nav_history_mut().set_mode(mode); - // pane.activate_item(index, true, true, cx); - // pane.nav_history_mut().set_mode(NavigationMode::Normal); + // If the item is still present in this pane, then activate it. + if let Some(index) = entry + .item + .upgrade() + .and_then(|v| pane.index_for_item(v.as_ref())) + { + let prev_active_item_index = pane.active_item_index(); + pane.nav_history_mut().set_mode(mode); + pane.activate_item(index, true, true, cx); + pane.nav_history_mut().set_mode(NavigationMode::Normal); - // let mut navigated = prev_active_item_index != pane.active_item_index(); - // if let Some(data) = entry.data { - // navigated |= pane.active_item()?.navigate(data, cx); - // } + let mut navigated = prev_active_item_index != pane.active_item_index(); + if let Some(data) = entry.data { + navigated |= pane.active_item()?.navigate(data, cx); + } - // if navigated { - // break None; - // } - // } - // // If the item is no longer present in this pane, then retrieve its - // // project path in order to reopen it. - // else { - // break pane - // .nav_history() - // .path_for_item(entry.item.id()) - // .map(|(project_path, _)| (project_path, entry)); - // } - // } - // }) - // } else { - // None - // }; + if navigated { + break None; + } + } + // If the item is no longer present in this pane, then retrieve its + // project path in order to reopen it. + else { + break pane + .nav_history() + .path_for_item(entry.item.id()) + .map(|(project_path, _)| (project_path, entry)); + } + } + }) + } else { + None + }; - // if let Some((project_path, entry)) = to_load { - // // If the item was no longer present, then load it again from its previous path. - // let task = self.load_path(project_path, cx); - // cx.spawn(|workspace, mut cx| async move { - // let task = task.await; - // let mut navigated = false; - // if let Some((project_entry_id, build_item)) = task.log_err() { - // let prev_active_item_id = pane.update(&mut cx, |pane, _| { - // pane.nav_history_mut().set_mode(mode); - // pane.active_item().map(|p| p.id()) - // })?; + if let Some((project_path, entry)) = to_load { + // If the item was no longer present, then load it again from its previous path. + let task = self.load_path(project_path, cx); + cx.spawn(|workspace, mut cx| async move { + let task = task.await; + let mut navigated = false; + if let Some((project_entry_id, build_item)) = task.log_err() { + let prev_active_item_id = pane.update(&mut cx, |pane, _| { + pane.nav_history_mut().set_mode(mode); + pane.active_item().map(|p| p.id()) + })?; - // pane.update(&mut cx, |pane, cx| { - // let item = pane.open_item(project_entry_id, true, cx, build_item); - // navigated |= Some(item.id()) != prev_active_item_id; - // pane.nav_history_mut().set_mode(NavigationMode::Normal); - // if let Some(data) = entry.data { - // navigated |= item.navigate(data, cx); - // } - // })?; - // } + pane.update(&mut cx, |pane, cx| { + let item = pane.open_item(project_entry_id, true, cx, build_item); + navigated |= Some(item.id()) != prev_active_item_id; + pane.nav_history_mut().set_mode(NavigationMode::Normal); + if let Some(data) = entry.data { + navigated |= item.navigate(data, cx); + } + })?; + } - // if !navigated { - // workspace - // .update(&mut cx, |workspace, cx| { - // Self::navigate_history(workspace, pane, mode, cx) - // })? - // .await?; - // } + if !navigated { + workspace + .update(&mut cx, |workspace, cx| { + Self::navigate_history(workspace, pane, mode, cx) + })? + .await?; + } - // Ok(()) - // }) - // } else { - // Task::ready(Ok(())) - // } - // } + Ok(()) + }) + } else { + Task::ready(Ok(())) + } + } - // pub fn go_back( - // &mut self, - // pane: WeakView, - // cx: &mut ViewContext, - // ) -> Task> { - // self.navigate_history(pane, NavigationMode::GoingBack, cx) - // } + pub fn go_back( + &mut self, + pane: WeakView, + cx: &mut ViewContext, + ) -> Task> { + self.navigate_history(pane, NavigationMode::GoingBack, cx) + } - // pub fn go_forward( - // &mut self, - // pane: WeakView, - // cx: &mut ViewContext, - // ) -> Task> { - // self.navigate_history(pane, NavigationMode::GoingForward, cx) - // } + pub fn go_forward( + &mut self, + pane: WeakView, + cx: &mut ViewContext, + ) -> Task> { + self.navigate_history(pane, NavigationMode::GoingForward, cx) + } - // pub fn reopen_closed_item(&mut self, cx: &mut ViewContext) -> Task> { - // self.navigate_history( - // self.active_pane().downgrade(), - // NavigationMode::ReopeningClosedItem, - // cx, - // ) - // } + pub fn reopen_closed_item(&mut self, cx: &mut ViewContext) -> Task> { + self.navigate_history( + self.active_pane().downgrade(), + NavigationMode::ReopeningClosedItem, + cx, + ) + } - // pub fn client(&self) -> &Client { - // &self.app_state.client - // } + pub fn client(&self) -> &Client { + &self.app_state.client + } - // pub fn set_titlebar_item(&mut self, item: AnyViewHandle, cx: &mut ViewContext) { - // self.titlebar_item = Some(item); - // cx.notify(); - // } + // todo!() + // pub fn set_titlebar_item(&mut self, item: AnyViewHandle, cx: &mut ViewContext) { + // self.titlebar_item = Some(item); + // cx.notify(); + // } - // pub fn titlebar_item(&self) -> Option { - // self.titlebar_item.clone() - // } + // pub fn titlebar_item(&self) -> Option { + // self.titlebar_item.clone() + // } // /// Call the given callback with a workspace whose project is local. // /// @@ -1261,32 +1264,29 @@ impl Workspace { // } // } - // pub fn worktrees<'a>( - // &self, - // cx: &'a AppContext, - // ) -> impl 'a + Iterator> { - // self.project.read(cx).worktrees(cx) - // } + pub fn worktrees<'a>(&self, cx: &'a AppContext) -> impl 'a + Iterator> { + self.project.read(cx).worktrees() + } - // pub fn visible_worktrees<'a>( - // &self, - // cx: &'a AppContext, - // ) -> impl 'a + Iterator> { - // self.project.read(cx).visible_worktrees(cx) - // } + pub fn visible_worktrees<'a>( + &self, + cx: &'a AppContext, + ) -> impl 'a + Iterator> { + self.project.read(cx).visible_worktrees(cx) + } - // pub fn worktree_scans_complete(&self, cx: &AppContext) -> impl Future + 'static { - // let futures = self - // .worktrees(cx) - // .filter_map(|worktree| worktree.read(cx).as_local()) - // .map(|worktree| worktree.scan_complete()) - // .collect::>(); - // async move { - // for future in futures { - // future.await; - // } - // } - // } + pub fn worktree_scans_complete(&self, cx: &AppContext) -> impl Future + 'static { + let futures = self + .worktrees(cx) + .filter_map(|worktree| worktree.read(cx).as_local()) + .map(|worktree| worktree.scan_complete()) + .collect::>(); + async move { + for future in futures { + future.await; + } + } + } // pub fn close_global(_: &CloseWindow, cx: &mut AppContext) { // cx.spawn(|mut cx| async move { @@ -1699,31 +1699,31 @@ impl Workspace { self.active_pane().read(cx).active_item() } - // fn active_project_path(&self, cx: &ViewContext) -> Option { - // self.active_item(cx).and_then(|item| item.project_path(cx)) - // } + fn active_project_path(&self, cx: &ViewContext) -> Option { + self.active_item(cx).and_then(|item| item.project_path(cx)) + } - // pub fn save_active_item( - // &mut self, - // save_intent: SaveIntent, - // cx: &mut ViewContext, - // ) -> Task> { - // let project = self.project.clone(); - // let pane = self.active_pane(); - // let item_ix = pane.read(cx).active_item_index(); - // let item = pane.read(cx).active_item(); - // let pane = pane.downgrade(); + pub fn save_active_item( + &mut self, + save_intent: SaveIntent, + cx: &mut ViewContext, + ) -> Task> { + let project = self.project.clone(); + let pane = self.active_pane(); + let item_ix = pane.read(cx).active_item_index(); + let item = pane.read(cx).active_item(); + let pane = pane.downgrade(); - // cx.spawn(|_, mut cx| async move { - // if let Some(item) = item { - // Pane::save_item(project, &pane, item_ix, item.as_ref(), save_intent, &mut cx) - // .await - // .map(|_| ()) - // } else { - // Ok(()) - // } - // }) - // } + cx.spawn(|_, mut cx| async move { + if let Some(item) = item { + Pane::save_item(project, &pane, item_ix, item.as_ref(), save_intent, &mut cx) + .await + .map(|_| ()) + } else { + Ok(()) + } + }) + } // pub fn close_inactive_items_and_panes( // &mut self, @@ -1825,19 +1825,20 @@ impl Workspace { // self.serialize_workspace(cx); // } - // pub fn close_all_docks(&mut self, cx: &mut ViewContext) { - // let docks = [&self.left_dock, &self.bottom_dock, &self.right_dock]; + pub fn close_all_docks(&mut self, cx: &mut ViewContext) { + let docks = [&self.left_dock, &self.bottom_dock, &self.right_dock]; - // for dock in docks { - // dock.update(cx, |dock, cx| { - // dock.set_open(false, cx); - // }); - // } + for dock in docks { + dock.update(cx, |dock, cx| { + dock.set_open(false, cx); + }); + } - // cx.focus_self(); - // cx.notify(); - // self.serialize_workspace(cx); - // } + // todo!("focus") + // cx.focus_self(); + cx.notify(); + self.serialize_workspace(cx); + } // /// Transfer focus to the panel of the given type. // pub fn focus_panel(&mut self, cx: &mut ViewContext) -> Option> { @@ -1904,19 +1905,19 @@ impl Workspace { // None // } - // fn zoom_out(&mut self, cx: &mut ViewContext) { - // for pane in &self.panes { - // pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); - // } + fn zoom_out(&mut self, cx: &mut ViewContext) { + for pane in &self.panes { + pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); + } - // self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx)); - // self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx)); - // self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx)); - // self.zoomed = None; - // self.zoomed_position = None; + self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + self.zoomed = None; + self.zoomed_position = None; - // cx.notify(); - // } + cx.notify(); + } // #[cfg(any(test, feature = "test-support"))] // pub fn zoomed_view(&self, cx: &AppContext) -> Option { @@ -1962,22 +1963,21 @@ impl Workspace { // cx.notify(); // } - fn add_pane(&mut self, _cx: &mut ViewContext) -> View { - todo!() - // let pane = cx.build_view(|cx| { - // Pane::new( - // self.weak_handle(), - // self.project.clone(), - // self.pane_history_timestamp.clone(), - // cx, - // ) - // }); - // cx.subscribe(&pane, Self::handle_pane_event).detach(); - // self.panes.push(pane.clone()); + fn add_pane(&mut self, cx: &mut ViewContext) -> View { + let pane = cx.build_view(|cx| { + Pane::new( + self.weak_handle(), + self.project.clone(), + self.pane_history_timestamp.clone(), + cx, + ) + }); + cx.subscribe(&pane, Self::handle_pane_event).detach(); + self.panes.push(pane.clone()); // todo!() // cx.focus(&pane); - // cx.emit(Event::PaneAdded(pane.clone())); - // pane + cx.emit(Event::PaneAdded(pane.clone())); + pane } // pub fn add_item_to_center( @@ -3122,6 +3122,7 @@ impl Workspace { None } + // todo!() // fn shared_screen_for_peer( // &self, // peer_id: PeerId, @@ -3498,6 +3499,7 @@ impl Workspace { }) } + // todo!() // #[cfg(any(test, feature = "test-support"))] // pub fn test_new(project: ModelHandle, cx: &mut ViewContext) -> Self { // use node_runtime::FakeNodeRuntime; @@ -3658,6 +3660,7 @@ fn open_items( }) } +// todo!() // fn notify_of_new_dock(workspace: &WeakView, cx: &mut AsyncAppContext) { // const NEW_PANEL_BLOG_POST: &str = "https://zed.dev/blog/new-panel-system"; // const NEW_DOCK_HINT_KEY: &str = "show_new_dock_key"; @@ -3738,23 +3741,22 @@ fn open_items( // }) // .ok(); -fn notify_if_database_failed(_workspace: WindowHandle, _cx: &mut AsyncAppContext) { +fn notify_if_database_failed(workspace: WindowHandle, cx: &mut AsyncAppContext) { const REPORT_ISSUE_URL: &str ="https://github.com/zed-industries/community/issues/new?assignees=&labels=defect%2Ctriage&template=2_bug_report.yml"; - // todo!() - // workspace - // .update(cx, |workspace, cx| { - // if (*db::ALL_FILE_DB_FAILED).load(std::sync::atomic::Ordering::Acquire) { - // workspace.show_notification_once(0, cx, |cx| { - // cx.build_view(|_| { - // MessageNotification::new("Failed to load the database file.") - // .with_click_message("Click to let us know about this error") - // .on_click(|cx| cx.platform().open_url(REPORT_ISSUE_URL)) - // }) - // }); - // } - // }) - // .log_err(); + workspace + .update(cx, |workspace, cx| { + if (*db2::ALL_FILE_DB_FAILED).load(std::sync::atomic::Ordering::Acquire) { + workspace.show_notification_once(0, cx, |cx| { + cx.build_view(|_| { + MessageNotification::new("Failed to load the database file.") + .with_click_message("Click to let us know about this error") + .on_click(|cx| cx.open_url(REPORT_ISSUE_URL)) + }) + }); + } + }) + .log_err(); } impl EventEmitter for Workspace { @@ -4176,36 +4178,32 @@ impl WorkspaceStore { } async fn handle_update_followers( - _this: Model, - _envelope: TypedEnvelope, + this: Model, + envelope: TypedEnvelope, _: Arc, - mut _cx: AsyncWindowContext, + mut cx: AsyncWindowContext, ) -> Result<()> { - // let leader_id = envelope.original_sender_id()?; - // let update = envelope.payload; + let leader_id = envelope.original_sender_id()?; + let update = envelope.payload; - // this.update(&mut cx, |this, cx| { - // for workspace in &this.workspaces { - // let Some(workspace) = workspace.upgrade() else { - // continue; - // }; - // workspace.update(cx, |workspace, cx| { - // let project_id = workspace.project.read(cx).remote_id(); - // if update.project_id != project_id && update.project_id.is_some() { - // return; - // } - // workspace.handle_update_followers(leader_id, update.clone(), cx); - // }); - // } - // Ok(()) - // })? - todo!() + this.update(&mut cx, |this, cx| { + for workspace in &this.workspaces { + workspace.update(cx, |workspace, cx| { + let project_id = workspace.project.read(cx).remote_id(); + if update.project_id != project_id && update.project_id.is_some() { + return; + } + workspace.handle_update_followers(leader_id, update.clone(), cx); + })?; + } + Ok(()) + })? } } -// impl Entity for WorkspaceStore { -// type Event = (); -// } +impl EventEmitter for WorkspaceStore { + type Event = (); +} impl ViewId { pub(crate) fn from_proto(message: proto::ViewId) -> Result { diff --git a/crates/workspace2/src/workspace_settings.rs b/crates/workspace2/src/workspace_settings.rs index 4b93b705a3..c4d1bb41cd 100644 --- a/crates/workspace2/src/workspace_settings.rs +++ b/crates/workspace2/src/workspace_settings.rs @@ -49,7 +49,7 @@ impl Settings for WorkspaceSettings { fn load( default_value: &Self::FileContent, user_values: &[&Self::FileContent], - _: &mut gpui2::AppContext, + _: &mut gpui::AppContext, ) -> anyhow::Result { Self::load_via_json_merge(default_value, user_values) } diff --git a/crates/zed2/src/main.rs b/crates/zed2/src/main.rs index f8b77fe9df..6522d97fdc 100644 --- a/crates/zed2/src/main.rs +++ b/crates/zed2/src/main.rs @@ -12,6 +12,7 @@ use cli::{ CliRequest, CliResponse, IpcHandshake, FORCE_CLI_MODE_ENV_VAR_NAME, }; use client::UserStore; +use collections::HashMap; use db::kvp::KEY_VALUE_STORE; use fs::RealFs; use futures::{channel::mpsc, SinkExt, StreamExt}; @@ -42,11 +43,13 @@ use std::{ thread, time::{SystemTime, UNIX_EPOCH}, }; +use text::Point; use util::{ async_maybe, channel::{parse_zed_link, ReleaseChannel, RELEASE_CHANNEL}, http::{self, HttpClient}, - paths, ResultExt, + paths::{self, PathLikeWithPosition}, + ResultExt, }; use uuid::Uuid; use workspace2::{AppState, WorkspaceStore}; @@ -228,10 +231,8 @@ fn main() { let mut _triggered_authentication = false; match open_rx.try_next() { - Ok(Some(OpenRequest::Paths { paths: _ })) => { - // todo!("workspace") - // cx.update(|cx| workspace::open_paths(&paths, &app_state, None, cx)) - // .detach(); + Ok(Some(OpenRequest::Paths { paths })) => { + workspace2::open_paths(&paths, &app_state, None, cx).detach(); } Ok(Some(OpenRequest::CliConnection { connection })) => { let app_state = app_state.clone(); @@ -263,10 +264,10 @@ fn main() { async move { while let Some(request) = open_rx.next().await { match request { - OpenRequest::Paths { paths: _ } => { - // todo!("workspace") - // cx.update(|cx| workspace::open_paths(&paths, &app_state, None, cx)) - // .detach(); + OpenRequest::Paths { paths } => { + cx.update(|cx| workspace2::open_paths(&paths, &app_state, None, cx)) + .ok() + .map(|t| t.detach()); } OpenRequest::CliConnection { connection } => { let app_state = app_state.clone(); @@ -781,45 +782,45 @@ async fn handle_cli_connection( ) { if let Some(request) = requests.next().await { match request { - CliRequest::Open { paths: _, wait: _ } => { - // let mut caret_positions = HashMap::new(); + CliRequest::Open { paths, wait } => { + let mut caret_positions = HashMap::default(); - // todo!("workspace") - // let paths = if paths.is_empty() { - // workspace::last_opened_workspace_paths() - // .await - // .map(|location| location.paths().to_vec()) - // .unwrap_or_default() - // } else { - // paths - // .into_iter() - // .filter_map(|path_with_position_string| { - // let path_with_position = PathLikeWithPosition::parse_str( - // &path_with_position_string, - // |path_str| { - // Ok::<_, std::convert::Infallible>( - // Path::new(path_str).to_path_buf(), - // ) - // }, - // ) - // .expect("Infallible"); - // let path = path_with_position.path_like; - // if let Some(row) = path_with_position.row { - // if path.is_file() { - // let row = row.saturating_sub(1); - // let col = - // path_with_position.column.unwrap_or(0).saturating_sub(1); - // caret_positions.insert(path.clone(), Point::new(row, col)); - // } - // } - // Some(path) - // }) - // .collect() - // }; + let paths = if paths.is_empty() { + workspace2::last_opened_workspace_paths() + .await + .map(|location| location.paths().to_vec()) + .unwrap_or_default() + } else { + paths + .into_iter() + .filter_map(|path_with_position_string| { + let path_with_position = PathLikeWithPosition::parse_str( + &path_with_position_string, + |path_str| { + Ok::<_, std::convert::Infallible>( + Path::new(path_str).to_path_buf(), + ) + }, + ) + .expect("Infallible"); + let path = path_with_position.path_like; + if let Some(row) = path_with_position.row { + if path.is_file() { + let row = row.saturating_sub(1); + let col = + path_with_position.column.unwrap_or(0).saturating_sub(1); + caret_positions.insert(path.clone(), Point::new(row, col)); + } + } + Some(path) + }) + .collect() + }; + // todo!("editor") // let mut errored = false; // match cx - // .update(|cx| workspace::open_paths(&paths, &app_state, None, cx)) + // .update(|cx| workspace2::open_paths(&paths, &app_state, None, cx)) // .await // { // Ok((workspace, items)) => { diff --git a/crates/zed2/src/only_instance.rs b/crates/zed2/src/only_instance.rs index b252f72ce5..a8c4b30816 100644 --- a/crates/zed2/src/only_instance.rs +++ b/crates/zed2/src/only_instance.rs @@ -37,10 +37,9 @@ pub enum IsOnlyInstance { } pub fn ensure_only_instance() -> IsOnlyInstance { - // todo!("zed_stateless") - // if *db::ZED_STATELESS { - // return IsOnlyInstance::Yes; - // } + if *db::ZED_STATELESS { + return IsOnlyInstance::Yes; + } if check_got_handshake() { return IsOnlyInstance::No; diff --git a/crates/zed2/src/zed2.rs b/crates/zed2/src/zed2.rs index 4f28536085..a33498538e 100644 --- a/crates/zed2/src/zed2.rs +++ b/crates/zed2/src/zed2.rs @@ -69,11 +69,10 @@ pub async fn handle_cli_connection( let mut caret_positions = HashMap::default(); let paths = if paths.is_empty() { - todo!() - // workspace::last_opened_workspace_paths() - // .await - // .map(|location| location.paths().to_vec()) - // .unwrap_or_default() + workspace2::last_opened_workspace_paths() + .await + .map(|location| location.paths().to_vec()) + .unwrap_or_default() } else { paths .into_iter() @@ -115,7 +114,7 @@ pub async fn handle_cli_connection( match item { Some(Ok(mut item)) => { if let Some(point) = caret_positions.remove(path) { - todo!() + todo!("editor") // if let Some(active_editor) = item.downcast::() { // active_editor // .downgrade() @@ -260,33 +259,33 @@ pub fn initialize_workspace( move |workspace, _, event, cx| { if let workspace2::Event::PaneAdded(pane) = event { pane.update(cx, |pane, cx| { - // todo!() - // pane.toolbar().update(cx, |toolbar, cx| { - // 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); - // }) + 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); + }) }); } }