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_fs::{File, FilesOp};
|
||||||
use yazi_macro::{act, err, ok_or_not_found, succ};
|
use yazi_macro::{act, err, ok_or_not_found, succ};
|
||||||
use yazi_parser::mgr::RenameOpt;
|
use yazi_parser::mgr::RenameOpt;
|
||||||
use yazi_proxy::{ConfirmProxy, InputProxy, MgrProxy};
|
use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, MgrProxy};
|
||||||
use yazi_shared::{Id, data::Data, url::{UrlBuf, UrlLike}};
|
use yazi_shared::{
|
||||||
|
Id,
|
||||||
|
data::Data,
|
||||||
|
url::{UrlBuf, UrlLike},
|
||||||
|
};
|
||||||
use yazi_vfs::{VfsFile, maybe_exists, provider};
|
use yazi_vfs::{VfsFile, maybe_exists, provider};
|
||||||
use yazi_watcher::WATCHER;
|
use yazi_watcher::WATCHER;
|
||||||
|
|
||||||
|
|
@ -40,6 +44,9 @@ impl Actor for Rename {
|
||||||
_ => None,
|
_ => 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 (tab, old) = (cx.tab().id, hovered.url_owned());
|
||||||
let mut input = InputProxy::show(InputCfg::rename().with_value(name).with_cursor(cursor));
|
let mut input = InputProxy::show(InputCfg::rename().with_value(name).with_cursor(cursor));
|
||||||
|
|
||||||
|
|
@ -49,14 +56,29 @@ impl Actor for Rename {
|
||||||
return;
|
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 {
|
let Some(Ok(new)) = old.parent().map(|u| u.try_join(name)) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if opt.force || !maybe_exists(&new).await || provider::must_identical(&old, &new).await {
|
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 {
|
} 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!();
|
succ!();
|
||||||
|
|
@ -96,6 +118,29 @@ impl Rename {
|
||||||
Ok(())
|
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 {
|
fn empty_url_part(url: &UrlBuf, by: &str) -> String {
|
||||||
if by == "all" {
|
if by == "all" {
|
||||||
return String::new();
|
return String::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue