diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs index 0c56f8f9c4b7b..e2acf373733ad 100644 --- a/helix-core/src/history.rs +++ b/helix-core/src/history.rs @@ -190,7 +190,6 @@ const UNDO_FILE_HEADER_LEN: usize = UNDO_FILE_HEADER_TAG.len(); const UNDO_FILE_VERSION: u8 = 1; impl History { - // TODO: Vim uses magic numbers for each revision. Why? pub fn serialize( &self, writer: &mut W, @@ -212,7 +211,6 @@ impl History { writer.write_all(&get_hash(&mut std::fs::File::open(path)?)?)?; // Append new revisions to the end of the file. - // TODO: Recompute hash on append write_usize(writer, self.revisions.len())?; writer.seek(SeekFrom::End(0))?; for rev in &self.revisions[last_saved_revision..] { @@ -279,10 +277,12 @@ impl History { if new_revs.is_empty() { return Ok(()); } + other.revisions.reserve_exact(n); // Only unique revisions in `self` matter, so saturating_sub(1) is sound as it going to 0 means there are no new revisions in the other history that aren't in `self` let offset = (other.revisions.len() - n).saturating_sub(1); for mut r in new_revs { + // Update parents of new revisions if r.parent >= n { r.parent += offset; } diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index f7814cf512fa2..77958cf62fcab 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -922,7 +922,6 @@ impl Document { } } - // TODO: Check error handling let has_valid_undofile = if undofile_enabled { let path = path.clone(); let undofile_path = undofile_path.clone(); @@ -970,20 +969,26 @@ impl Document { }; // Set undofile perms - // TODO: Vim does (perm & 0707) | ((perm & 07) << 3) #[cfg(unix)] if undofile_enabled && undofile_res.is_ok() && undofile_path.as_ref().unwrap().exists() { + use std::os::unix::ffi::OsStrExt; + use std::os::unix::fs::{MetadataExt, PermissionsExt}; let meta = tokio::fs::metadata(path.as_path()).await?; // From https://github.com/uutils/coreutils/blob/2c73e978ba882c9cd56f0f16fae6f8dcce1c9850/src/uucore/src/lib/features/perms.rs#L46-L61 - use std::os::unix::ffi::OsStrExt; - use std::os::unix::fs::MetadataExt; let uid = meta.uid(); let gid = meta.gid(); let s = std::ffi::CString::new(path.as_os_str().as_bytes())?; let ret = unsafe { libc::chown(s.as_ptr(), uid, gid) }; if ret != 0 { + let mut perms = meta.permissions(); + let new_perms = (perms.mode() & 0x0707) | (perms.mode() & 0x07) << 3; + perms.set_mode(new_perms); + + // Ignore errors + let _ = tokio::fs::set_permissions(&undofile_path.unwrap(), perms).await; + undofile_res = Err(anyhow::anyhow!(tokio::io::Error::last_os_error())); }