Add ability to configure atomic saving

pull/13656/head
Isaac Mills 2025-05-30 10:16:47 -06:00
parent 8961ae1dc6
commit faa6736d29
No known key found for this signature in database
GPG Key ID: B67D7410F33A0F61
3 changed files with 23 additions and 1 deletions

View File

@ -34,6 +34,7 @@ pub struct EditorConfig {
// pub spelling_language: Option<SpellingLanguage>,
pub trim_trailing_whitespace: Option<bool>,
pub insert_final_newline: Option<bool>,
pub atomic_save: Option<bool>,
pub max_line_length: Option<NonZeroU16>,
}
@ -159,6 +160,13 @@ impl EditorConfig {
"false" => Some(false),
_ => None,
});
let atomic_save = pairs
.get("atomic_save")
.and_then(|value| match value.as_ref() {
"true" => Some(true),
"false" => Some(false),
_ => None,
});
// This option is not in the spec but is supported by some editors.
// <https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#max_line_length>
let max_line_length = pairs
@ -172,6 +180,7 @@ impl EditorConfig {
encoding,
trim_trailing_whitespace,
insert_final_newline,
atomic_save,
max_line_length,
}
}
@ -305,6 +314,7 @@ mod test {
[docs/**.txt]
insert_final_newline = true
atomic_write = true
"#;
assert_eq!(
@ -326,6 +336,7 @@ mod test {
EditorConfig {
indent_style: Some(IndentStyle::Spaces(4)),
insert_final_newline: Some(true),
atomic_save: Some(true),
..Default::default()
}
);

View File

@ -980,6 +980,7 @@ impl Document {
// mark changes up to now as saved
let current_rev = self.get_current_revision();
let doc_id = self.id();
let atomic_write = self.atomic_save();
let encoding_with_bom_info = (self.encoding, self.has_bom);
let last_saved_time = self.last_saved_time;
@ -1029,7 +1030,7 @@ impl Document {
// Assume it is a hardlink to prevent data loss if the metadata cant be read (e.g. on certain Windows configurations)
let is_hardlink = helix_stdx::faccess::hardlink_count(&write_path).unwrap_or(2) > 1;
let backup = if path.exists() {
let backup = if path.exists() && atomic_write {
let path_ = write_path.clone();
// hacks: we use tempfile to handle the complex task of creating
// non clobbered temporary path for us we don't want
@ -1914,6 +1915,13 @@ impl Document {
.unwrap_or_else(|| self.config.load().insert_final_newline)
}
/// Whether the document should write it's contents to a backup file, then rename the backup to the target file when saving. This prevents data loss when saving, but may confuse some file watching/hot reloading programs.
pub fn atomic_save(&self) -> bool {
self.editor_config
.atomic_save
.unwrap_or_else(|| self.config.load().atomic_save)
}
/// Whether the document should trim whitespace preceding line endings on save.
pub fn trim_trailing_whitespace(&self) -> bool {
self.editor_config

View File

@ -346,6 +346,8 @@ pub struct Config {
pub default_line_ending: LineEndingConfig,
/// Whether to automatically insert a trailing line-ending on write if missing. Defaults to `true`.
pub insert_final_newline: bool,
/// Whether the document should write it's contents to a backup file, then rename the backup to the target file when saving. This prevents data loss when saving, but may confuse some file watching/hot reloading programs. Defaults to `true`
pub atomic_save: bool,
/// Whether to automatically remove all trailing line-endings after the final one on write.
/// Defaults to `false`.
pub trim_final_newlines: bool,
@ -1017,6 +1019,7 @@ impl Default for Config {
workspace_lsp_roots: Vec::new(),
default_line_ending: LineEndingConfig::default(),
insert_final_newline: true,
atomic_save: true,
trim_final_newlines: false,
trim_trailing_whitespace: false,
smart_tab: Some(SmartTabConfig::default()),