From 5b9f5f9fdb7d1729dad6e3ded65ae639878fddd1 Mon Sep 17 00:00:00 2001 From: Kirawi <67773714+kirawi@users.noreply.github.com> Date: Mon, 20 May 2024 17:46:24 -0400 Subject: [PATCH] Handle relative symlinks on write (#10790) try again try wip --- helix-term/tests/test/commands/write.rs | 45 +++++++++++++++++++++++++ helix-view/src/document.rs | 10 +++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/helix-term/tests/test/commands/write.rs b/helix-term/tests/test/commands/write.rs index 350f34aab..4db98a046 100644 --- a/helix-term/tests/test/commands/write.rs +++ b/helix-term/tests/test/commands/write.rs @@ -604,6 +604,51 @@ async fn test_symlink_write_fail() -> anyhow::Result<()> { Ok(()) } +#[tokio::test(flavor = "multi_thread")] +async fn test_symlink_write_relative() -> anyhow::Result<()> { + #[cfg(unix)] + use std::os::unix::fs::symlink; + #[cfg(not(unix))] + use std::os::windows::fs::symlink_file as symlink; + + // tempdir + // |- - b + // | |- file + // |- linked (symlink to file) + let dir = tempfile::tempdir()?; + let inner_dir = dir.path().join("b"); + std::fs::create_dir(&inner_dir)?; + + let mut file = tempfile::NamedTempFile::new_in(&inner_dir)?; + let symlink_path = dir.path().join("linked"); + let relative_path = std::path::PathBuf::from("b").join(file.path().file_name().unwrap()); + symlink(relative_path, &symlink_path)?; + + let mut app = helpers::AppBuilder::new() + .with_file(&symlink_path, None) + .build()?; + + test_key_sequence( + &mut app, + Some("ithe gostak distims the doshes:w"), + None, + false, + ) + .await?; + + reload_file(&mut file).unwrap(); + let mut file_content = String::new(); + file.as_file_mut().read_to_string(&mut file_content)?; + + assert_eq!( + LineFeedHandling::Native.apply("the gostak distims the doshes"), + file_content + ); + assert!(symlink_path.is_symlink()); + + Ok(()) +} + async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> { let mut file = tempfile::NamedTempFile::new()?; diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index b8d318bb8..23b597a36 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -895,7 +895,15 @@ impl Future> + 'static + Send } let write_path = tokio::fs::read_link(&path) .await - .unwrap_or_else(|_| path.clone()); + .ok() + .and_then(|p| { + if p.is_relative() { + path.parent().map(|parent| parent.join(p)) + } else { + Some(p) + } + }) + .unwrap_or_else(|| path.clone()); if readonly(&write_path) { bail!(std::io::Error::new(