This commit is contained in:
sxyazi 2023-11-05 21:12:43 +08:00
parent 1e283682ce
commit 4a72dea37e
No known key found for this signature in database
25 changed files with 70 additions and 55 deletions

View file

@ -2,10 +2,14 @@ use yazi_config::keymap::Exec;
use crate::completion::Completion; use crate::completion::Completion;
pub struct Opt(isize); pub struct Opt {
step: isize,
}
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { Self(e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0)) } fn from(e: &Exec) -> Self {
Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl Completion { impl Completion {
@ -38,7 +42,7 @@ impl Completion {
} }
pub fn arrow(&mut self, opt: impl Into<Opt>) -> bool { pub fn arrow(&mut self, opt: impl Into<Opt>) -> bool {
let step = opt.into().0; let opt = opt.into() as Opt;
if step > 0 { self.next(step as usize) } else { self.prev(step.unsigned_abs()) } if opt.step > 0 { self.next(opt.step as usize) } else { self.prev(opt.step.unsigned_abs()) }
} }
} }

View file

@ -2,16 +2,18 @@ use yazi_config::keymap::{Exec, KeymapLayer};
use crate::{completion::Completion, emit}; use crate::{completion::Completion, emit};
pub struct Opt(bool); pub struct Opt {
submit: bool,
}
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { Self(e.named.contains_key("submit")) } fn from(e: &Exec) -> Self { Self { submit: e.named.contains_key("submit") } }
} }
impl Completion { impl Completion {
pub fn close(&mut self, opt: impl Into<Opt>) -> bool { pub fn close(&mut self, opt: impl Into<Opt>) -> bool {
let submit = opt.into().0; let opt = opt.into() as Opt;
if submit { if opt.submit {
emit!(Call( emit!(Call(
Exec::call("complete", vec![self.selected().into()]).with("ticket", self.ticket).vec(), Exec::call("complete", vec![self.selected().into()]).with("ticket", self.ticket).vec(),
KeymapLayer::Input KeymapLayer::Input

View file

@ -24,7 +24,7 @@ impl<'a> From<&'a Exec> for Opt<'a> {
impl Completion { impl Completion {
pub fn show<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn show<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
if self.ticket != opt.ticket { if self.ticket != opt.ticket {
return false; return false;
} }

View file

@ -29,7 +29,7 @@ impl Completion {
} }
pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn trigger<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
if opt.ticket < self.ticket { if opt.ticket < self.ticket {
return false; return false;
} }

View file

@ -18,7 +18,7 @@ impl<'a> From<&'a Exec> for Opt<'a> {
impl Input { impl Input {
pub fn complete<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn complete<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
if self.ticket != opt.ticket { if self.ticket != opt.ticket {
return false; return false;
} }

View file

@ -16,7 +16,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
pub fn create(&self, opt: impl Into<Opt>) -> bool { pub fn create(&self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let cwd = self.cwd().to_owned(); let cwd = self.cwd().to_owned();
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input(InputOpt::top("Create:"))); let mut result = emit!(Input(InputOpt::top("Create:")));

View file

@ -15,7 +15,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
pub fn link(&mut self, opt: impl Into<Opt>, tasks: &Tasks) -> bool { pub fn link(&mut self, opt: impl Into<Opt>, tasks: &Tasks) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let (cut, ref src) = self.yanked; let (cut, ref src) = self.yanked;
!cut && tasks.file_link(src, self.cwd(), opt.relative, opt.force) !cut && tasks.file_link(src, self.cwd(), opt.relative, opt.force)
} }

View file

@ -46,7 +46,7 @@ impl Manager {
return false; return false;
} }
let opt = opt.into(); let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let todo: Vec<_> = files.iter().filter(|(_, m)| m.is_none()).map(|(u, _)| u).collect(); let todo: Vec<_> = files.iter().filter(|(_, m)| m.is_none()).map(|(u, _)| u).collect();
if let Ok(mut mimes) = external::file(&todo).await { if let Ok(mut mimes) = external::file(&todo).await {

View file

@ -15,7 +15,7 @@ impl Manager {
let dest = self.cwd(); let dest = self.cwd();
let (cut, ref src) = self.yanked; let (cut, ref src) = self.yanked;
let opt = opt.into(); let opt = opt.into() as Opt;
if cut { tasks.file_cut(src, dest, opt.force) } else { tasks.file_copy(src, dest, opt.force) } if cut { tasks.file_cut(src, dest, opt.force) } else { tasks.file_copy(src, dest, opt.force) }
} }
} }

View file

@ -15,7 +15,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
pub fn quit(&self, opt: impl Into<Opt>, tasks: &Tasks) -> bool { pub fn quit(&self, opt: impl Into<Opt>, tasks: &Tasks) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let tasks = tasks.len(); let tasks = tasks.len();
if tasks == 0 { if tasks == 0 {

View file

@ -18,7 +18,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
pub fn remove(&mut self, opt: impl Into<Opt>, tasks: &Tasks) -> bool { pub fn remove(&mut self, opt: impl Into<Opt>, tasks: &Tasks) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let targets = self.selected().into_iter().map(|f| f.url()).collect(); let targets = self.selected().into_iter().map(|f| f.url()).collect();
tasks.file_remove(targets, opt.force, opt.permanently) tasks.file_remove(targets, opt.force, opt.permanently)
} }

View file

@ -40,7 +40,7 @@ impl Manager {
return false; return false;
}; };
let opt = opt.into(); let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input( let mut result = emit!(Input(
InputOpt::hovered("Rename:").with_value(hovered.file_name().unwrap().to_string_lossy()) InputOpt::hovered("Rename:").with_value(hovered.file_name().unwrap().to_string_lossy())

View file

@ -18,7 +18,7 @@ impl From<usize> for Opt {
impl Tabs { impl Tabs {
pub fn close(&mut self, opt: impl Into<Opt>) -> bool { pub fn close(&mut self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let len = self.items.len(); let len = self.items.len();
if len < 2 || opt.idx >= len { if len < 2 || opt.idx >= len {

View file

@ -27,7 +27,7 @@ impl Tabs {
return false; return false;
} }
let opt = opt.into(); let opt = opt.into() as Opt;
let url = if opt.current { self.active().current.cwd.to_owned() } else { opt.url.unwrap() }; let url = if opt.current { self.active().current.cwd.to_owned() } else { opt.url.unwrap() };
let mut tab = Tab::from(url); let mut tab = Tab::from(url);

View file

@ -3,18 +3,18 @@ use yazi_config::keymap::Exec;
use crate::manager::Tabs; use crate::manager::Tabs;
pub struct Opt { pub struct Opt {
idx: isize, step: isize,
} }
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { fn from(e: &Exec) -> Self {
Self { idx: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) }
} }
} }
impl Tabs { impl Tabs {
pub fn swap(&mut self, opt: impl Into<Opt>) -> bool { pub fn swap(&mut self, opt: impl Into<Opt>) -> bool {
let idx = self.absolute(opt.into().idx); let idx = self.absolute(opt.into().step);
if idx == self.idx { if idx == self.idx {
return false; return false;
} }

View file

@ -3,26 +3,26 @@ use yazi_config::keymap::Exec;
use crate::manager::Tabs; use crate::manager::Tabs;
pub struct Opt { pub struct Opt {
idx: isize, step: isize,
rel: bool, relative: bool,
} }
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { fn from(e: &Exec) -> Self {
Self { Self {
idx: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0), step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0),
rel: e.named.contains_key("relative"), relative: e.named.contains_key("relative"),
} }
} }
} }
impl Tabs { impl Tabs {
pub fn switch(&mut self, opt: impl Into<Opt>) -> bool { pub fn switch(&mut self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let idx = if opt.rel { let idx = if opt.relative {
(self.idx as isize + opt.idx).rem_euclid(self.items.len() as isize) as usize (self.idx as isize + opt.step).rem_euclid(self.items.len() as isize) as usize
} else { } else {
opt.idx as usize opt.step as usize
}; };
if idx == self.idx || idx >= self.items.len() { if idx == self.idx || idx >= self.items.len() {

View file

@ -12,7 +12,7 @@ impl From<&Exec> for Opt {
impl Manager { impl Manager {
pub fn yank(&mut self, opt: impl Into<Opt>) -> bool { pub fn yank(&mut self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
self.yanked.0 = opt.cut; self.yanked.0 = opt.cut;
self.yanked.1 = self.selected().into_iter().map(|f| f.url()).collect(); self.yanked.1 = self.selected().into_iter().map(|f| f.url()).collect();

View file

@ -2,11 +2,13 @@ use yazi_config::keymap::Exec;
use crate::{emit, tab::Tab, Step}; use crate::{emit, tab::Tab, Step};
pub struct Opt(Step); pub struct Opt {
step: Step,
}
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { fn from(e: &Exec) -> Self {
Self(e.args.first().and_then(|s| s.parse().ok()).unwrap_or_default()) Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or_default() }
} }
} }
@ -14,13 +16,17 @@ impl<T> From<T> for Opt
where where
T: Into<Step>, T: Into<Step>,
{ {
fn from(t: T) -> Self { Self(t.into()) } fn from(t: T) -> Self { Self { step: t.into() } }
} }
impl Tab { impl Tab {
pub fn arrow(&mut self, opt: impl Into<Opt>) -> bool { pub fn arrow(&mut self, opt: impl Into<Opt>) -> bool {
let step = opt.into().0; let opt = opt.into() as Opt;
let ok = if step.is_positive() { self.current.next(step) } else { self.current.prev(step) }; let ok = if opt.step.is_positive() {
self.current.next(opt.step)
} else {
self.current.prev(opt.step)
};
if !ok { if !ok {
return false; return false;
} }

View file

@ -14,7 +14,7 @@ impl<'a> From<&'a Exec> for Opt<'a> {
impl Tab { impl Tab {
pub fn copy<'a>(&self, opt: impl Into<Opt<'a>>) -> bool { pub fn copy<'a>(&self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let mut s = OsString::new(); let mut s = OsString::new();
let mut it = self.selected().into_iter().peekable(); let mut it = self.selected().into_iter().peekable();

View file

@ -37,7 +37,7 @@ impl From<&Exec> for ArrowOpt {
impl Tab { impl Tab {
pub fn find<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn find<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let rx = emit!(Input( let rx = emit!(Input(
InputOpt::top(if opt.prev { "Find previous:" } else { "Find next:" }).with_realtime() InputOpt::top(if opt.prev { "Find previous:" } else { "Find next:" }).with_realtime()
@ -61,7 +61,7 @@ impl Tab {
} }
pub fn find_do<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool { pub fn find_do<'a>(&mut self, opt: impl Into<Opt<'a>>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let Some(query) = opt.query else { let Some(query) = opt.query else {
return false; return false;
}; };

View file

@ -28,7 +28,7 @@ impl From<&Exec> for Opt {
impl Tab { impl Tab {
pub fn jump(&self, opt: impl Into<Opt>) -> bool { pub fn jump(&self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
if opt.type_ == OptType::None { if opt.type_ == OptType::None {
return false; return false;
} }

View file

@ -32,7 +32,7 @@ impl From<&Exec> for Opt {
impl Tab { impl Tab {
pub fn search(&mut self, opt: impl Into<Opt>) -> bool { pub fn search(&mut self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
if opt.type_ == OptType::None { if opt.type_ == OptType::None {
return self.search_stop(); return self.search_stop();
} }

View file

@ -2,31 +2,34 @@ use yazi_config::keymap::Exec;
use crate::tab::Tab; use crate::tab::Tab;
pub struct Opt(Option<bool>); pub struct Opt {
state: Option<bool>,
impl From<Option<bool>> for Opt {
fn from(b: Option<bool>) -> Self { Self(b) }
} }
impl From<&Exec> for Opt { impl From<&Exec> for Opt {
fn from(e: &Exec) -> Self { fn from(e: &Exec) -> Self {
Self(match e.named.get("state").map(|s| s.as_bytes()) { Self {
Some(b"true") => Some(true), state: match e.named.get("state").map(|s| s.as_bytes()) {
Some(b"false") => Some(false), Some(b"true") => Some(true),
_ => None, Some(b"false") => Some(false),
}) _ => None,
},
}
} }
} }
impl From<Option<bool>> for Opt {
fn from(state: Option<bool>) -> Self { Self { state } }
}
impl Tab { impl Tab {
pub fn select(&mut self, opt: impl Into<Opt>) -> bool { pub fn select(&mut self, opt: impl Into<Opt>) -> bool {
if let Some(u) = self.current.hovered().map(|h| h.url()) { if let Some(u) = self.current.hovered().map(|h| h.url()) {
return self.current.files.select(&u, opt.into().0); return self.current.files.select(&u, opt.into().state);
} }
false false
} }
pub fn select_all(&mut self, opt: impl Into<Opt>) -> bool { pub fn select_all(&mut self, opt: impl Into<Opt>) -> bool {
self.current.files.select_all(opt.into().0) self.current.files.select_all(opt.into().state)
} }
} }

View file

@ -26,7 +26,7 @@ impl Tab {
.map(|f| (f.url.as_os_str().to_owned(), Default::default())) .map(|f| (f.url.as_os_str().to_owned(), Default::default()))
.collect(); .collect();
let mut opt = opt.into(); let mut opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
if !opt.confirm || opt.cmd.is_empty() { if !opt.confirm || opt.cmd.is_empty() {
let mut result = emit!(Input( let mut result = emit!(Input(

View file

@ -14,7 +14,7 @@ impl From<&Exec> for Opt {
impl Tab { impl Tab {
pub fn visual_mode(&mut self, opt: impl Into<Opt>) -> bool { pub fn visual_mode(&mut self, opt: impl Into<Opt>) -> bool {
let opt = opt.into(); let opt = opt.into() as Opt;
let idx = self.current.cursor; let idx = self.current.cursor;
if opt.unset { if opt.unset {