diff --git a/zed-rpc/proto/zed.proto b/zed-rpc/proto/zed.proto index 8e58de7d04343fe680a887c2652d17a2fe5ef92e..d4d4406e0d594704844a1b0cd612ef6f3df01e11 100644 --- a/zed-rpc/proto/zed.proto +++ b/zed-rpc/proto/zed.proto @@ -109,6 +109,7 @@ message BufferSaved { uint64 worktree_id = 1; uint64 buffer_id = 2; repeated VectorClockEntry version = 3; + Timestamp mtime = 4; } message User { diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 4db999922dd26148d2d8032467f97614a93a5a09..304d9e3f4074221787daf5f47170407d5ced914b 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -666,7 +666,10 @@ impl Buffer { self.file.as_mut() } - pub fn save(&mut self, cx: &mut ModelContext) -> Result>> { + pub fn save( + &mut self, + cx: &mut ModelContext, + ) -> Result>> { let file = self .file .as_ref() @@ -675,11 +678,11 @@ impl Buffer { let version = self.version.clone(); let save = file.save(self.remote_id, text, version, cx.as_mut()); Ok(cx.spawn(|this, mut cx| async move { - let version = save.await?; + let (version, mtime) = save.await?; this.update(&mut cx, |this, cx| { - this.did_save(version.clone(), cx).unwrap(); + this.did_save(version.clone(), mtime, cx); }); - Ok(version) + Ok((version, mtime)) })) } @@ -702,22 +705,23 @@ impl Buffer { cx.spawn(|this, mut cx| async move { save_as.await.map(|new_file| { this.update(&mut cx, |this, cx| { + let mtime = new_file.mtime; this.file = Some(new_file); - this.did_save(version, cx).unwrap(); + this.did_save(version, mtime, cx); }); }) }) } - pub fn did_save(&mut self, version: time::Global, cx: &mut ModelContext) -> Result<()> { - if let Some(file) = self.file.as_ref() { - self.saved_mtime = file.mtime; - self.saved_version = version; - cx.emit(Event::Saved); - Ok(()) - } else { - Err(anyhow!("buffer has no file")) - } + pub fn did_save( + &mut self, + version: time::Global, + mtime: SystemTime, + cx: &mut ModelContext, + ) { + self.saved_mtime = mtime; + self.saved_version = version; + cx.emit(Event::Saved); } pub fn file_updated( @@ -3235,7 +3239,7 @@ mod tests { assert!(buffer.is_dirty()); assert_eq!(*events.borrow(), &[Event::Edited, Event::Dirtied]); events.borrow_mut().clear(); - buffer.did_save(buffer.version(), cx).unwrap(); + buffer.did_save(buffer.version(), buffer.file().unwrap().mtime, cx); }); // after saving, the buffer is not dirty, and emits a saved event. diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index dfae434742ec792880b0adbeac6a4e3c8c7c0696..cb4da11f1f8ba17de05ee92dac102678cc15edb6 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -386,7 +386,13 @@ impl Worktree { .and_then(|buf| buf.upgrade(&cx)) { buffer.update(cx, |buffer, cx| { - buffer.did_save(message.version.try_into()?, cx) + let version = message.version.try_into()?; + let mtime = message + .mtime + .ok_or_else(|| anyhow!("missing mtime"))? + .into(); + buffer.did_save(version, mtime, cx); + Result::<_, anyhow::Error>::Ok(()) })?; } Ok(()) @@ -1423,22 +1429,23 @@ impl File { text: Rope, version: time::Global, cx: &mut MutableAppContext, - ) -> Task> { + ) -> Task> { self.worktree.update(cx, |worktree, cx| match worktree { Worktree::Local(worktree) => { let rpc = worktree.rpc.clone(); let save = worktree.save(self.path.clone(), text, cx); cx.spawn(|_, _| async move { - save.await?; + let entry = save.await?; if let Some((rpc, worktree_id)) = rpc { rpc.send(proto::BufferSaved { worktree_id, buffer_id, version: (&version).into(), + mtime: Some(entry.mtime.into()), }) .await?; } - Ok(version) + Ok((version, entry.mtime)) }) } Worktree::Remote(worktree) => { @@ -1451,7 +1458,12 @@ impl File { buffer_id, }) .await?; - Ok(response.version.try_into()?) + let version = response.version.try_into()?; + let mtime = response + .mtime + .ok_or_else(|| anyhow!("missing mtime"))? + .into(); + Ok((version, mtime)) }) } }) @@ -2477,13 +2489,14 @@ mod remote { .and_then(|shared_buffers| shared_buffers.get(&envelope.payload.buffer_id).cloned()) .ok_or_else(|| anyhow!("unknown buffer id {}", envelope.payload.buffer_id)) })?; - let version = buffer.update(cx, |buffer, cx| buffer.save(cx))?.await?; + let (version, mtime) = buffer.update(cx, |buffer, cx| buffer.save(cx))?.await?; rpc.respond( envelope.receipt(), proto::BufferSaved { worktree_id: envelope.payload.worktree_id, buffer_id: envelope.payload.buffer_id, version: (&version).into(), + mtime: Some(mtime.into()), }, ) .await?;