diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 60bc5b7cf..7da96b08a 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -575,7 +575,7 @@ pub fn handle_document_write(&mut self, doc_save_event: DocumentSavedEventResult doc_save_event.revision ); - doc.set_last_saved_revision(doc_save_event.revision); + doc.set_last_saved_revision(doc_save_event.revision, doc_save_event.save_time); let lines = doc_save_event.text.len_lines(); let bytes = doc_save_event.text.len_bytes(); diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 489555112..346f04ed8 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -106,6 +106,7 @@ fn serialize(&self, serializer: S) -> Result #[derive(Debug, Clone)] pub struct DocumentSavedEvent { pub revision: usize, + pub save_time: SystemTime, pub doc_id: DocumentId, pub path: PathBuf, pub text: Rope, @@ -965,6 +966,11 @@ impl Future> + 'static + Send } .await; + let save_time = match fs::metadata(&write_path).await { + Ok(metadata) => metadata.modified().map_or(SystemTime::now(), |mtime| mtime), + Err(_) => SystemTime::now(), + }; + if let Some(backup) = backup { if write_result.is_err() { // restore backup @@ -987,6 +993,7 @@ impl Future> + 'static + Send let event = DocumentSavedEvent { revision: current_rev, + save_time, doc_id, path, text: text.clone(), @@ -1045,6 +1052,26 @@ pub fn detect_indent_and_line_ending(&mut self) { } } + pub fn pickup_last_saved_time(&mut self) { + self.last_saved_time = match self.path.as_mut().unwrap().metadata() { + Ok(metadata) => match metadata.modified() { + Ok(mtime) => mtime, + Err(_) => { + log::error!( + "Use a system time instead of fs' mtime not supported on this platform" + ); + SystemTime::now() + } + }, + Err(e) => { + log::error!( + "Use a system time instead of fs' mtime: failed to file's metadata: {e}" + ); + SystemTime::now() + } + }; + } + // Detect if the file is readonly and change the readonly field if necessary (unix only) pub fn detect_readonly(&mut self) { // Allows setting the flag for files the user cannot modify, like root files @@ -1082,9 +1109,7 @@ pub fn reload( self.apply(&transaction, view.id); self.append_changes_to_history(view); self.reset_modified(); - - self.last_saved_time = SystemTime::now(); - + self.pickup_last_saved_time(); self.detect_indent_and_line_ending(); match provider_registry.get_diff_base(&path) { @@ -1123,6 +1148,7 @@ pub fn set_path(&mut self, path: Option<&Path>) { self.path = path; self.detect_readonly(); + self.pickup_last_saved_time(); } /// Set the programming language for the file and load associated data (e.g. highlighting) @@ -1603,7 +1629,7 @@ pub fn reset_modified(&mut self) { } /// Set the document's latest saved revision to the given one. - pub fn set_last_saved_revision(&mut self, rev: usize) { + pub fn set_last_saved_revision(&mut self, rev: usize, save_time: SystemTime) { log::debug!( "doc {} revision updated {} -> {}", self.id, @@ -1611,7 +1637,7 @@ pub fn set_last_saved_revision(&mut self, rev: usize) { rev ); self.last_saved_revision = rev; - self.last_saved_time = SystemTime::now(); + self.last_saved_time = save_time; } /// Get the document's latest saved revision. diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index ba7337f22..4249db1d5 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -2083,7 +2083,7 @@ pub async fn flush_writes(&mut self) -> anyhow::Result<()> { }; let doc = doc_mut!(self, &save_event.doc_id); - doc.set_last_saved_revision(save_event.revision); + doc.set_last_saved_revision(save_event.revision, save_event.save_time); } }