mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
b303219b99
commit
8eb2eea5cc
4 changed files with 29 additions and 10 deletions
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use yazi_config::popup::InputCfg;
|
use yazi_config::popup::InputCfg;
|
||||||
use yazi_proxy::{InputProxy, TabProxy, WATCHER};
|
use yazi_proxy::{InputProxy, TabProxy, WATCHER};
|
||||||
use yazi_shared::{event::Cmd, fs::{maybe_exists, ok_or_not_found, File, FilesOp, Url}};
|
use yazi_shared::{event::Cmd, fs::{maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}};
|
||||||
|
|
||||||
use crate::manager::Manager;
|
use crate::manager::Manager;
|
||||||
|
|
||||||
|
|
@ -47,6 +47,10 @@ impl Manager {
|
||||||
|
|
||||||
if dir {
|
if dir {
|
||||||
fs::create_dir_all(&new).await?;
|
fs::create_dir_all(&new).await?;
|
||||||
|
} else if let Ok(real) = symlink_realpath(&new).await {
|
||||||
|
ok_or_not_found(fs::remove_file(&new).await)?;
|
||||||
|
FilesOp::Deleting(parent.clone(), vec![Url::from(real)]).emit();
|
||||||
|
fs::File::create(&new).await?;
|
||||||
} else {
|
} else {
|
||||||
fs::create_dir_all(&parent).await.ok();
|
fs::create_dir_all(&parent).await.ok();
|
||||||
ok_or_not_found(fs::remove_file(&new).await)?;
|
ok_or_not_found(fs::remove_file(&new).await)?;
|
||||||
|
|
@ -54,7 +58,7 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(f) = File::from(new.clone()).await {
|
if let Ok(f) = File::from(new.clone()).await {
|
||||||
FilesOp::Upserting(parent, HashMap::from_iter([(new.clone(), f)])).emit();
|
FilesOp::Upserting(parent, HashMap::from_iter([(f.url(), f)])).emit();
|
||||||
TabProxy::reveal(&new)
|
TabProxy::reveal(&new)
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use tokio::fs;
|
||||||
use yazi_config::popup::InputCfg;
|
use yazi_config::popup::InputCfg;
|
||||||
use yazi_dds::Pubsub;
|
use yazi_dds::Pubsub;
|
||||||
use yazi_proxy::{InputProxy, TabProxy, WATCHER};
|
use yazi_proxy::{InputProxy, TabProxy, WATCHER};
|
||||||
use yazi_shared::{event::Cmd, fs::{maybe_exists, File, FilesOp, Url}};
|
use yazi_shared::{event::Cmd, fs::{maybe_exists, ok_or_not_found, symlink_realpath, File, FilesOp, Url}};
|
||||||
|
|
||||||
use crate::manager::Manager;
|
use crate::manager::Manager;
|
||||||
|
|
||||||
|
|
@ -81,7 +81,13 @@ impl Manager {
|
||||||
let Some(p_new) = new.parent_url() else { return Ok(()) };
|
let Some(p_new) = new.parent_url() else { return Ok(()) };
|
||||||
let _permit = WATCHER.acquire().await.unwrap();
|
let _permit = WATCHER.acquire().await.unwrap();
|
||||||
|
|
||||||
|
let overwritten = symlink_realpath(&new).await;
|
||||||
fs::rename(&old, &new).await?;
|
fs::rename(&old, &new).await?;
|
||||||
|
|
||||||
|
if let Ok(p) = overwritten {
|
||||||
|
ok_or_not_found(fs::rename(&p, &new).await)?;
|
||||||
|
FilesOp::Deleting(p_new.clone(), vec![Url::from(p)]).emit();
|
||||||
|
}
|
||||||
Pubsub::pub_from_rename(tab, &old, &new);
|
Pubsub::pub_from_rename(tab, &old, &new);
|
||||||
|
|
||||||
let file = File::from(new.clone()).await?;
|
let file = File::from(new.clone()).await?;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use yazi_plugin::isolate;
|
use yazi_plugin::isolate;
|
||||||
use yazi_proxy::WATCHER;
|
use yazi_proxy::WATCHER;
|
||||||
use yazi_shared::{fs::{symlink_realpath, File, FilesOp, Url}, RoCell};
|
use yazi_shared::{fs::{symlink_realpath_with, File, FilesOp, Url}, RoCell};
|
||||||
|
|
||||||
use super::Linked;
|
use super::Linked;
|
||||||
use crate::folder::{Files, Folder};
|
use crate::folder::{Files, Folder};
|
||||||
|
|
@ -111,7 +111,7 @@ impl Watcher {
|
||||||
};
|
};
|
||||||
|
|
||||||
let realpath = if file.is_link() {
|
let realpath = if file.is_link() {
|
||||||
symlink_realpath(&url, &mut cached).await
|
symlink_realpath_with(&url, &mut cached).await
|
||||||
} else {
|
} else {
|
||||||
fs::canonicalize(&url).await.map(Cow::Owned)
|
fs::canonicalize(&url).await.map(Cow::Owned)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,23 +24,32 @@ pub fn ok_or_not_found(result: io::Result<()>) -> io::Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub async fn symlink_realpath(path: &Path) -> io::Result<PathBuf> {
|
||||||
|
if fs::symlink_metadata(path).await?.is_symlink() {
|
||||||
|
symlink_realpath_with(path, &mut HashMap::new()).await.map(|p| p.into_owned())
|
||||||
|
} else {
|
||||||
|
fs::canonicalize(path).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// realpath(3) without resolving symlinks. This is useful for case-insensitive
|
// realpath(3) without resolving symlinks. This is useful for case-insensitive
|
||||||
// filesystems.
|
// filesystems.
|
||||||
//
|
//
|
||||||
// Make sure the file of the path exists and is a symlink.
|
// Make sure the file of the path exists and is a symlink.
|
||||||
pub async fn symlink_realpath<'a>(
|
pub async fn symlink_realpath_with<'a>(
|
||||||
path: &'a Path,
|
path: &'a Path,
|
||||||
cached: &'a mut HashMap<PathBuf, PathBuf>,
|
cached: &'a mut HashMap<PathBuf, PathBuf>,
|
||||||
) -> io::Result<Cow<'a, Path>> {
|
) -> io::Result<Cow<'a, Path>> {
|
||||||
let Some(parent) = path.parent() else {
|
|
||||||
return Ok(Cow::Borrowed(path));
|
|
||||||
};
|
|
||||||
|
|
||||||
let lowercased: PathBuf = path.as_os_str().to_ascii_lowercase().into();
|
let lowercased: PathBuf = path.as_os_str().to_ascii_lowercase().into();
|
||||||
if lowercased == path {
|
if lowercased == path {
|
||||||
return Ok(Cow::Borrowed(path));
|
return Ok(Cow::Borrowed(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Some(parent) = path.parent() else {
|
||||||
|
return Ok(Cow::Borrowed(path));
|
||||||
|
};
|
||||||
|
|
||||||
let case = parent.as_os_str().as_encoded_bytes().iter().any(|&b| b.is_ascii_uppercase());
|
let case = parent.as_os_str().as_encoded_bytes().iter().any(|&b| b.is_ascii_uppercase());
|
||||||
if !cached.contains_key(parent) {
|
if !cached.contains_key(parent) {
|
||||||
let mut it = fs::read_dir(parent).await?;
|
let mut it = fs::read_dir(parent).await?;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue