Added proto messages for updating the head text

Mikayla Maki created

Change summary

crates/collab/src/integration_tests.rs |  3 -
crates/collab/src/rpc.rs               | 18 ++++++++++
crates/project/src/project.rs          | 46 ++++++++++++++++++++++++++-
crates/rpc/proto/zed.proto             |  7 ++++
crates/rpc/src/proto.rs                |  2 +
5 files changed, 69 insertions(+), 7 deletions(-)

Detailed changes

crates/collab/src/integration_tests.rs 🔗

@@ -1065,9 +1065,6 @@ async fn test_git_head_text(
         );
     });
 
-    //TODO: WAIT FOR REMOTE UPDATES TO FINISH on B
-    executor.run_until_parked();
-
     // Smoke test B
     buffer_b.read_with(cx_b, |buffer, _| {
         assert_eq!(buffer.head_text(), Some(new_head_text.as_ref()));

crates/collab/src/rpc.rs 🔗

@@ -205,7 +205,8 @@ impl Server {
             .add_request_handler(Server::follow)
             .add_message_handler(Server::unfollow)
             .add_message_handler(Server::update_followers)
-            .add_request_handler(Server::get_channel_messages);
+            .add_request_handler(Server::get_channel_messages)
+            .add_message_handler(Server::update_head_text);
 
         Arc::new(server)
     }
@@ -1727,6 +1728,21 @@ impl Server {
         Ok(())
     }
 
+    async fn update_head_text(
+        self: Arc<Server>,
+        request: TypedEnvelope<proto::UpdateHeadText>,
+    ) -> Result<()> {
+        let receiver_ids = self.store().await.project_connection_ids(
+            ProjectId::from_proto(request.payload.project_id),
+            request.sender_id,
+        )?;
+        broadcast(request.sender_id, receiver_ids, |connection_id| {
+            self.peer
+                .forward_send(request.sender_id, connection_id, request.payload.clone())
+        });
+        Ok(())
+    }
+
     pub(crate) async fn store(&self) -> StoreGuard<'_> {
         #[cfg(test)]
         tokio::task::yield_now().await;

crates/project/src/project.rs 🔗

@@ -8,7 +8,10 @@ pub mod worktree;
 mod project_tests;
 
 use anyhow::{anyhow, Context, Result};
-use client::{proto, Client, PeerId, TypedEnvelope, User, UserStore};
+use client::{
+    proto::{self},
+    Client, PeerId, TypedEnvelope, User, UserStore,
+};
 use clock::ReplicaId;
 use collections::{hash_map, BTreeMap, HashMap, HashSet};
 use futures::{future::Shared, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt};
@@ -421,6 +424,7 @@ impl Project {
         client.add_model_request_handler(Self::handle_open_buffer_by_id);
         client.add_model_request_handler(Self::handle_open_buffer_by_path);
         client.add_model_request_handler(Self::handle_save_buffer);
+        client.add_model_message_handler(Self::handle_update_head_text);
     }
 
     pub fn local(
@@ -4667,14 +4671,29 @@ impl Project {
                     None => return,
                 };
 
+                let shared_remote_id = self.shared_remote_id();
+                let client = self.client.clone();
+
                 cx.spawn(|_, mut cx| async move {
                     let head_text = cx
                         .background()
                         .spawn(async move { repo.repo.lock().load_head_text(&path) })
                         .await;
-                    buffer.update(&mut cx, |buffer, cx| {
-                        buffer.update_head_text(head_text, cx);
+
+                    let buffer_id = buffer.update(&mut cx, |buffer, cx| {
+                        buffer.update_head_text(head_text.clone(), cx);
+                        buffer.remote_id()
                     });
+
+                    if let Some(project_id) = shared_remote_id {
+                        client
+                            .send(proto::UpdateHeadText {
+                                project_id,
+                                buffer_id: buffer_id as u64,
+                                head_text,
+                            })
+                            .log_err();
+                    }
                 })
                 .detach();
             }
@@ -5253,6 +5272,27 @@ impl Project {
         })
     }
 
+    async fn handle_update_head_text(
+        this: ModelHandle<Self>,
+        envelope: TypedEnvelope<proto::UpdateHeadText>,
+        _: Arc<Client>,
+        mut cx: AsyncAppContext,
+    ) -> Result<()> {
+        this.update(&mut cx, |this, cx| {
+            let buffer_id = envelope.payload.buffer_id;
+            let head_text = envelope.payload.head_text;
+            let buffer = this
+                .opened_buffers
+                .get_mut(&buffer_id)
+                .and_then(|b| b.upgrade(cx))
+                .ok_or_else(|| anyhow!("No such buffer {}", buffer_id))?;
+
+            buffer.update(cx, |buffer, cx| buffer.update_head_text(head_text, cx));
+
+            Ok(())
+        })
+    }
+
     async fn handle_update_buffer_file(
         this: ModelHandle<Self>,
         envelope: TypedEnvelope<proto::UpdateBufferFile>,

crates/rpc/proto/zed.proto 🔗

@@ -108,6 +108,7 @@ message Envelope {
         FollowResponse follow_response = 93;
         UpdateFollowers update_followers = 94;
         Unfollow unfollow = 95;
+        UpdateHeadText update_head_text = 96;
     }
 }
 
@@ -992,3 +993,9 @@ message WorktreeMetadata {
     string root_name = 2;
     bool visible = 3;
 }
+
+message UpdateHeadText {
+    uint64 project_id = 1;
+    uint64 buffer_id = 2;
+    optional string head_text = 3;
+}

crates/rpc/src/proto.rs 🔗

@@ -167,6 +167,7 @@ messages!(
     (UpdateProject, Foreground),
     (UpdateWorktree, Foreground),
     (UpdateWorktreeExtensions, Background),
+    (UpdateHeadText, Background),
 );
 
 request_messages!(
@@ -263,6 +264,7 @@ entity_messages!(
     UpdateProject,
     UpdateWorktree,
     UpdateWorktreeExtensions,
+    UpdateHeadText
 );
 
 entity_messages!(channel_id, ChannelMessageSent);