wip

KCaverly created

Change summary

crates/workspace2/src/workspace2.rs | 239 +++++++++++++++---------------
crates/zed2/src/main.rs             |  50 +++---
crates/zed2/src/zed2.rs             |  30 +++
3 files changed, 176 insertions(+), 143 deletions(-)

Detailed changes

crates/workspace2/src/workspace2.rs 🔗

@@ -14,15 +14,18 @@ use anyhow::{anyhow, Result};
 use call2::ActiveCall;
 use client2::{
     proto::{self, PeerId},
-    Client, UserStore,
+    Client, TypedEnvelope, UserStore,
 };
 use collections::{HashMap, HashSet};
 use dock::Dock;
-use futures::{channel::oneshot, FutureExt};
+use futures::{
+    channel::{mpsc, oneshot},
+    FutureExt,
+};
 use gpui2::{
-    AnyModel, AnyView, AppContext, AsyncAppContext, DisplayId, EventEmitter, MainThread, Model,
-    Subscription, Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowBounds,
-    WindowHandle, WindowOptions,
+    AnyModel, AnyView, AppContext, AsyncAppContext, AsyncWindowContext, DisplayId, EventEmitter,
+    MainThread, Model, ModelContext, Subscription, Task, View, ViewContext, VisualContext,
+    WeakModel, WeakView, WindowBounds, WindowHandle, WindowOptions,
 };
 use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ProjectItem};
 use language2::LanguageRegistry;
@@ -418,7 +421,7 @@ pub struct AppState {
 }
 
 pub struct WorkspaceStore {
-    workspaces: HashSet<WeakModel<Workspace>>,
+    workspaces: HashSet<WeakView<Workspace>>,
     followers: Vec<Follower>,
     client: Arc<Client>,
     _subscriptions: Vec<client2::Subscription>,
@@ -539,7 +542,7 @@ pub struct Workspace {
     last_leaders_by_pane: HashMap<WeakView<Pane>, PeerId>,
     //     window_edited: bool,
     active_call: Option<(Model<ActiveCall>, Vec<Subscription>)>,
-    //     leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
+    leader_updates_tx: mpsc::UnboundedSender<(PeerId, proto::UpdateFollowers)>,
     database_id: WorkspaceId,
     app_state: Arc<AppState>,
     //     subscriptions: Vec<Subscription>,
@@ -2853,16 +2856,16 @@ impl Workspace {
     //         }
     //     }
 
-    //     fn handle_update_followers(
-    //         &mut self,
-    //         leader_id: PeerId,
-    //         message: proto::UpdateFollowers,
-    //         _cx: &mut ViewContext<Self>,
-    //     ) {
-    //         self.leader_updates_tx
-    //             .unbounded_send((leader_id, message))
-    //             .ok();
-    //     }
+    fn handle_update_followers(
+        &mut self,
+        leader_id: PeerId,
+        message: proto::UpdateFollowers,
+        _cx: &mut ViewContext<Self>,
+    ) {
+        self.leader_updates_tx
+            .unbounded_send((leader_id, message))
+            .ok();
+    }
 
     //     async fn process_leader_update(
     //         this: &WeakView<Self>,
@@ -3886,18 +3889,19 @@ impl EventEmitter for Workspace {
 // }
 
 impl WorkspaceStore {
-    //     pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self {
-    //         Self {
-    //             workspaces: Default::default(),
-    //             followers: Default::default(),
-    //             _subscriptions: vec![
-    //                 client.add_request_handler(cx.handle(), Self::handle_follow),
-    //                 client.add_message_handler(cx.handle(), Self::handle_unfollow),
-    //                 client.add_message_handler(cx.handle(), Self::handle_update_followers),
-    //             ],
-    //             client,
-    //         }
-    //     }
+    pub fn new(client: Arc<Client>, cx: &mut ModelContext<Self>) -> Self {
+        // Self {
+        //     workspaces: Default::default(),
+        //     followers: Default::default(),
+        //     _subscriptions: vec![
+        //         client.add_request_handler(cx.weak_model(), Self::handle_follow),
+        //         client.add_message_handler(cx.weak_model(), Self::handle_unfollow),
+        //         client.add_message_handler(cx.weak_model(), Self::handle_update_followers),
+        //     ],
+        //     client,
+        // }
+        todo!()
+    }
 
     pub fn update_followers(
         &self,
@@ -3933,99 +3937,100 @@ impl WorkspaceStore {
             })
             .log_err()
     }
-}
 
-//     async fn handle_follow(
-//         this: ModelHandle<Self>,
-//         envelope: TypedEnvelope<proto::Follow>,
-//         _: Arc<Client>,
-//         mut cx: AsyncAppContext,
-//     ) -> Result<proto::FollowResponse> {
-//         this.update(&mut cx, |this, cx| {
-//             let follower = Follower {
-//                 project_id: envelope.payload.project_id,
-//                 peer_id: envelope.original_sender_id()?,
-//             };
-//             let active_project = ActiveCall::global(cx)
-//                 .read(cx)
-//                 .location()
-//                 .map(|project| project.id());
-
-//             let mut response = proto::FollowResponse::default();
-//             for workspace in &this.workspaces {
-//                 let Some(workspace) = workspace.upgrade(cx) else {
-//                     continue;
-//                 };
-
-//                 workspace.update(cx.as_mut(), |workspace, cx| {
-//                     let handler_response = workspace.handle_follow(follower.project_id, cx);
-//                     if response.views.is_empty() {
-//                         response.views = handler_response.views;
-//                     } else {
-//                         response.views.extend_from_slice(&handler_response.views);
-//                     }
+    // async fn handle_follow(
+    //     this: Model<Self>,
+    //     envelope: TypedEnvelope<proto::Follow>,
+    //     _: Arc<Client>,
+    //     mut cx: AsyncAppContext,
+    // ) -> Result<proto::FollowResponse> {
+    //     this.update(&mut cx, |this, cx| {
+    //         let follower = Follower {
+    //             project_id: envelope.payload.project_id,
+    //             peer_id: envelope.original_sender_id()?,
+    //         };
+    //         let active_project = ActiveCall::global(cx)
+    //             .read(cx)
+    //             .location()
+    //             .map(|project| project.id());
 
-//                     if let Some(active_view_id) = handler_response.active_view_id.clone() {
-//                         if response.active_view_id.is_none()
-//                             || Some(workspace.project.id()) == active_project
-//                         {
-//                             response.active_view_id = Some(active_view_id);
-//                         }
-//                     }
-//                 });
-//             }
+    //         let mut response = proto::FollowResponse::default();
+    //         for workspace in &this.workspaces {
+    //             let Some(workspace) = workspace.upgrade(cx) else {
+    //                 continue;
+    //             };
 
-//             if let Err(ix) = this.followers.binary_search(&follower) {
-//                 this.followers.insert(ix, follower);
-//             }
+    //             workspace.update(cx.as_mut(), |workspace, cx| {
+    //                 let handler_response = workspace.handle_follow(follower.project_id, cx);
+    //                 if response.views.is_empty() {
+    //                     response.views = handler_response.views;
+    //                 } else {
+    //                     response.views.extend_from_slice(&handler_response.views);
+    //                 }
 
-//             Ok(response)
-//         })
-//     }
+    //                 if let Some(active_view_id) = handler_response.active_view_id.clone() {
+    //                     if response.active_view_id.is_none()
+    //                         || Some(workspace.project.id()) == active_project
+    //                     {
+    //                         response.active_view_id = Some(active_view_id);
+    //                     }
+    //                 }
+    //             });
+    //         }
 
-//     async fn handle_unfollow(
-//         this: ModelHandle<Self>,
-//         envelope: TypedEnvelope<proto::Unfollow>,
-//         _: Arc<Client>,
-//         mut cx: AsyncAppContext,
-//     ) -> Result<()> {
-//         this.update(&mut cx, |this, _| {
-//             let follower = Follower {
-//                 project_id: envelope.payload.project_id,
-//                 peer_id: envelope.original_sender_id()?,
-//             };
-//             if let Ok(ix) = this.followers.binary_search(&follower) {
-//                 this.followers.remove(ix);
-//             }
-//             Ok(())
-//         })
-//     }
+    //         if let Err(ix) = this.followers.binary_search(&follower) {
+    //             this.followers.insert(ix, follower);
+    //         }
 
-//     async fn handle_update_followers(
-//         this: ModelHandle<Self>,
-//         envelope: TypedEnvelope<proto::UpdateFollowers>,
-//         _: Arc<Client>,
-//         mut cx: AsyncAppContext,
-//     ) -> Result<()> {
-//         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(cx) else {
-//                     continue;
-//                 };
-//                 workspace.update(cx.as_mut(), |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(())
-//         })
-//     }
-// }
+    //         Ok(response)
+    //     })
+    // }
+
+    async fn handle_unfollow(
+        model: Model<Self>,
+        envelope: TypedEnvelope<proto::Unfollow>,
+        _: Arc<Client>,
+        mut cx: AsyncAppContext,
+    ) -> Result<()> {
+        model.update(&mut cx, |this, _| {
+            let follower = Follower {
+                project_id: envelope.payload.project_id,
+                peer_id: envelope.original_sender_id()?,
+            };
+            if let Ok(ix) = this.followers.binary_search(&follower) {
+                this.followers.remove(ix);
+            }
+            Ok(())
+        })?
+    }
+
+    async fn handle_update_followers(
+        this: Model<Self>,
+        envelope: TypedEnvelope<proto::UpdateFollowers>,
+        _: Arc<Client>,
+        mut cx: AsyncWindowContext,
+    ) -> Result<()> {
+        // 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!()
+    }
+}
 
 // impl Entity for WorkspaceStore {
 //     type Event = ();
@@ -4320,7 +4325,7 @@ pub fn open_paths(
         .await;
 
         if let Some(existing) = existing {
-            // Ok((
+            // // Ok((
             //     existing.clone(),
             //     cx.update_window_root(&existing, |workspace, cx| {
             //         workspace.open_paths(abs_paths, true, cx)

crates/zed2/src/main.rs 🔗

@@ -12,7 +12,7 @@ use client2::UserStore;
 use db2::kvp::KEY_VALUE_STORE;
 use fs2::RealFs;
 use futures::{channel::mpsc, SinkExt, StreamExt};
-use gpui2::{App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
+use gpui2::{Action, App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
 use isahc::{prelude::Configurable, Request};
 use language2::LanguageRegistry;
 use log::LevelFilter;
@@ -45,7 +45,7 @@ use util::{
     paths, ResultExt,
 };
 use uuid::Uuid;
-use workspace2::AppState;
+use workspace2::{AppState, WorkspaceStore};
 use zed2::languages;
 use zed2::{ensure_only_instance, Assets, IsOnlyInstance};
 
@@ -120,7 +120,7 @@ fn main() {
         language2::init(cx);
         languages::init(languages.clone(), node_runtime.clone(), cx);
         let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
-        // let workspace_store = cx.add_model(|cx| WorkspaceStore::new(client.clone(), cx));
+        let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
 
         cx.set_global(client.clone());
 
@@ -165,20 +165,18 @@ fn main() {
 
         // client.telemetry().start(installation_id, session_id, cx);
 
-        // todo!("app_state")
-        let app_state: Arc<AppState> = todo!();
-        // let app_state = Arc::new(AppState {
-        //     languages,
-        //     client: client.clone(),
-        //     user_store,
-        //     fs,
-        //     build_window_options,
-        //     initialize_workspace,
-        //     background_actions,
-        //     workspace_store,
-        //     node_runtime,
-        // });
-        // cx.set_global(Arc::downgrade(&app_state));
+        let app_state = Arc::new(AppState {
+            languages,
+            client: client.clone(),
+            user_store,
+            fs,
+            build_window_options,
+            initialize_workspace,
+            background_actions,
+            workspace_store,
+            node_runtime,
+        });
+        cx.set_global(Arc::downgrade(&app_state));
 
         // audio::init(Assets, cx);
         // auto_update::init(http.clone(), client::ZED_SERVER_URL.clone(), cx);
@@ -914,11 +912,13 @@ async fn handle_cli_connection(
     }
 }
 
-// pub fn background_actions() -> &'static [(&'static str, &'static dyn Action)] {
-//     &[
-//         ("Go to file", &file_finder::Toggle),
-//         ("Open command palette", &command_palette::Toggle),
-//         ("Open recent projects", &recent_projects::OpenRecent),
-//         ("Change your settings", &zed_actions::OpenSettings),
-//     ]
-// }
+pub fn background_actions() -> &'static [(&'static str, &'static dyn Action)] {
+    // &[
+    //     ("Go to file", &file_finder::Toggle),
+    //     ("Open command palette", &command_palette::Toggle),
+    //     ("Open recent projects", &recent_projects::OpenRecent),
+    //     ("Change your settings", &zed_actions::OpenSettings),
+    // ]
+    // todo!()
+    &[]
+}

crates/zed2/src/zed2.rs 🔗

@@ -5,7 +5,10 @@ mod open_listener;
 
 pub use assets::*;
 use collections::HashMap;
-use gpui2::{AsyncAppContext, Point};
+use gpui2::{
+    point, px, AsyncAppContext, Point, Styled, TitlebarOptions, WindowBounds, WindowKind,
+    WindowOptions,
+};
 pub use only_instance::*;
 pub use open_listener::*;
 
@@ -20,6 +23,7 @@ use futures::{
 };
 use std::{path::Path, sync::Arc, thread, time::Duration};
 use util::{paths::PathLikeWithPosition, ResultExt};
+use uuid::Uuid;
 use workspace2::AppState;
 
 pub fn connect_to_cli(
@@ -211,3 +215,27 @@ pub async fn handle_cli_connection(
         }
     }
 }
+
+pub fn build_window_options(
+    bounds: Option<WindowBounds>,
+    display: Option<Uuid>,
+    platform: &dyn Platform,
+) -> WindowOptions {
+    let bounds = bounds.unwrap_or(WindowBounds::Maximized);
+    let display_id = display.and_then(|display| platform.screen_by_id(display));
+
+    WindowOptions {
+        bounds,
+        titlebar: Some(TitlebarOptions {
+            title: None,
+            appears_transparent: true,
+            traffic_light_position: Some(point(px(8.), px(8.))),
+        }),
+        center: false,
+        focus: false,
+        show: false,
+        kind: WindowKind::Normal,
+        is_movable: false,
+        display_id,
+    }
+}