Wait for version before returning code actions

Antonio Scandurra created

Change summary

crates/lsp/src/lsp.rs         |  8 +++++---
crates/project/src/project.rs | 11 +++++++++--
crates/rpc/proto/zed.proto    |  1 +
3 files changed, 15 insertions(+), 5 deletions(-)

Detailed changes

crates/lsp/src/lsp.rs 🔗

@@ -521,7 +521,7 @@ impl LanguageServer {
 #[cfg(any(test, feature = "test-support"))]
 impl FakeLanguageServer {
     fn new(
-        executor: Arc<gpui::executor::Background>,
+        background: Arc<gpui::executor::Background>,
         stdin: async_pipe::PipeReader,
         stdout: async_pipe::PipeWriter,
     ) -> Self {
@@ -537,11 +537,13 @@ impl FakeLanguageServer {
 
         // Receive incoming messages
         let handlers = this.handlers.clone();
-        executor
+        let executor = background.clone();
+        background
             .spawn(async move {
                 let mut buffer = Vec::new();
                 let mut stdin = smol::io::BufReader::new(stdin);
                 while Self::receive(&mut stdin, &mut buffer).await.is_ok() {
+                    executor.simulate_random_delay().await;
                     if let Ok(request) = serde_json::from_slice::<AnyRequest>(&buffer) {
                         assert_eq!(request.jsonrpc, JSON_RPC_VERSION);
 
@@ -571,7 +573,7 @@ impl FakeLanguageServer {
             .detach();
 
         // Send outgoing messages
-        executor
+        background
             .spawn(async move {
                 let mut stdout = smol::io::BufWriter::new(stdout);
                 while let Some(notification) = outgoing_rx.next().await {

crates/project/src/project.rs 🔗

@@ -1578,8 +1578,7 @@ impl Project {
             })
         } else if let Some(project_id) = self.remote_id() {
             let rpc = self.client.clone();
-            cx.foreground().spawn(async move {
-                let _buffer = buffer_handle.clone();
+            cx.spawn_weak(|_, mut cx| async move {
                 let response = rpc
                     .request(proto::GetCodeActions {
                         project_id,
@@ -1588,6 +1587,13 @@ impl Project {
                         end: Some(language::proto::serialize_anchor(&range.end)),
                     })
                     .await?;
+
+                buffer_handle
+                    .update(&mut cx, |buffer, _| {
+                        buffer.wait_for_version(response.version.into())
+                    })
+                    .await;
+
                 response
                     .actions
                     .into_iter()
@@ -2448,6 +2454,7 @@ impl Project {
                 .iter()
                 .map(language::proto::serialize_code_action)
                 .collect(),
+            version: (&version).into(),
         })
     }
 

crates/rpc/proto/zed.proto 🔗

@@ -261,6 +261,7 @@ message GetCodeActions {
 
 message GetCodeActionsResponse {
     repeated CodeAction actions = 1;
+    repeated VectorClockEntry version = 2;
 }
 
 message ApplyCodeAction {