yazi_core/tab/commands/
copy.rsuse std::{borrow::Cow, ffi::{OsStr, OsString}, path::Path};
use yazi_plugin::CLIPBOARD;
use yazi_shared::event::CmdCow;
use crate::tab::Tab;
struct Opt {
type_: Cow<'static, str>,
separator: Separator,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
type_: c.take_first_str().unwrap_or_default(),
separator: c.str("separator").unwrap_or_default().into(),
}
}
}
impl Tab {
#[yazi_codegen::command]
pub fn copy(&mut self, opt: Opt) {
if !self.try_escape_visual() {
return;
}
let mut s = OsString::new();
let mut it = self.selected_or_hovered().peekable();
while let Some(u) = it.next() {
s.push(match opt.type_.as_ref() {
"path" => opt.separator.transform(u),
"dirname" => opt.separator.transform(u.parent().unwrap_or(Path::new(""))),
"filename" => opt.separator.transform(u.name()),
"name_without_ext" => opt.separator.transform(u.file_stem().unwrap_or_default()),
_ => return,
});
if it.peek().is_some() {
s.push("\n");
}
}
if s.is_empty() && opt.type_ == "dirname" {
s.push(self.cwd());
}
futures::executor::block_on(CLIPBOARD.set(s));
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
enum Separator {
Auto,
Unix,
}
impl From<&str> for Separator {
fn from(value: &str) -> Self {
match value {
"unix" => Self::Unix,
_ => Self::Auto,
}
}
}
impl Separator {
fn transform<T: AsRef<Path> + ?Sized>(self, p: &T) -> Cow<OsStr> {
#[cfg(windows)]
if self == Self::Unix {
return match yazi_fs::backslash_to_slash(p.as_ref()) {
Cow::Owned(p) => Cow::Owned(p.into_os_string()),
Cow::Borrowed(p) => Cow::Borrowed(p.as_os_str()),
};
}
Cow::Borrowed(p.as_ref().as_os_str())
}
}