mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: renaming empty files into directories
This commit is contained in:
parent
41e5717930
commit
29a610d389
1 changed files with 49 additions and 4 deletions
|
|
@ -4,8 +4,12 @@ use yazi_dds::Pubsub;
|
|||
use yazi_fs::{File, FilesOp};
|
||||
use yazi_macro::{act, err, ok_or_not_found, succ};
|
||||
use yazi_parser::mgr::RenameOpt;
|
||||
use yazi_proxy::{ConfirmProxy, InputProxy, MgrProxy};
|
||||
use yazi_shared::{Id, data::Data, url::{UrlBuf, UrlLike}};
|
||||
use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, MgrProxy};
|
||||
use yazi_shared::{
|
||||
Id,
|
||||
data::Data,
|
||||
url::{UrlBuf, UrlLike},
|
||||
};
|
||||
use yazi_vfs::{VfsFile, maybe_exists, provider};
|
||||
use yazi_watcher::WATCHER;
|
||||
|
||||
|
|
@ -40,6 +44,9 @@ impl Actor for Rename {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let target_is_file = hovered.is_file();
|
||||
let target_is_empty = hovered.len == 0;
|
||||
|
||||
let (tab, old) = (cx.tab().id, hovered.url_owned());
|
||||
let mut input = InputProxy::show(InputCfg::rename().with_value(name).with_cursor(cursor));
|
||||
|
||||
|
|
@ -49,14 +56,29 @@ impl Actor for Rename {
|
|||
return;
|
||||
}
|
||||
|
||||
let conversion_to_dir_requested =
|
||||
target_is_file && (name.ends_with('/') || name.ends_with('\\'));
|
||||
if conversion_to_dir_requested && !target_is_empty {
|
||||
AppProxy::notify_warn("Rename", "Only empty files may be converted to directories");
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(Ok(new)) = old.parent().map(|u| u.try_join(name)) else {
|
||||
return;
|
||||
};
|
||||
|
||||
if opt.force || !maybe_exists(&new).await || provider::must_identical(&old, &new).await {
|
||||
Self::r#do(tab, old, new).await.ok();
|
||||
if conversion_to_dir_requested && target_is_empty {
|
||||
Self::replace_file_with_dir(old, new).await.ok();
|
||||
} else {
|
||||
Self::r#do(tab, old, new).await.ok();
|
||||
}
|
||||
} else if ConfirmProxy::show(ConfirmCfg::overwrite(&new)).await {
|
||||
Self::r#do(tab, old, new).await.ok();
|
||||
if conversion_to_dir_requested && target_is_empty {
|
||||
Self::replace_file_with_dir(old, new).await.ok();
|
||||
} else {
|
||||
Self::r#do(tab, old, new).await.ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
succ!();
|
||||
|
|
@ -96,6 +118,29 @@ impl Rename {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn replace_file_with_dir(file: UrlBuf, dir: UrlBuf) -> Result<()> {
|
||||
let _permit = WATCHER.acquire().await.unwrap();
|
||||
|
||||
if let Ok(real_file) = provider::casefold(&file).await
|
||||
&& let Some((file_p, file_n)) = real_file.pair()
|
||||
{
|
||||
ok_or_not_found!(provider::remove_file(&file).await);
|
||||
FilesOp::Deleting(file_p.into(), [file_n.into()].into()).emit();
|
||||
}
|
||||
|
||||
provider::create_dir_all(&dir).await?;
|
||||
|
||||
if let Ok(real_dir) = provider::casefold(&dir).await
|
||||
&& let Some((dir_p, dir_n)) = real_dir.pair()
|
||||
{
|
||||
let dir = File::new(&real_dir).await?;
|
||||
FilesOp::Upserting(dir_p.into(), [(dir_n.into(), dir)].into()).emit();
|
||||
MgrProxy::reveal(&real_dir);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn empty_url_part(url: &UrlBuf, by: &str) -> String {
|
||||
if by == "all" {
|
||||
return String::new();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue