Only send UpdateBufferFile messages for buffers whose files have changed

Max Brunsfeld created

Send that message when saving a buffer as a new path.

Change summary

crates/language/src/buffer.rs       |  5 ---
crates/project/src/project.rs       | 23 ++++++++------
crates/project/src/project_tests.rs |  1 
crates/project/src/worktree.rs      | 50 ++++++++++++++++++------------
4 files changed, 43 insertions(+), 36 deletions(-)

Detailed changes

crates/language/src/buffer.rs 🔗

@@ -549,16 +549,11 @@ impl Buffer {
         version: clock::Global,
         fingerprint: RopeFingerprint,
         mtime: SystemTime,
-        new_file: Option<Arc<dyn File>>,
         cx: &mut ModelContext<Self>,
     ) {
         self.saved_version = version;
         self.saved_version_fingerprint = fingerprint;
         self.saved_mtime = mtime;
-        if let Some(new_file) = new_file {
-            self.file = Some(new_file);
-            self.file_update_count += 1;
-        }
         cx.emit(Event::Saved);
         cx.notify();
     }

crates/project/src/project.rs 🔗

@@ -4461,16 +4461,19 @@ impl Project {
                             renamed_buffers.push((cx.handle(), old_path));
                         }
 
-                        if let Some(project_id) = self.remote_id() {
-                            self.client
-                                .send(proto::UpdateBufferFile {
-                                    project_id,
-                                    buffer_id: *buffer_id as u64,
-                                    file: Some(new_file.to_proto()),
-                                })
-                                .log_err();
+                        if new_file != *old_file {
+                            if let Some(project_id) = self.remote_id() {
+                                self.client
+                                    .send(proto::UpdateBufferFile {
+                                        project_id,
+                                        buffer_id: *buffer_id as u64,
+                                        file: Some(new_file.to_proto()),
+                                    })
+                                    .log_err();
+                            }
+
+                            buffer.file_updated(Arc::new(new_file), cx).detach();
                         }
-                        buffer.file_updated(Arc::new(new_file), cx).detach();
                     }
                 });
             } else {
@@ -6054,7 +6057,7 @@ impl Project {
                 .and_then(|buffer| buffer.upgrade(cx));
             if let Some(buffer) = buffer {
                 buffer.update(cx, |buffer, cx| {
-                    buffer.did_save(version, fingerprint, mtime, None, cx);
+                    buffer.did_save(version, fingerprint, mtime, cx);
                 });
             }
             Ok(())

crates/project/src/project_tests.rs 🔗

@@ -2482,7 +2482,6 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) {
             buffer.version(),
             buffer.as_rope().fingerprint(),
             buffer.file().unwrap().mtime(),
-            None,
             cx,
         );
     });

crates/project/src/worktree.rs 🔗

@@ -20,6 +20,7 @@ use gpui::{
     executor, AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, MutableAppContext,
     Task,
 };
+use language::File as _;
 use language::{
     proto::{
         deserialize_fingerprint, deserialize_version, serialize_fingerprint, serialize_line_ending,
@@ -728,7 +729,7 @@ impl LocalWorktree {
         &self,
         buffer_handle: ModelHandle<Buffer>,
         path: Arc<Path>,
-        replace_file: bool,
+        has_changed_file: bool,
         cx: &mut ModelContext<Worktree>,
     ) -> Task<Result<(clock::Global, RopeFingerprint, SystemTime)>> {
         let handle = cx.handle();
@@ -746,6 +747,32 @@ impl LocalWorktree {
         cx.as_mut().spawn(|mut cx| async move {
             let entry = save.await?;
 
+            if has_changed_file {
+                let new_file = Arc::new(File {
+                    entry_id: entry.id,
+                    worktree: handle,
+                    path: entry.path,
+                    mtime: entry.mtime,
+                    is_local: true,
+                    is_deleted: false,
+                });
+
+                if let Some(project_id) = project_id {
+                    rpc.send(proto::UpdateBufferFile {
+                        project_id,
+                        buffer_id,
+                        file: Some(new_file.to_proto()),
+                    })
+                    .log_err();
+                }
+
+                buffer_handle.update(&mut cx, |buffer, cx| {
+                    if has_changed_file {
+                        buffer.file_updated(new_file, cx).detach();
+                    }
+                });
+            }
+
             if let Some(project_id) = project_id {
                 rpc.send(proto::BufferSaved {
                     project_id,
@@ -757,24 +784,7 @@ impl LocalWorktree {
             }
 
             buffer_handle.update(&mut cx, |buffer, cx| {
-                buffer.did_save(
-                    version.clone(),
-                    fingerprint,
-                    entry.mtime,
-                    if replace_file {
-                        Some(Arc::new(File {
-                            entry_id: entry.id,
-                            worktree: handle,
-                            path: entry.path,
-                            mtime: entry.mtime,
-                            is_local: true,
-                            is_deleted: false,
-                        }))
-                    } else {
-                        None
-                    },
-                    cx,
-                );
+                buffer.did_save(version.clone(), fingerprint, entry.mtime, cx);
             });
 
             Ok((version, fingerprint, entry.mtime))
@@ -1137,7 +1147,7 @@ impl RemoteWorktree {
                 .into();
 
             buffer_handle.update(&mut cx, |buffer, cx| {
-                buffer.did_save(version.clone(), fingerprint, mtime, None, cx);
+                buffer.did_save(version.clone(), fingerprint, mtime, cx);
             });
 
             Ok((version, fingerprint, mtime))