Update buffer's saved mtime when file is reloaded after on-disk change

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2021-10-21 12:05:44 +02:00
parent eea0f35d38
commit eb9d7c8660
2 changed files with 35 additions and 72 deletions

View File

@ -300,26 +300,20 @@ impl Buffer {
cx.emit(Event::Saved); cx.emit(Event::Saved);
} }
pub fn file_updated( pub fn file_renamed(&self, cx: &mut ModelContext<Self>) {
&mut self, cx.emit(Event::FileHandleChanged);
path: Arc<Path>,
mtime: SystemTime,
new_text: Option<String>,
cx: &mut ModelContext<Self>,
) {
let file = self.file.as_mut().unwrap();
let mut changed = false;
if path != *file.path() {
file.set_path(path);
changed = true;
} }
if mtime != file.mtime() { pub fn file_updated(
file.set_mtime(mtime); &mut self,
changed = true; new_text: String,
if let Some(new_text) = new_text { cx: &mut ModelContext<Self>,
) -> Option<Task<()>> {
if let Some(file) = self.file.as_ref() {
cx.emit(Event::FileHandleChanged);
let mtime = file.mtime();
if self.version == self.saved_version { if self.version == self.saved_version {
cx.spawn(|this, mut cx| async move { return Some(cx.spawn(|this, mut cx| async move {
let diff = this let diff = this
.read_with(&cx, |this, cx| this.diff(new_text.into(), cx)) .read_with(&cx, |this, cx| this.diff(new_text.into(), cx))
.await; .await;
@ -330,15 +324,10 @@ impl Buffer {
cx.emit(Event::Reloaded); cx.emit(Event::Reloaded);
} }
}); });
}) }));
.detach();
} }
} }
} None
if changed {
cx.emit(Event::FileHandleChanged);
}
} }
pub fn file_deleted(&mut self, cx: &mut ModelContext<Self>) { pub fn file_deleted(&mut self, cx: &mut ModelContext<Self>) {
@ -740,20 +729,6 @@ impl Buffer {
}) })
} }
pub fn set_text_from_disk(&self, new_text: Arc<str>, cx: &mut ModelContext<Self>) -> Task<()> {
cx.spawn(|this, mut cx| async move {
let diff = this
.read_with(&cx, |this, cx| this.diff(new_text, cx))
.await;
this.update(&mut cx, |this, cx| {
if this.apply_diff(diff, cx) {
this.saved_version = this.version.clone();
}
});
})
}
fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> bool { fn apply_diff(&mut self, diff: Diff, cx: &mut ModelContext<Self>) -> bool {
if self.version == diff.base_version { if self.version == diff.base_version {
self.start_transaction(None).unwrap(); self.start_transaction(None).unwrap();

View File

@ -594,20 +594,12 @@ impl Worktree {
let buffer_is_clean = !buffer.is_dirty(); let buffer_is_clean = !buffer.is_dirty();
if let Some(file) = buffer.file_mut() { if let Some(file) = buffer.file_mut() {
let mut file_changed = false;
if let Some(entry) = file if let Some(entry) = file
.entry_id() .entry_id()
.and_then(|entry_id| self.entry_for_id(entry_id)) .and_then(|entry_id| self.entry_for_id(entry_id))
{ {
if entry.path != *file.path() {
file.set_path(entry.path.clone());
file_changed = true;
}
if entry.mtime != file.mtime() { if entry.mtime != file.mtime() {
file.set_mtime(entry.mtime); file.set_mtime(entry.mtime);
file_changed = true;
if let Some(worktree) = self.as_local() { if let Some(worktree) = self.as_local() {
if buffer_is_clean { if buffer_is_clean {
let abs_path = worktree.absolutize(file.path().as_ref()); let abs_path = worktree.absolutize(file.path().as_ref());
@ -615,6 +607,11 @@ impl Worktree {
} }
} }
} }
if entry.path != *file.path() {
file.set_path(entry.path.clone());
buffer.file_renamed(cx);
}
} else if let Some(entry) = self.entry_for_path(file.path().as_ref()) { } else if let Some(entry) = self.entry_for_path(file.path().as_ref()) {
file.set_entry_id(Some(entry.id)); file.set_entry_id(Some(entry.id));
file.set_mtime(entry.mtime); file.set_mtime(entry.mtime);
@ -624,17 +621,9 @@ impl Worktree {
refresh_buffer(abs_path, &worktree.fs, cx); refresh_buffer(abs_path, &worktree.fs, cx);
} }
} }
file_changed = true;
} else if !file.is_deleted() { } else if !file.is_deleted() {
if buffer_is_clean {
cx.emit(language::Event::Dirtied);
}
file.set_entry_id(None); file.set_entry_id(None);
file_changed = true; buffer.file_deleted(cx);
}
if file_changed {
cx.emit(language::Event::FileHandleChanged);
} }
} }
}); });
@ -1186,15 +1175,14 @@ fn build_gitignore(abs_path: &Path, fs: &dyn Fs) -> Result<Gitignore> {
pub fn refresh_buffer(abs_path: PathBuf, fs: &Arc<dyn Fs>, cx: &mut ModelContext<Buffer>) { pub fn refresh_buffer(abs_path: PathBuf, fs: &Arc<dyn Fs>, cx: &mut ModelContext<Buffer>) {
let fs = fs.clone(); let fs = fs.clone();
cx.spawn(|buffer, mut cx| async move { cx.spawn(|buffer, mut cx| async move {
let new_text = fs.load(&abs_path).await; match fs.load(&abs_path).await {
match new_text {
Err(error) => log::error!("error refreshing buffer after file changed: {}", error), Err(error) => log::error!("error refreshing buffer after file changed: {}", error),
Ok(new_text) => { Ok(new_text) => {
buffer if let Some(task) =
.update(&mut cx, |buffer, cx| { buffer.update(&mut cx, |buffer, cx| buffer.file_updated(new_text, cx))
buffer.set_text_from_disk(new_text.into(), cx) {
}) task.await;
.await; }
} }
} }
}) })