mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
1e283682ce
commit
4a72dea37e
25 changed files with 70 additions and 55 deletions
|
|
@ -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()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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:")));
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
state: match e.named.get("state").map(|s| s.as_bytes()) {
|
||||||
Some(b"true") => Some(true),
|
Some(b"true") => Some(true),
|
||||||
Some(b"false") => Some(false),
|
Some(b"false") => Some(false),
|
||||||
_ => None,
|
_ => 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue