feat: new copy --separator option to allow specifying the path separator (#1877)

Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
Li-Lun Lin 2024-11-03 17:40:29 +08:00 committed by GitHub
parent 5531874a9a
commit 565f9cc898
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,4 @@
use std::ffi::{OsStr, OsString}; use std::{borrow::Cow, ffi::{OsStr, OsString}, path::Path};
use yazi_plugin::CLIPBOARD; use yazi_plugin::CLIPBOARD;
use yazi_shared::event::Cmd; use yazi_shared::event::Cmd;
@ -6,11 +6,17 @@ use yazi_shared::event::Cmd;
use crate::tab::Tab; use crate::tab::Tab;
struct Opt { struct Opt {
type_: String, type_: String,
separator: Separator,
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { Self { type_: c.take_first_str().unwrap_or_default() } } fn from(mut c: Cmd) -> Self {
Self {
type_: c.take_first_str().unwrap_or_default(),
separator: c.str("separator").unwrap_or_default().into(),
}
}
} }
impl Tab { impl Tab {
@ -24,10 +30,10 @@ impl Tab {
let mut it = self.selected_or_hovered(true).peekable(); let mut it = self.selected_or_hovered(true).peekable();
while let Some(u) = it.next() { while let Some(u) = it.next() {
s.push(match opt.type_.as_str() { s.push(match opt.type_.as_str() {
"path" => u.as_os_str(), "path" => opt.separator.transform(u),
"dirname" => u.parent().map_or(OsStr::new(""), |p| p.as_os_str()), "dirname" => opt.separator.transform(u.parent().unwrap_or(Path::new(""))),
"filename" => u.name(), "filename" => opt.separator.transform(u.name()),
"name_without_ext" => u.file_stem().unwrap_or(OsStr::new("")), "name_without_ext" => opt.separator.transform(u.file_stem().unwrap_or_default()),
_ => return, _ => return,
}); });
if it.peek().is_some() { if it.peek().is_some() {
@ -43,3 +49,32 @@ impl Tab {
futures::executor::block_on(CLIPBOARD.set(s)); futures::executor::block_on(CLIPBOARD.set(s));
} }
} }
// --- Separator
#[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_shared::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())
}
}