copy actor - add target option

This commit is contained in:
Vladimir Mikryukov 2026-01-06 19:54:52 +02:00
parent c9327ca851
commit f9cc93cedb
No known key found for this signature in database
GPG key ID: 5B7EB187B7E39421

View file

@ -1,4 +1,5 @@
use anyhow::{Result, bail}; use anyhow::{Result, bail};
use std::path::Path;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::mgr::CopyOpt; use yazi_parser::mgr::CopyOpt;
use yazi_shared::{data::Data, strand::ToStrand, url::UrlLike}; use yazi_shared::{data::Data, strand::ToStrand, url::UrlLike};
@ -41,6 +42,35 @@ impl Actor for Copy {
"name_without_ext" => { "name_without_ext" => {
s.extend_from_slice(&opt.separator.transform(&u.stem().unwrap_or_default())); s.extend_from_slice(&opt.separator.transform(&u.stem().unwrap_or_default()));
} }
"target" => {
if let Some(local_path) = u.as_local() {
match std::fs::read_link(local_path) {
Ok(target_path) => {
let resolved = if target_path.is_absolute() {
target_path
} else {
// `read_link` returns the raw link text, which is often relative
// Resolve it against the symlink's parent directory so the result is usable
let parent = local_path
.parent()
.or_else(|| cx.cwd().as_local())
.unwrap_or_else(|| Path::new(""));
parent.join(target_path)
};
let resolved = resolved.as_path();
s.extend_from_slice(&opt.separator.transform(&resolved));
}
Err(_) => {
// If read_link fails, fall back to copying the symlink path itself
s.extend_from_slice(&opt.separator.transform(&u.to_strand()));
}
}
} else {
// If not a local path, fall back to copying the symlink path itself
s.extend_from_slice(&opt.separator.transform(&u.to_strand()));
}
}
_ => bail!("Unknown copy type: {}", opt.r#type), _ => bail!("Unknown copy type: {}", opt.r#type),
}; };
if it.peek().is_some() { if it.peek().is_some() {