Skip to content

Commit

Permalink
Use fs' mtime to avoid saving problem on out-of-synced network fs (he…
Browse files Browse the repository at this point in the history
…lix-editor#11142)

In the case of network file systems, if the server time is ahead
of the local system time, then helix could annoy with messages
that the file has already been modified by another application.
  • Loading branch information
noktoborus authored and plul committed Oct 13, 2024
1 parent ebc7834 commit f7804d3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
2 changes: 1 addition & 1 deletion helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ impl Application {
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();
Expand Down
36 changes: 31 additions & 5 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ impl Serialize for Mode {
#[derive(Debug, Clone)]
pub struct DocumentSavedEvent {
pub revision: usize,
pub save_time: SystemTime,
pub doc_id: DocumentId,
pub path: PathBuf,
pub text: Rope,
Expand Down Expand Up @@ -965,6 +966,11 @@ impl Document {
}
.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
Expand All @@ -987,6 +993,7 @@ impl Document {

let event = DocumentSavedEvent {
revision: current_rev,
save_time,
doc_id,
path,
text: text.clone(),
Expand Down Expand Up @@ -1045,6 +1052,26 @@ impl Document {
}
}

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
Expand Down Expand Up @@ -1082,9 +1109,7 @@ impl Document {
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) {
Expand Down Expand Up @@ -1123,6 +1148,7 @@ impl Document {
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)
Expand Down Expand Up @@ -1603,15 +1629,15 @@ impl Document {
}

/// 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,
self.last_saved_revision,
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.
Expand Down
2 changes: 1 addition & 1 deletion helix-view/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2083,7 +2083,7 @@ impl Editor {
};

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);
}
}

Expand Down

0 comments on commit f7804d3

Please sign in to comment.