Start sharing paths with the server via RPC

Antonio Scandurra created

Change summary

zed/src/workspace.rs | 17 ++++++++---------
zed/src/worktree.rs  | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 10 deletions(-)

Detailed changes

zed/src/workspace.rs 🔗

@@ -647,7 +647,7 @@ impl Workspace {
         let zed_url = std::env::var("ZED_SERVER_URL").unwrap_or("https://zed.dev".to_string());
         let executor = cx.background_executor().clone();
 
-        let task = cx.spawn::<_, _, surf::Result<()>>(|_this, cx| async move {
+        let task = cx.spawn::<_, _, surf::Result<()>>(|this, mut cx| async move {
             let (user_id, access_token) =
                 login(zed_url.clone(), cx.platform(), cx.background_executor()).await?;
 
@@ -682,15 +682,14 @@ impl Workspace {
                 Err(anyhow!("failed to authenticate with RPC server"))?;
             }
 
-            let share_response = rpc_client
-                .request(proto::from_client::ShareWorktree {
-                    worktree_id: worktree_id as u64,
-                    files: Vec::new(),
-                })
-                .await?;
-
-            log::info!("sharing worktree {:?}", share_response);
+            let share_task = this.update(&mut cx, |this, cx| {
+                let worktree = this.worktrees.iter().next()?;
+                Some(worktree.update(cx, |worktree, cx| worktree.share(rpc_client, cx)))
+            });
 
+            if let Some(share_task) = share_task {
+                share_task.await?;
+            }
             Ok(())
         });
 

zed/src/worktree.rs 🔗

@@ -4,6 +4,7 @@ mod ignore;
 
 use crate::{
     editor::{History, Rope},
+    rpc_client::RpcClient,
     sum_tree::{self, Cursor, Edit, SumTree},
     util::Bias,
 };
@@ -31,6 +32,7 @@ use std::{
     sync::{Arc, Weak},
     time::{Duration, SystemTime, UNIX_EPOCH},
 };
+use zed_rpc::proto::{self, from_client::PathAndDigest};
 
 use self::{char_bag::CharBag, ignore::IgnoreStack};
 
@@ -52,6 +54,7 @@ pub struct Worktree {
     scan_state: (watch::Sender<ScanState>, watch::Receiver<ScanState>),
     _event_stream_handle: fsevent::Handle,
     poll_scheduled: bool,
+    rpc_client: Option<Arc<RpcClient>>,
 }
 
 #[derive(Clone, Debug)]
@@ -93,6 +96,7 @@ impl Worktree {
             scan_state: watch::channel_with(ScanState::Scanning),
             _event_stream_handle: event_stream_handle,
             poll_scheduled: false,
+            rpc_client: None,
         };
 
         std::thread::spawn(move || {
@@ -221,6 +225,39 @@ impl Worktree {
             Ok(())
         })
     }
+
+    pub fn share(
+        &mut self,
+        client: Arc<RpcClient>,
+        cx: &mut ModelContext<Self>,
+    ) -> Task<anyhow::Result<()>> {
+        self.rpc_client = Some(client.clone());
+        let snapshot = self.snapshot();
+        cx.spawn(|_this, cx| async move {
+            let files = cx
+                .background_executor()
+                .spawn(async move {
+                    snapshot
+                        .paths()
+                        .map(|path| PathAndDigest {
+                            path: path.as_os_str().as_bytes().to_vec(),
+                            digest: Default::default(),
+                        })
+                        .collect()
+                })
+                .await;
+
+            let share_response = client
+                .request(proto::from_client::ShareWorktree {
+                    worktree_id: 0,
+                    files,
+                })
+                .await?;
+
+            log::info!("sharing worktree {:?}", share_response);
+            Ok(())
+        })
+    }
 }
 
 impl Entity for Worktree {
@@ -264,7 +301,6 @@ impl Snapshot {
         FileIter::all(self, start)
     }
 
-    #[cfg(test)]
     pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> {
         self.entries
             .cursor::<(), ()>()