diff --git a/yazi-core/src/manager/commands/bulk_rename.rs b/yazi-core/src/manager/commands/bulk_rename.rs index 2e808538..fedfef8c 100644 --- a/yazi-core/src/manager/commands/bulk_rename.rs +++ b/yazi-core/src/manager/commands/bulk_rename.rs @@ -6,7 +6,7 @@ use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}}; use yazi_config::{OPEN, PREVIEW}; use yazi_dds::Pubsub; use yazi_proxy::{AppProxy, TasksProxy, HIDER, WATCHER}; -use yazi_shared::{fs::{are_paths_equal, max_common_root, maybe_exists, File, FilesOp, Url}, terminal_clear}; +use yazi_shared::{fs::{are_names_equal, max_common_root, maybe_exists, File, FilesOp, Url}, terminal_clear}; use crate::manager::Manager; @@ -84,7 +84,7 @@ impl Manager { for (o, n) in todo { let (old, new) = (root.join(&o), root.join(&n)); - if maybe_exists(&new).await && !are_paths_equal(&old, &new).await { + if maybe_exists(&new).await && !are_names_equal(&old, &new) { failed.push((o, n, anyhow!("Destination already exists"))); } else if let Err(e) = fs::rename(&old, &new).await { failed.push((o, n, e.into())); diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index c5b303c8..39813303 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -5,7 +5,7 @@ use tokio::fs; use yazi_config::popup::InputCfg; use yazi_dds::Pubsub; use yazi_proxy::{InputProxy, TabProxy, WATCHER}; -use yazi_shared::{event::Cmd, fs::{are_paths_equal, maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}}; +use yazi_shared::{event::Cmd, fs::{are_names_equal, maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}}; use crate::manager::Manager; @@ -62,7 +62,7 @@ impl Manager { } let new = hovered.parent().unwrap().join(name); - if opt.force || !maybe_exists(&new).await || are_paths_equal(&hovered, &new).await { + if opt.force || !maybe_exists(&new).await || are_names_equal(&hovered, &new) { Self::rename_do(tab, hovered, Url::from(new)).await.ok(); return; } @@ -81,7 +81,7 @@ impl Manager { let Some(p_new) = new.parent_url() else { return Ok(()) }; let _permit = WATCHER.acquire().await.unwrap(); - let are_different = !are_paths_equal(&old, &new).await; + let are_different = !are_names_equal(&old, &new); let overwritten = symlink_realpath(&new).await; fs::rename(&old, &new).await?; diff --git a/yazi-shared/src/fs/fns.rs b/yazi-shared/src/fs/fns.rs index 45bf9885..b8edcfb6 100644 --- a/yazi-shared/src/fs/fns.rs +++ b/yazi-shared/src/fs/fns.rs @@ -24,34 +24,19 @@ pub fn ok_or_not_found(result: io::Result<()>) -> io::Result<()> { } #[inline] -pub async fn are_paths_equal(old: impl AsRef, new: impl AsRef) -> bool { - if let (Some(old), Some(new)) = ( - canonicalize_without_resolving_itself(old).await, - canonicalize_without_resolving_itself(new).await, - ) { +pub fn are_names_equal(old: impl AsRef, new: impl AsRef) -> bool { + if let (Some(old), Some(new)) = (old.as_ref().file_name(), new.as_ref().file_name()) { + let (old, new) = if cfg!(target_os = "macos") || cfg!(target_os = "windows") { + (Cow::Owned(old.to_ascii_lowercase()), Cow::Owned(new.to_ascii_lowercase())) + } else { + (Cow::Borrowed(old), Cow::Borrowed(new)) + }; old == new } else { false } } -#[inline] -async fn canonicalize_without_resolving_itself(path: impl AsRef) -> Option { - let meta = fs::symlink_metadata(&path).await.ok()?; - if meta.is_symlink() { - let (parent, link) = (path.as_ref().parent()?, path.as_ref().file_name()?); - let parent = fs::canonicalize(parent).await.ok()?; - let new_link = if cfg!(target_os = "macos") || cfg!(target_os = "windows") { - Cow::Owned(link.to_ascii_lowercase()) - } else { - Cow::Borrowed(link) - }; - Some(parent.join(new_link)) - } else { - fs::canonicalize(path).await.ok() - } -} - pub async fn symlink_realpath(path: &Path) -> Result { let p = fs::canonicalize(path).await?; if p == path {