From 4ce51c813841af211fb9b36284f4df4db6078a53 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 9 Mar 2023 07:26:22 +0100 Subject: [PATCH] Limit dirty buffer save optimization to multi-buffers --- crates/editor/src/items.rs | 31 ++++++++++++++++++++++++++++--- crates/project/src/project.rs | 14 +------------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 0d594a66ef354ab49152a2e0e3d318592f6c3233..cda702de00f6411e10bda7ad890d8136688ebf42 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -612,9 +612,34 @@ impl Item for Editor { let buffers = self.buffer().clone().read(cx).all_buffers(); cx.as_mut().spawn(|mut cx| async move { format.await?; - project - .update(&mut cx, |project, cx| project.save_buffers(buffers, cx)) - .await?; + + if buffers.len() == 1 { + project + .update(&mut cx, |project, cx| project.save_buffers(buffers, cx)) + .await?; + } else { + // For multi-buffers, only save those ones that contain changes. For clean buffers + // we simulate saving by calling `Buffer::did_save`, so that language servers or + // other downstream listeners of save events get notified. + let (dirty_buffers, clean_buffers) = buffers.into_iter().partition(|buffer| { + buffer.read_with(&cx, |buffer, _| buffer.is_dirty() || buffer.has_conflict()) + }); + + project + .update(&mut cx, |project, cx| { + project.save_buffers(dirty_buffers, cx) + }) + .await?; + for buffer in clean_buffers { + buffer.update(&mut cx, |buffer, cx| { + let version = buffer.saved_version().clone(); + let fingerprint = buffer.saved_version_fingerprint(); + let mtime = buffer.saved_mtime(); + buffer.did_save(version, fingerprint, mtime, cx); + }); + } + } + Ok(()) }) } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index f93de8e1d847d263dad2526dbcaaa77b0571b118..2ebea8d07dad811a378a065a7f666caaf594c6d3 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -1434,19 +1434,7 @@ impl Project { let worktree = file.worktree.clone(); let path = file.path.clone(); worktree.update(cx, |worktree, cx| match worktree { - Worktree::Local(worktree) => { - if buffer.read(cx).is_dirty() || buffer.read(cx).has_conflict() { - worktree.save_buffer(buffer, path, false, cx) - } else { - buffer.update(cx, |buffer, cx| { - let version = buffer.saved_version().clone(); - let fingerprint = buffer.saved_version_fingerprint(); - let mtime = buffer.saved_mtime(); - buffer.did_save(version.clone(), fingerprint, mtime, cx); - Task::ready(Ok((version, fingerprint, mtime))) - }) - } - } + Worktree::Local(worktree) => worktree.save_buffer(buffer, path, false, cx), Worktree::Remote(worktree) => worktree.save_buffer(buffer, cx), }) }