refactor: new yazi-parser crate (#2956)

This commit is contained in:
三咲雅 misaki masa 2025-07-06 19:17:00 +08:00 committed by GitHub
parent ec7eb3e416
commit a426d449f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
258 changed files with 1657 additions and 1443 deletions

78
Cargo.lock generated
View file

@ -194,9 +194,9 @@ dependencies = [
[[package]]
name = "avif-serialize"
version = "0.8.4"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19135c0c7a60bfee564dbe44ab5ce0557c6bf3884e5291a50be76a15640c4fbd"
checksum = "2ea8ef51aced2b9191c08197f55450d830876d9933f8f48a429b354f1d496b42"
dependencies = [
"arrayvec",
]
@ -349,9 +349,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.27"
version = "1.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
dependencies = [
"jobserver",
"libc",
@ -879,18 +879,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "filetime"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
dependencies = [
"cfg-if",
"libc",
"libredox",
"windows-sys 0.59.0",
]
[[package]]
name = "flate2"
version = "1.1.2"
@ -1325,9 +1313,9 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libfuzzer-sys"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75"
checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404"
dependencies = [
"arbitrary",
"cc",
@ -1341,7 +1329,6 @@ checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
dependencies = [
"bitflags 2.9.1",
"libc",
"redox_syscall",
]
[[package]]
@ -1558,12 +1545,11 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "notify"
version = "8.0.0"
version = "8.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
checksum = "3163f59cd3fa0e9ef8c32f242966a7b9994fd7378366099593e0e73077cd8c97"
dependencies = [
"bitflags 2.9.1",
"filetime",
"fsevent-sys",
"inotify",
"kqueue",
@ -1572,7 +1558,7 @@ dependencies = [
"mio",
"notify-types",
"walkdir",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
]
[[package]]
@ -2677,9 +2663,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.46.0"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
"backtrace",
"bytes",
@ -3469,13 +3455,19 @@ dependencies = [
name = "yazi-binding"
version = "25.6.11"
dependencies = [
"ansi-to-tui",
"mlua",
"paste",
"ratatui",
"serde_json",
"tokio",
"tracing",
"unicode-width 0.2.0",
"yazi-adapter",
"yazi-config",
"yazi-fs",
"yazi-macro",
"yazi-proxy",
"yazi-shared",
]
@ -3555,7 +3547,6 @@ name = "yazi-core"
version = "25.6.11"
dependencies = [
"anyhow",
"bitflags 2.9.1",
"crossterm 0.29.0",
"futures",
"indexmap",
@ -3577,6 +3568,7 @@ dependencies = [
"yazi-dds",
"yazi-fs",
"yazi-macro",
"yazi-parser",
"yazi-plugin",
"yazi-proxy",
"yazi-scheduler",
@ -3693,14 +3685,31 @@ version = "25.6.11"
name = "yazi-packing"
version = "25.5.28"
[[package]]
name = "yazi-parser"
version = "25.6.11"
dependencies = [
"anyhow",
"bitflags 2.9.1",
"mlua",
"tokio",
"yazi-binding",
"yazi-boot",
"yazi-config",
"yazi-dds",
"yazi-fs",
"yazi-macro",
"yazi-proxy",
"yazi-shared",
"yazi-widgets",
]
[[package]]
name = "yazi-plugin"
version = "25.6.11"
dependencies = [
"ansi-to-tui",
"anyhow",
"base64",
"clipboard-win",
"crossterm 0.29.0",
"futures",
"globset",
@ -3726,10 +3735,12 @@ dependencies = [
"yazi-dds",
"yazi-fs",
"yazi-macro",
"yazi-parser",
"yazi-prebuilt",
"yazi-proxy",
"yazi-shared",
"yazi-term",
"yazi-widgets",
]
[[package]]
@ -3812,16 +3823,21 @@ dependencies = [
name = "yazi-widgets"
version = "25.6.11"
dependencies = [
"base64",
"clipboard-win",
"crossterm 0.29.0",
"futures",
"parking_lot",
"ratatui",
"tokio",
"unicode-width 0.2.0",
"yazi-binding",
"yazi-codegen",
"yazi-config",
"yazi-macro",
"yazi-plugin",
"yazi-proxy",
"yazi-shared",
"yazi-term",
]
[[package]]
@ -3861,9 +3877,9 @@ dependencies = [
[[package]]
name = "zune-jpeg"
version = "0.4.18"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7384255a918371b5af158218d131530f694de9ad3815ebdd0453a940485cb0fa"
checksum = "2c9e525af0a6a658e031e95f14b7f889976b74a11ba0eca5a5fc9ac8a1c43a6a"
dependencies = [
"zune-core",
]

View file

@ -45,7 +45,7 @@ scopeguard = "1.2.0"
serde = { version = "1.0.219", features = [ "derive" ] }
serde_json = "1.0.140"
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
tokio = { version = "1.46.0", features = [ "full" ] }
tokio = { version = "1.46.1", features = [ "full" ] }
tokio-stream = "0.1.17"
tokio-util = "0.7.15"
toml = { version = "0.8.23" }

View file

@ -9,13 +9,21 @@ homepage = "https://yazi-rs.github.io"
repository = "https://github.com/sxyazi/yazi"
[dependencies]
yazi-config = { path = "../yazi-config", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
yazi-config = { path = "../yazi-config", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
# External dependencies
mlua = { workspace = true }
paste = { workspace = true }
ratatui = { workspace = true }
serde_json = { workspace = true }
ansi-to-tui = { workspace = true }
mlua = { workspace = true }
paste = { workspace = true }
ratatui = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
unicode-width = { workspace = true }
# Logging
tracing = { workspace = true }

View file

@ -14,13 +14,13 @@ const QUADRANT_OUTSIDE: u8 = 5;
#[derive(Clone, Debug, Default)]
pub struct Border {
pub(crate) area: Area,
pub area: Area,
pub(crate) edge: Edge,
pub(crate) r#type: ratatui::widgets::BorderType,
pub(crate) style: ratatui::style::Style,
pub edge: Edge,
pub r#type: ratatui::widgets::BorderType,
pub style: ratatui::style::Style,
pub(crate) titles: Vec<(ratatui::widgets::block::Position, ratatui::text::Line<'static>)>,
pub titles: Vec<(ratatui::widgets::block::Position, ratatui::text::Line<'static>)>,
}
impl Border {

View file

@ -22,7 +22,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
b"Rect" => super::Rect::compose(lua)?,
b"Row" => super::Row::compose(lua)?,
b"Span" => super::Span::compose(lua)?,
b"Style" => yazi_binding::Style::compose(lua)?,
b"Style" => crate::Style::compose(lua)?,
b"Table" => super::Table::compose(lua)?,
b"Text" => super::Text::compose(lua)?,
b"Wrap" => super::Wrap::compose(lua)?,

View file

@ -1,8 +1,8 @@
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;
use yazi_binding::Style;
use super::{Area, Span};
use crate::Style;
#[derive(Clone, Debug, Default)]
pub struct Gauge {

View file

@ -107,7 +107,7 @@ impl UserData for Line {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, inner.style);
yazi_binding::impl_style_shorthands!(methods, inner.style);
crate::impl_style_shorthands!(methods, inner.style);
methods.add_method("width", |_, me, ()| Ok(me.inner.width()));
methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {

View file

@ -1,10 +1,9 @@
use std::any::TypeId;
use mlua::{AnyUserData, ExternalError};
use yazi_binding::Error;
use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text};
use crate::elements::Rect;
use crate::{Error, elements::Rect};
#[derive(Clone, Debug)]
pub enum Renderable {

View file

@ -69,7 +69,7 @@ impl TryFrom<Value> for Span {
impl UserData for Span {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
crate::impl_style_method!(methods, 0.style);
yazi_binding::impl_style_shorthands!(methods, 0.style);
crate::impl_style_shorthands!(methods, 0.style);
methods.add_method("visible", |_, Span(me), ()| {
Ok(me.content.chars().any(|c| c.width().unwrap_or(0) > 0))

View file

@ -1,16 +1,15 @@
use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, UserData, Value};
use ratatui::widgets::StatefulWidget;
use yazi_binding::Style;
use super::{Area, Row};
use crate::elements::Constraint;
use crate::{Style, elements::Constraint};
const EXPECTED: &str = "expected a table of Rows";
// --- Table
#[derive(Clone, Debug, Default)]
pub struct Table {
pub(crate) area: Area,
pub area: Area,
rows: Vec<Row>,
header: Option<ratatui::widgets::Row<'static>>,
@ -84,15 +83,15 @@ impl Table {
}
#[inline]
pub(crate) fn len(&self) -> usize { self.rows.len() }
pub fn len(&self) -> usize { self.rows.len() }
pub(crate) fn select(&mut self, idx: Option<usize>) {
pub fn select(&mut self, idx: Option<usize>) {
self
.state
.select(idx.map(|i| if self.rows.is_empty() { 0 } else { i.min(self.rows.len() - 1) }));
}
pub(crate) fn selected(&self) -> Option<usize> {
pub fn selected(&self) -> Option<usize> {
if self.rows.is_empty() { None } else { Some(self.state.selected()?.min(self.rows.len() - 1)) }
}
}

View file

@ -3,10 +3,9 @@ use std::{any::TypeId, mem};
use ansi_to_tui::IntoText;
use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use ratatui::widgets::Widget;
use yazi_binding::Error;
use super::{Area, Line, Span, Wrap};
use crate::elements::Align;
use crate::{Error, elements::Align};
const EXPECTED: &str = "expected a string, Line, Span, or a table of them";
@ -112,7 +111,7 @@ impl UserData for Text {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, inner.style);
yazi_binding::impl_style_shorthands!(methods, inner.style);
crate::impl_style_shorthands!(methods, inner.style);
methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {
ud.borrow_mut::<Self>()?.inner.alignment = Some(align.0);

View file

@ -6,7 +6,7 @@ use yazi_macro::render;
use yazi_proxy::{AppProxy, HIDER};
use super::{Line, Rect, Span};
use crate::bindings::{Permit, PermitRef};
use crate::{Permit, PermitRef};
pub(super) struct Utils;

View file

@ -1,9 +1,8 @@
use std::ops::Deref;
use mlua::{ExternalError, FromLua, Lua, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value};
use yazi_binding::Url;
use crate::{bindings::Cha, impl_file_fields, impl_file_methods};
use crate::{Cha, Url, impl_file_fields, impl_file_methods};
pub type FileRef = UserDataRef<File>;

View file

@ -1,3 +1,7 @@
#![allow(clippy::unit_arg)]
mod macros;
yazi_macro::mod_flat!(color error icon id stage style url urn);
yazi_macro::mod_pub!(elements);
yazi_macro::mod_flat!(cha color composer error file icon id permit runtime stage style url urn);

View file

@ -1,3 +1,30 @@
#[macro_export]
macro_rules! runtime {
($lua:ident) => {{
use mlua::ExternalError;
$lua.app_data_ref::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
}};
}
#[macro_export]
macro_rules! runtime_mut {
($lua:ident) => {{
use mlua::ExternalError;
$lua.app_data_mut::<$crate::Runtime>().ok_or_else(|| "Runtime not found".into_lua_err())
}};
}
#[macro_export]
macro_rules! deprecate {
($lua:ident, $tt:tt) => {{
let id = match $crate::runtime!($lua)?.current() {
Some(id) => &format!("`{id}.yazi` plugin"),
None => "`init.lua` config",
};
yazi_proxy::deprecate!(format!($tt, id));
}};
}
#[macro_export]
macro_rules! cached_field {
($fields:ident, $key:ident, $value:expr) => {
@ -18,6 +45,34 @@ macro_rules! cached_field {
};
}
#[macro_export]
macro_rules! impl_area_method {
($methods:ident) => {
$methods.add_function_mut(
"area",
|lua, (ud, area): (mlua::AnyUserData, Option<mlua::AnyUserData>)| {
use mlua::IntoLua;
if let Some(v) = area {
ud.borrow_mut::<Self>()?.area = $crate::elements::Area::try_from(v)?;
ud.into_lua(lua)
} else {
ud.borrow::<Self>()?.area.into_lua(lua)
}
},
);
};
}
#[macro_export]
macro_rules! impl_style_method {
($methods:ident, $($field:tt).+) => {
$methods.add_function_mut("style", |_, (ud, value): (mlua::AnyUserData, mlua::Value)| {
ud.borrow_mut::<Self>()?.$($field).+ = $crate::Style::try_from(value)?.0;
Ok(ud)
});
};
}
#[macro_export]
macro_rules! impl_style_shorthands {
($methods:ident, $($field:tt).+) => {
@ -85,3 +140,32 @@ macro_rules! impl_style_shorthands {
});
};
}
#[macro_export]
macro_rules! impl_file_fields {
($fields:ident) => {
$crate::cached_field!($fields, cha, |_, me| Ok($crate::Cha(me.cha)));
$crate::cached_field!($fields, url, |_, me| Ok($crate::Url::new(me.url_owned())));
$crate::cached_field!($fields, link_to, |_, me| Ok(me.link_to.clone().map($crate::Url::new)));
$crate::cached_field!($fields, name, |lua, me| {
Some(me.name())
.filter(|s| !s.is_empty())
.map(|s| lua.create_string(s.as_encoded_bytes()))
.transpose()
});
};
}
#[macro_export]
macro_rules! impl_file_methods {
($methods:ident) => {
$methods.add_method("hash", |_, me, ()| Ok(me.hash_u64()));
$methods.add_method("icon", |_, me, ()| {
use $crate::Icon;
// TODO: use a cache
Ok(yazi_config::THEME.icon.matches(me).map(Icon::from))
});
};
}

View file

@ -16,6 +16,7 @@ yazi-config = { path = "../yazi-config", version = "25.6.11" }
yazi-dds = { path = "../yazi-dds", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
yazi-parser = { path = "../yazi-parser", version = "25.6.11" }
yazi-plugin = { path = "../yazi-plugin", version = "25.6.11" }
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
yazi-scheduler = { path = "../yazi-scheduler", version = "25.6.11" }
@ -25,11 +26,10 @@ yazi-widgets = { path = "../yazi-widgets", version = "25.6.11" }
# External dependencies
anyhow = { workspace = true }
bitflags = { workspace = true }
crossterm = { workspace = true }
futures = { workspace = true }
indexmap = { workspace = true }
notify = { version = "8.0.0", default-features = false, features = [ "macos_fsevent" ] }
notify = { version = "8.1.0", default-features = false, features = [ "macos_fsevent" ] }
parking_lot = { workspace = true }
ratatui = { workspace = true }
scopeguard = { workspace = true }

View file

@ -1,22 +1,12 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_widgets::{Scrollable, Step};
use yazi_parser::cmp::ArrowOpt;
use yazi_widgets::Scrollable;
use crate::cmp::Cmp;
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Cmp {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step));
}
}

View file

@ -1,25 +1,14 @@
use std::mem;
use yazi_macro::render;
use yazi_parser::cmp::CloseOpt;
use yazi_proxy::InputProxy;
use yazi_shared::event::CmdCow;
use crate::cmp::Cmp;
struct Opt {
submit: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { submit: c.bool("submit") } }
}
impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } }
}
impl Cmp {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
pub fn close(&mut self, opt: CloseOpt) {
if let Some(s) = self.selected().filter(|_| opt.submit) {
InputProxy::complete(s, self.ticket);
}

View file

@ -1,38 +1,17 @@
use std::{borrow::Cow, mem, ops::ControlFlow, path::PathBuf};
use std::{mem, ops::ControlFlow};
use yazi_macro::render;
use yazi_parser::cmp::ShowOpt;
use yazi_proxy::options::CmpItem;
use yazi_shared::{Id, event::{Cmd, CmdCow, Data}, osstr_contains, osstr_starts_with};
use yazi_shared::{osstr_contains, osstr_starts_with};
use crate::cmp::Cmp;
const LIMIT: usize = 30;
struct Opt {
cache: Vec<CmpItem>,
cache_name: PathBuf,
word: Cow<'static, str>,
ticket: Id,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
cache: c.take_any("cache").unwrap_or_default(),
cache_name: c.take_any("cache-name").unwrap_or_default(),
word: c.take_str("word").unwrap_or_default(),
ticket: c.get("ticket").and_then(Data::as_id).unwrap_or_default(),
}
}
}
impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self::from(CmdCow::from(c)) }
}
impl Cmp {
#[yazi_codegen::command]
pub fn show(&mut self, opt: Opt) {
pub fn show(&mut self, opt: ShowOpt) {
if self.ticket != opt.ticket {
return;
}

View file

@ -1,30 +1,17 @@
use std::{borrow::Cow, ffi::OsString, mem, path::{MAIN_SEPARATOR_STR, Path, PathBuf}};
use std::{ffi::OsString, mem, path::{MAIN_SEPARATOR_STR, Path, PathBuf}};
use tokio::fs;
use yazi_fs::{CWD, expand_path};
use yazi_macro::{emit, render};
use yazi_parser::cmp::TriggerOpt;
use yazi_proxy::options::CmpItem;
use yazi_shared::{Id, event::{Cmd, CmdCow, Data}, natsort};
use yazi_shared::{event::Cmd, natsort};
use crate::cmp::Cmp;
struct Opt {
word: Cow<'static, str>,
ticket: Id,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
word: c.take_first_str().unwrap_or_default(),
ticket: c.get("ticket").and_then(Data::as_id).unwrap_or_default(),
}
}
}
impl Cmp {
#[yazi_codegen::command]
pub fn trigger(&mut self, opt: Opt) {
pub fn trigger(&mut self, opt: TriggerOpt) {
if opt.ticket < self.ticket {
return;
}

View file

@ -1,22 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use yazi_parser::confirm::ArrowOpt;
use crate::{confirm::Confirm, mgr::Mgr};
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Confirm {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt, mgr: &Mgr) {
pub fn arrow(&mut self, opt: ArrowOpt, mgr: &Mgr) {
let area = mgr.area(self.position);
let len = self.list.line_count(area.width);

View file

@ -1,22 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::confirm::CloseOpt;
use crate::confirm::Confirm;
struct Opt {
submit: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { submit: c.bool("submit") } }
}
impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } }
}
impl Confirm {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
pub fn close(&mut self, opt: CloseOpt) {
if let Some(cb) = self.callback.take() {
_ = cb.send(opt.submit);
}

View file

@ -1,26 +1,11 @@
use tokio::sync::oneshot;
use yazi_config::popup::ConfirmCfg;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::confirm::ShowOpt;
use crate::confirm::Confirm;
pub struct Opt {
cfg: ConfirmCfg,
tx: oneshot::Sender<bool>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { cfg: c.take_any("cfg").ok_or(())?, tx: c.take_any("tx").ok_or(())? })
}
}
impl Confirm {
pub fn show(&mut self, opt: impl TryInto<Opt>) {
let Ok(opt): Result<Opt, _> = opt.try_into() else {
pub fn show(&mut self, opt: impl TryInto<ShowOpt>) {
let Ok(opt): Result<ShowOpt, _> = opt.try_into() else {
return;
};

View file

@ -1,27 +1,13 @@
use yazi_adapter::Dimension;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_widgets::{Scrollable, Step};
use yazi_parser::help::ArrowOpt;
use yazi_widgets::Scrollable;
use crate::help::{HELP_MARGIN, Help};
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl From<isize> for Opt {
fn from(n: isize) -> Self { Self { step: n.into() } }
}
impl Help {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step));
}
}

View file

@ -1,23 +1,13 @@
use yazi_macro::render;
use yazi_parser::input::CloseOpt;
use yazi_proxy::CmpProxy;
use yazi_shared::{errors::InputError, event::CmdCow};
use yazi_shared::errors::InputError;
use crate::input::Input;
struct Opt {
submit: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { submit: c.bool("submit") } }
}
impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } }
}
impl Input {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
pub fn close(&mut self, opt: CloseOpt) {
self.visible = false;
self.ticket.next();

View file

@ -1,22 +1,13 @@
use yazi_macro::render;
use yazi_parser::input::EscapeOpt;
use yazi_proxy::CmpProxy;
use yazi_shared::event::CmdCow;
use yazi_widgets::input::InputOp;
use crate::input::Input;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl From<()> for Opt {
fn from(_: ()) -> Self { Self }
}
impl Input {
#[yazi_codegen::command]
pub fn escape(&mut self, _: Opt) {
pub fn escape(&mut self, _: EscapeOpt) {
use yazi_widgets::input::InputMode as M;
let mode = self.snap().mode;

View file

@ -1,27 +1,14 @@
use tokio::sync::mpsc;
use yazi_config::{YAZI, popup::InputCfg};
use yazi_config::YAZI;
use yazi_macro::render;
use yazi_shared::{errors::InputError, event::CmdCow};
use yazi_parser::input::ShowOpt;
use yazi_shared::errors::InputError;
use yazi_widgets::input::InputCallback;
use crate::input::Input;
pub struct Opt {
cfg: InputCfg,
tx: mpsc::UnboundedSender<Result<String, InputError>>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { cfg: c.take_any("cfg").ok_or(())?, tx: c.take_any("tx").ok_or(())? })
}
}
impl Input {
pub fn show(&mut self, opt: impl TryInto<Opt>) {
let Ok(opt): Result<Opt, _> = opt.try_into() else { return };
pub fn show(&mut self, opt: impl TryInto<ShowOpt>) {
let Ok(opt): Result<ShowOpt, _> = opt.try_into() else { return };
self.close(false);
self.visible = true;

View file

@ -1,17 +1,10 @@
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::CloseOpt;
use crate::{mgr::{Mgr, commands::quit}, tasks::Tasks};
#[derive(Default)]
struct Opt(quit::Opt);
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self(c.into()) }
}
use crate::{mgr::Mgr, tasks::Tasks};
impl Mgr {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt, tasks: &Tasks) {
pub fn close(&mut self, opt: CloseOpt, tasks: &Tasks) {
if self.tabs.len() > 1 {
return self.tabs.close(self.tabs.cursor);
}

View file

@ -2,23 +2,15 @@ use anyhow::Result;
use tokio::fs;
use yazi_config::popup::{ConfirmCfg, InputCfg};
use yazi_fs::{File, FilesOp, maybe_exists, ok_or_not_found, realname};
use yazi_parser::mgr::CreateOpt;
use yazi_proxy::{ConfirmProxy, InputProxy, TabProxy, WATCHER};
use yazi_shared::{event::CmdCow, url::{Url, UrnBuf}};
use yazi_shared::url::{Url, UrnBuf};
use crate::mgr::Mgr;
struct Opt {
dir: bool,
force: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { dir: c.bool("dir"), force: c.bool("force") } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn create(&self, opt: Opt) {
pub fn create(&self, opt: CreateOpt) {
let cwd = self.cwd().to_owned();
let mut input = InputProxy::show(InputCfg::create(opt.dir));

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::HardlinkOpt;
use crate::{mgr::Mgr, tasks::Tasks};
struct Opt {
force: bool,
follow: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { force: c.bool("force"), follow: c.bool("follow") } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn hardlink(&mut self, opt: Opt, tasks: &Tasks) {
pub fn hardlink(&mut self, opt: HardlinkOpt, tasks: &Tasks) {
if self.yanked.cut {
return;
}

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::LinkOpt;
use crate::{mgr::Mgr, tasks::Tasks};
struct Opt {
relative: bool,
force: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { relative: c.bool("relative"), force: c.bool("force") } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn link(&mut self, opt: Opt, tasks: &Tasks) {
pub fn link(&mut self, opt: LinkOpt, tasks: &Tasks) {
if self.yanked.cut {
return;
}

View file

@ -3,27 +3,16 @@ use std::{borrow::Cow, iter};
use tracing::error;
use yazi_config::{YAZI, popup::PickCfg};
use yazi_fs::File;
use yazi_parser::mgr::OpenOpt;
use yazi_plugin::isolate;
use yazi_proxy::{MgrProxy, PickProxy, TasksProxy, options::OpenDoOpt};
use yazi_shared::{MIME_DIR, event::CmdCow, url::Url};
use crate::{mgr::Mgr, tab::Folder, tasks::Tasks};
#[derive(Clone, Copy)]
pub(super) struct Opt {
pub(super) interactive: bool,
pub(super) hovered: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { interactive: c.bool("interactive"), hovered: c.bool("hovered") }
}
}
impl Mgr {
#[yazi_codegen::command]
pub fn open(&mut self, opt: Opt, tasks: &Tasks) {
pub fn open(&mut self, opt: OpenOpt, tasks: &Tasks) {
if !self.active_mut().try_escape_visual() {
return;
}

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::PasteOpt;
use crate::{mgr::Mgr, tasks::Tasks};
struct Opt {
force: bool,
follow: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { force: c.bool("force"), follow: c.bool("follow") } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn paste(&mut self, opt: Opt, tasks: &Tasks) {
pub fn paste(&mut self, opt: PasteOpt, tasks: &Tasks) {
let (src, dest) = (self.yanked.iter().collect::<Vec<_>>(), self.cwd());
if self.yanked.cut {

View file

@ -1,33 +1,11 @@
use yazi_parser::mgr::PeekOpt;
use yazi_proxy::HIDER;
use yazi_shared::{event::{CmdCow, Data}, url::Url};
use crate::mgr::Mgr;
#[derive(Debug, Default)]
struct Opt {
skip: Option<usize>,
force: bool,
only_if: Option<Url>,
upper_bound: bool,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
skip: c.first().and_then(Data::as_usize),
force: c.bool("force"),
only_if: c.take_url("only-if"),
upper_bound: c.bool("upper-bound"),
}
}
}
impl From<bool> for Opt {
fn from(force: bool) -> Self { Self { force, ..Default::default() } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn peek(&mut self, opt: Opt) {
pub fn peek(&mut self, opt: PeekOpt) {
let Some(hovered) = self.hovered().cloned() else {
return self.active_mut().preview.reset();
};

View file

@ -4,35 +4,15 @@ use tokio::{select, time};
use yazi_boot::ARGS;
use yazi_config::popup::ConfirmCfg;
use yazi_macro::emit;
use yazi_parser::mgr::{OpenOpt, QuitOpt};
use yazi_proxy::ConfirmProxy;
use yazi_shared::{event::{CmdCow, Data, EventQuit}, url::Url};
use yazi_shared::{event::EventQuit, url::Url};
use crate::{mgr::Mgr, tasks::Tasks};
#[derive(Default)]
pub(super) struct Opt {
pub(super) code: i32,
pub(super) no_cwd_file: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self {
code: c.get("code").and_then(Data::as_i32).unwrap_or_default(),
no_cwd_file: c.bool("no-cwd-file"),
}
}
}
impl From<Opt> for EventQuit {
fn from(value: Opt) -> Self {
EventQuit { code: value.code, no_cwd_file: value.no_cwd_file, ..Default::default() }
}
}
impl Mgr {
#[yazi_codegen::command]
pub fn quit(&self, opt: Opt, tasks: &Tasks) {
pub fn quit(&self, opt: QuitOpt, tasks: &Tasks) {
let event = opt.into();
let ongoing = tasks.ongoing().clone();
@ -74,7 +54,7 @@ impl Mgr {
});
}
pub(super) fn quit_with_selected<'a, I>(opt: super::open::Opt, selected: I) -> bool
pub(super) fn quit_with_selected<'a, I>(opt: OpenOpt, selected: I) -> bool
where
I: Iterator<Item = &'a Url>,
{

View file

@ -1,30 +1,12 @@
use yazi_config::popup::ConfirmCfg;
use yazi_parser::mgr::RemoveOpt;
use yazi_proxy::{ConfirmProxy, MgrProxy};
use yazi_shared::{event::CmdCow, url::Url};
use crate::{mgr::Mgr, tasks::Tasks};
struct Opt {
force: bool,
permanently: bool,
hovered: bool,
targets: Vec<Url>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
force: c.bool("force"),
permanently: c.bool("permanently"),
hovered: c.bool("hovered"),
targets: c.take_any("targets").unwrap_or_default(),
}
}
}
impl Mgr {
#[yazi_codegen::command]
pub fn remove(&mut self, mut opt: Opt, tasks: &Tasks) {
pub fn remove(&mut self, mut opt: RemoveOpt, tasks: &Tasks) {
if !self.active_mut().try_escape_visual() {
return;
}
@ -55,7 +37,7 @@ impl Mgr {
}
#[yazi_codegen::command]
pub fn remove_do(&mut self, opt: Opt, tasks: &Tasks) {
pub fn remove_do(&mut self, opt: RemoveOpt, tasks: &Tasks) {
self.tabs.iter_mut().for_each(|t| {
t.selected.remove_many(&opt.targets);
});

View file

@ -1,37 +1,18 @@
use std::borrow::Cow;
use anyhow::Result;
use tokio::fs;
use yazi_config::popup::{ConfirmCfg, InputCfg};
use yazi_dds::Pubsub;
use yazi_fs::{File, FilesOp, maybe_exists, ok_or_not_found, paths_to_same_file, realname};
use yazi_macro::err;
use yazi_parser::mgr::RenameOpt;
use yazi_proxy::{ConfirmProxy, InputProxy, TabProxy, WATCHER};
use yazi_shared::{Id, event::CmdCow, url::{Url, UrnBuf}};
use yazi_shared::{Id, url::{Url, UrnBuf}};
use crate::mgr::Mgr;
struct Opt {
hovered: bool,
force: bool,
empty: Cow<'static, str>,
cursor: Cow<'static, str>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
hovered: c.bool("hovered"),
force: c.bool("force"),
empty: c.take_str("empty").unwrap_or_default(),
cursor: c.take_str("cursor").unwrap_or_default(),
}
}
}
impl Mgr {
#[yazi_codegen::command]
pub fn rename(&mut self, opt: Opt) {
pub fn rename(&mut self, opt: RenameOpt) {
if !self.active_mut().try_escape_visual() {
return;
} else if !opt.hovered && !self.active().selected.is_empty() {

View file

@ -1,21 +1,12 @@
use yazi_config::YAZI;
use yazi_parser::mgr::SeekOpt;
use yazi_plugin::isolate;
use yazi_shared::event::{CmdCow, Data};
use crate::mgr::Mgr;
#[derive(Debug)]
struct Opt {
units: i16,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { units: c.first().and_then(Data::as_i16).unwrap_or(0) } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn seek(&mut self, opt: Opt) {
pub fn seek(&mut self, opt: SeekOpt) {
let Some(hovered) = self.hovered() else {
return self.active_mut().preview.reset();
};

View file

@ -1,18 +1,10 @@
use yazi_shared::event::{CmdCow, Data};
use yazi_parser::mgr::SpotOpt;
use crate::mgr::Mgr;
struct Opt {
skip: Option<usize>,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { skip: c.get("skip").and_then(Data::as_usize) } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn spot(&mut self, opt: Opt) {
pub fn spot(&mut self, opt: SpotOpt) {
let Some(hovered) = self.hovered().cloned() else {
return;
};

View file

@ -1,23 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_parser::mgr::TabCloseOpt;
use crate::mgr::Tabs;
struct Opt {
idx: usize,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { idx: c.first().and_then(Data::as_usize).unwrap_or(0) } }
}
impl From<usize> for Opt {
fn from(idx: usize) -> Self { Self { idx } }
}
impl Tabs {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
pub fn close(&mut self, opt: TabCloseOpt) {
let len = self.items.len();
if len < 2 || opt.idx >= len {
return;

View file

@ -1,35 +1,14 @@
use yazi_boot::BOOT;
use yazi_fs::expand_path;
use yazi_macro::render;
use yazi_parser::{mgr::TabCreateOpt, tab::CdSource};
use yazi_proxy::AppProxy;
use yazi_shared::{event::CmdCow, url::Url};
use crate::{mgr::Tabs, tab::{Tab, commands::CdSource}};
use crate::{mgr::Tabs, tab::Tab};
const MAX_TABS: usize = 9;
struct Opt {
wd: Option<Url>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
if c.bool("current") {
return Self { wd: None };
}
let Some(mut wd) = c.take_first_url() else {
return Self { wd: Some(Url::from(&BOOT.cwds[0])) };
};
if wd.is_regular() && !c.bool("raw") {
wd = Url::from(expand_path(wd));
}
Self { wd: Some(wd) }
}
}
impl Tabs {
#[yazi_codegen::command]
pub fn create(&mut self, opt: Opt) {
pub fn create(&mut self, opt: TabCreateOpt) {
if self.items.len() >= MAX_TABS {
AppProxy::notify_warn("Too many tabs", "You can only open up to 9 tabs at the same time.");
return;

View file

@ -1,19 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_parser::mgr::TabSwapOpt;
use crate::mgr::Tabs;
struct Opt {
step: isize,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
}
impl Tabs {
#[yazi_codegen::command]
pub fn swap(&mut self, opt: Opt) {
pub fn swap(&mut self, opt: TabSwapOpt) {
let idx = opt.step.saturating_add_unsigned(self.cursor).rem_euclid(self.items.len() as _) as _;
if idx == self.cursor {
return;

View file

@ -1,22 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data};
use yazi_parser::mgr::TabSwitchOpt;
use crate::mgr::Tabs;
struct Opt {
step: isize,
relative: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(Data::as_isize).unwrap_or(0), relative: c.bool("relative") }
}
}
impl Tabs {
#[yazi_codegen::command]
pub fn switch(&mut self, opt: Opt) {
pub fn switch(&mut self, opt: TabSwitchOpt) {
let idx = if opt.relative {
opt.step.saturating_add_unsigned(self.cursor).rem_euclid(self.items.len() as _) as _
} else {

View file

@ -1,20 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::UnyankOpt;
use crate::mgr::Mgr;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl From<()> for Opt {
fn from(_: ()) -> Self { Self }
}
impl Mgr {
#[yazi_codegen::command]
pub fn unyank(&mut self, _: Opt) {
pub fn unyank(&mut self, _: UnyankOpt) {
let repeek = self.hovered().is_some_and(|f| f.is_dir() && self.yanked.contains_in(&f.url));
self.yanked.clear();

View file

@ -1,23 +1,11 @@
use yazi_fs::FilesOp;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::UpdateFilesOpt;
use crate::{mgr::{LINKED, Mgr}, tab::Folder, tasks::Tasks};
pub struct Opt {
op: FilesOp,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { op: c.take_any("op").ok_or(())? })
}
}
impl Mgr {
pub fn update_files(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
pub fn update_files(&mut self, opt: impl TryInto<UpdateFilesOpt>, tasks: &Tasks) {
let Ok(opt) = opt.try_into() else {
return;
};

View file

@ -2,25 +2,13 @@ use std::collections::HashMap;
use tracing::error;
use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data, DataKey};
use yazi_parser::mgr::UpdateMimesOpt;
use crate::{mgr::{LINKED, Mgr}, tasks::Tasks};
pub struct Opt {
updates: HashMap<DataKey, Data>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { updates: c.try_take("updates").and_then(Data::into_dict).ok_or(())? })
}
}
impl Mgr {
pub fn update_mimes(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
let Ok(opt): Result<Opt, _> = opt.try_into() else {
pub fn update_mimes(&mut self, opt: impl TryInto<UpdateMimesOpt>, tasks: &Tasks) {
let Ok(opt): Result<UpdateMimesOpt, _> = opt.try_into() else {
return error!("invalid arguments for update_mimes");
};

View file

@ -1,26 +1,10 @@
use yazi_shared::{event::{CmdCow, Data}, url::Url};
use yazi_parser::mgr::UpdatePagedOpt;
use crate::{mgr::Mgr, tasks::Tasks};
#[derive(Default)]
pub struct Opt {
page: Option<usize>,
only_if: Option<Url>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self { page: c.first().and_then(Data::as_usize), only_if: c.take_url("only-if") }
}
}
impl From<()> for Opt {
fn from(_: ()) -> Self { Self::default() }
}
impl Mgr {
pub fn update_paged(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
let Ok(opt): Result<Opt, _> = opt.try_into() else {
pub fn update_paged(&mut self, opt: impl TryInto<UpdatePagedOpt>, tasks: &Tasks) {
let Ok(opt): Result<UpdatePagedOpt, _> = opt.try_into() else {
return;
};

View file

@ -1,21 +1,9 @@
use yazi_shared::{event::CmdCow, url::Url};
use yazi_parser::mgr::UpdateTasksOpt;
use crate::mgr::Mgr;
pub struct Opt {
urls: Vec<Url>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { urls: c.take_any("urls").ok_or(())? })
}
}
impl Mgr {
pub fn update_tasks(&mut self, opt: impl TryInto<Opt>) {
pub fn update_tasks(&mut self, opt: impl TryInto<UpdateTasksOpt>) {
let Ok(opt) = opt.try_into() else {
return;
};

View file

@ -1,30 +1,10 @@
use std::collections::HashSet;
use yazi_macro::render;
use yazi_shared::{event::CmdCow, url::Url};
use yazi_parser::mgr::UpdateYankedOpt;
use crate::mgr::{Mgr, Yanked};
#[derive(Default)]
pub struct Opt {
cut: bool,
urls: HashSet<Url>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
if let Some(iter) = c.take_any::<yazi_dds::body::BodyYankIter>("urls") {
Ok(Self { urls: iter.urls.into_iter().collect(), cut: iter.cut })
} else {
Err(())
}
}
}
impl Mgr {
pub fn update_yanked(&mut self, opt: impl TryInto<Opt>) {
pub fn update_yanked(&mut self, opt: impl TryInto<UpdateYankedOpt>) {
let Ok(opt) = opt.try_into() else { return };
if opt.urls.is_empty() && self.yanked.is_empty() {

View file

@ -1,21 +1,12 @@
use std::collections::HashSet;
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::WatchOpt;
use crate::mgr::Mgr;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl From<()> for Opt {
fn from((): ()) -> Self { Self }
}
impl Mgr {
#[yazi_codegen::command]
pub fn watch(&mut self, _: Opt) {
pub fn watch(&mut self, _: WatchOpt) {
let mut to_watch = HashSet::with_capacity(3 * self.tabs.len());
for tab in self.tabs.iter() {
to_watch.insert(tab.cwd());

View file

@ -1,19 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::mgr::YankOpt;
use crate::mgr::{Mgr, Yanked};
struct Opt {
cut: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { cut: c.bool("cut") } }
}
impl Mgr {
#[yazi_codegen::command]
pub fn yank(&mut self, opt: Opt) {
pub fn yank(&mut self, opt: YankOpt) {
if !self.active_mut().try_escape_visual() {
return;
}

View file

@ -4,10 +4,11 @@ use yazi_boot::BOOT;
use yazi_dds::Pubsub;
use yazi_fs::File;
use yazi_macro::err;
use yazi_parser::tab::CdSource;
use yazi_proxy::MgrProxy;
use yazi_shared::{Id, url::Url};
use crate::tab::{Folder, Tab, commands::CdSource};
use crate::tab::{Folder, Tab};
pub struct Tabs {
pub cursor: usize,

View file

@ -1,36 +1,13 @@
use std::time::Duration;
use ratatui::layout::Rect;
use yazi_parser::notify::TickOpt;
use yazi_proxy::AppProxy;
use yazi_shared::event::{Cmd, CmdCow, Data};
use crate::notify::Notify;
pub struct Opt {
interval: Duration,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(c: CmdCow) -> Result<Self, Self::Error> {
let interval = c.first().and_then(Data::as_f64).ok_or(())?;
if interval < 0.0 {
return Err(());
}
Ok(Self { interval: Duration::from_secs_f64(interval) })
}
}
impl TryFrom<Cmd> for Opt {
type Error = ();
fn try_from(c: Cmd) -> Result<Self, Self::Error> { Self::try_from(CmdCow::from(c)) }
}
impl Notify {
pub fn tick(&mut self, opt: impl TryInto<Opt>, area: Rect) {
pub fn tick(&mut self, opt: impl TryInto<TickOpt>, area: Rect) {
self.tick_handle.take().map(|h| h.abort());
let Ok(opt) = opt.try_into() else {
return;

View file

@ -1,23 +1,13 @@
use yazi_config::YAZI;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_widgets::{Scrollable, Step};
use yazi_parser::pick::ArrowOpt;
use yazi_widgets::Scrollable;
use crate::pick::Pick;
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Pick {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step));
}
}

View file

@ -1,23 +1,12 @@
use anyhow::anyhow;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::pick::CloseOpt;
use crate::pick::Pick;
struct Opt {
submit: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { submit: c.bool("submit") } }
}
impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } }
}
impl Pick {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
pub fn close(&mut self, opt: CloseOpt) {
if let Some(cb) = self.callback.take() {
_ = cb.send(if opt.submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) });
}

View file

@ -1,25 +1,10 @@
use tokio::sync::oneshot;
use yazi_config::popup::PickCfg;
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::pick::ShowOpt;
use crate::pick::Pick;
pub struct Opt {
cfg: PickCfg,
tx: oneshot::Sender<anyhow::Result<usize>>,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { cfg: c.take_any("cfg").ok_or(())?, tx: c.take_any("tx").ok_or(())? })
}
}
impl Pick {
pub fn show(&mut self, opt: impl TryInto<Opt>) {
pub fn show(&mut self, opt: impl TryInto<ShowOpt>) {
let Ok(opt) = opt.try_into() else {
return;
};

View file

@ -1,23 +1,12 @@
use yazi_macro::render;
use yazi_parser::spot::ArrowOpt;
use yazi_proxy::MgrProxy;
use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use crate::spot::Spot;
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl Spot {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
pub fn arrow(&mut self, opt: ArrowOpt) {
let Some(lock) = &mut self.lock else { return };
let new = opt.step.add(self.skip, lock.len().unwrap_or(u16::MAX as _), 0);

View file

@ -1,17 +1,8 @@
use yazi_shared::event::CmdCow;
use yazi_parser::spot::CloseOpt;
use crate::spot::Spot;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl From<()> for Opt {
fn from(_: ()) -> Self { Self }
}
impl Spot {
#[yazi_codegen::command]
pub fn close(&mut self, _: Opt) { self.reset(); }
pub fn close(&mut self, _: CloseOpt) { self.reset(); }
}

View file

@ -1,21 +1,11 @@
use std::borrow::Cow;
use yazi_plugin::CLIPBOARD;
use yazi_shared::event::CmdCow;
use yazi_parser::spot::CopyOpt;
use yazi_widgets::CLIPBOARD;
use crate::spot::Spot;
struct Opt {
r#type: Cow<'static, str>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self { Self { r#type: c.take_first_str().unwrap_or_default() } }
}
impl Spot {
#[yazi_codegen::command]
pub fn copy(&mut self, opt: Opt) {
pub fn copy(&mut self, opt: CopyOpt) {
let Some(lock) = &self.lock else { return };
let Some(table) = lock.table() else { return };

View file

@ -1,21 +1,11 @@
use std::borrow::Cow;
use yazi_parser::spot::SwipeOpt;
use yazi_proxy::{MgrProxy, TabProxy};
use yazi_shared::event::CmdCow;
use crate::spot::Spot;
struct Opt {
step: Cow<'static, str>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self { Self { step: c.take_first_str().unwrap_or_default() } }
}
impl Spot {
#[yazi_codegen::command]
pub fn swipe(&mut self, opt: Opt) {
pub fn swipe(&mut self, opt: SwipeOpt) {
TabProxy::arrow(opt.step);
MgrProxy::spot(None);
}

View file

@ -4,7 +4,8 @@ use tokio_util::sync::CancellationToken;
use yazi_config::YAZI;
use yazi_fs::File;
use yazi_macro::render;
use yazi_plugin::{isolate, utils::SpotLock};
use yazi_parser::tab::SpotLock;
use yazi_plugin::isolate;
use yazi_shared::url::Url;
#[derive(Default)]

View file

@ -1,27 +1,12 @@
use yazi_macro::render;
use yazi_parser::tab::ArrowOpt;
use yazi_proxy::MgrProxy;
use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use crate::tab::Tab;
struct Opt {
step: Step,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
Self { step: c.first().and_then(|d| d.try_into().ok()).unwrap_or_default() }
}
}
impl From<isize> for Opt {
fn from(n: isize) -> Self { Self { step: n.into() } }
}
impl Tab {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
pub fn arrow(&mut self, opt: ArrowOpt) {
if !self.current.arrow(opt.step) {
return;
}

View file

@ -1,6 +1,6 @@
use yazi_parser::tab::CdSource;
use yazi_shared::event::CmdCow;
use super::cd::CdSource;
use crate::tab::Tab;
impl Tab {

View file

@ -6,34 +6,15 @@ use yazi_config::popup::InputCfg;
use yazi_dds::Pubsub;
use yazi_fs::{File, FilesOp, expand_path};
use yazi_macro::{err, render};
use yazi_parser::tab::CdOpt;
use yazi_proxy::{CmpProxy, InputProxy, MgrProxy, TabProxy};
use yazi_shared::{Debounce, errors::InputError, event::CmdCow, url::Url};
use yazi_shared::{Debounce, errors::InputError, url::Url};
use crate::tab::Tab;
struct Opt {
target: Url,
interactive: bool,
source: CdSource,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
let mut target = c.take_first_url().unwrap_or_default();
if target.is_regular() && !c.bool("raw") {
target = Url::from(expand_path(target));
}
Self { target, interactive: c.bool("interactive"), source: CdSource::Cd }
}
}
impl From<(Url, CdSource)> for Opt {
fn from((target, source): (Url, CdSource)) -> Self { Self { target, interactive: false, source } }
}
impl Tab {
#[yazi_codegen::command]
pub fn cd(&mut self, opt: Opt) {
pub fn cd(&mut self, opt: CdOpt) {
if !self.try_escape_visual() {
return;
}
@ -111,20 +92,3 @@ impl Tab {
});
}
}
// --- OptSource
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum CdSource {
Tab,
Cd,
Reveal,
Enter,
Leave,
Forward,
Back,
}
impl CdSource {
#[inline]
fn big_jump(self) -> bool { self == Self::Cd || self == Self::Reveal }
}

View file

@ -1,29 +1,13 @@
use std::{borrow::Cow, ffi::{OsStr, OsString}, path::Path};
use std::{ffi::OsString, path::Path};
use yazi_plugin::CLIPBOARD;
use yazi_shared::event::CmdCow;
use yazi_parser::tab::CopyOpt;
use yazi_widgets::CLIPBOARD;
use crate::tab::Tab;
struct Opt {
r#type: Cow<'static, str>,
separator: Separator,
hovered: bool,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
r#type: c.take_first_str().unwrap_or_default(),
separator: c.str("separator").unwrap_or_default().into(),
hovered: c.bool("hovered"),
}
}
}
impl Tab {
#[yazi_codegen::command]
pub fn copy(&mut self, opt: Opt) {
pub fn copy(&mut self, opt: CopyOpt) {
if !self.try_escape_visual() {
return;
}
@ -57,32 +41,3 @@ impl Tab {
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_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())
}
}

View file

@ -1,6 +1,6 @@
use yazi_parser::tab::CdSource;
use yazi_shared::event::CmdCow;
use super::cd::CdSource;
use crate::tab::Tab;
impl Tab {

View file

@ -1,39 +1,12 @@
use bitflags::bitflags;
use yazi_macro::{render, render_and};
use yazi_parser::tab::{EscapeOpt, FilterOpt};
use yazi_proxy::{AppProxy, MgrProxy};
use yazi_shared::event::CmdCow;
use crate::tab::Tab;
bitflags! {
struct Opt: u8 {
const FIND = 0b00001;
const VISUAL = 0b00010;
const FILTER = 0b00100;
const SELECT = 0b01000;
const SEARCH = 0b10000;
}
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self {
c.args.iter().fold(Opt::empty(), |acc, (k, v)| {
match (k.as_str().unwrap_or(""), v.as_bool().unwrap_or(false)) {
("all", true) => Self::all(),
("find", true) => acc | Self::FIND,
("visual", true) => acc | Self::VISUAL,
("filter", true) => acc | Self::FILTER,
("select", true) => acc | Self::SELECT,
("search", true) => acc | Self::SEARCH,
_ => acc,
}
})
}
}
impl Tab {
#[yazi_codegen::command]
pub fn escape(&mut self, opt: Opt) {
pub fn escape(&mut self, opt: EscapeOpt) {
if opt.is_empty() {
_ = self.escape_find()
|| self.escape_visual()
@ -43,19 +16,19 @@ impl Tab {
return;
}
if opt.contains(Opt::FIND) {
if opt.contains(EscapeOpt::FIND) {
self.escape_find();
}
if opt.contains(Opt::VISUAL) {
if opt.contains(EscapeOpt::VISUAL) {
self.escape_visual();
}
if opt.contains(Opt::FILTER) {
if opt.contains(EscapeOpt::FILTER) {
self.escape_filter();
}
if opt.contains(Opt::SELECT) {
if opt.contains(EscapeOpt::SELECT) {
self.escape_select();
}
if opt.contains(Opt::SEARCH) {
if opt.contains(EscapeOpt::SEARCH) {
self.escape_search();
}
}
@ -76,7 +49,7 @@ impl Tab {
return false;
}
self.filter_do(super::filter::Opt::default());
self.filter_do(FilterOpt::default());
render_and!(true)
}

View file

@ -1,35 +1,19 @@
use std::{borrow::Cow, time::Duration};
use std::time::Duration;
use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg;
use yazi_fs::FilterCase;
use yazi_macro::emit;
use yazi_parser::tab::FilterOpt;
use yazi_proxy::InputProxy;
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, CmdCow}};
use yazi_shared::{Debounce, errors::InputError, event::Cmd};
use crate::tab::Tab;
#[derive(Default)]
pub(super) struct Opt {
pub query: Cow<'static, str>,
pub case: FilterCase,
pub done: bool,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
query: c.take_first_str().unwrap_or_default(),
case: FilterCase::from(&*c),
done: c.bool("done"),
}
}
}
impl Tab {
#[yazi_codegen::command]
pub fn filter(&mut self, opt: Opt) {
pub fn filter(&mut self, opt: FilterOpt) {
let input = InputProxy::show(InputCfg::filter());
tokio::spawn(async move {

View file

@ -1,13 +1,13 @@
use yazi_fs::Filter;
use yazi_macro::render;
use yazi_parser::tab::FilterOpt;
use yazi_proxy::MgrProxy;
use super::filter::Opt;
use crate::tab::Tab;
impl Tab {
#[yazi_codegen::command]
pub fn filter_do(&mut self, opt: Opt) {
pub fn filter_do(&mut self, opt: FilterOpt) {
let filter = if opt.query.is_empty() {
None
} else if let Ok(f) = Filter::new(&opt.query, opt.case) {

View file

@ -1,30 +1,19 @@
use std::{borrow::Cow, time::Duration};
use std::time::Duration;
use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg;
use yazi_fs::FilterCase;
use yazi_macro::emit;
use yazi_parser::tab::FindOpt;
use yazi_proxy::InputProxy;
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, CmdCow}};
use yazi_shared::{Debounce, errors::InputError, event::Cmd};
use crate::tab::Tab;
pub(super) struct Opt {
pub(super) query: Option<Cow<'static, str>>,
pub(super) prev: bool,
pub(super) case: FilterCase,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self { query: c.take_first_str(), prev: c.bool("previous"), case: FilterCase::from(&*c) }
}
}
impl Tab {
#[yazi_codegen::command]
pub fn find(&mut self, opt: Opt) {
pub fn find(&mut self, opt: FindOpt) {
let input = InputProxy::show(InputCfg::find(opt.prev));
tokio::spawn(async move {

View file

@ -1,19 +1,11 @@
use yazi_macro::render;
use yazi_shared::event::CmdCow;
use yazi_parser::tab::FindArrowOpt;
use crate::tab::Tab;
struct Opt {
prev: bool,
}
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self { prev: c.bool("previous") } }
}
impl Tab {
#[yazi_codegen::command]
pub fn find_arrow(&mut self, opt: Opt) {
pub fn find_arrow(&mut self, opt: FindArrowOpt) {
let Some(finder) = &mut self.finder else {
return;
};

View file

@ -1,11 +1,11 @@
use yazi_macro::render;
use yazi_parser::tab::FindOpt;
use super::find::Opt;
use crate::tab::{Finder, Tab};
impl Tab {
#[yazi_codegen::command]
pub fn find_do(&mut self, opt: Opt) {
pub fn find_do(&mut self, opt: FindOpt) {
let Some(query) = opt.query else {
return;
};

View file

@ -1,17 +1,11 @@
use yazi_fs::clean_url;
use yazi_shared::event::CmdCow;
use yazi_parser::tab::FollowOpt;
use crate::tab::Tab;
struct Opt;
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl Tab {
#[yazi_codegen::command]
pub fn follow(&mut self, _: Opt) {
pub fn follow(&mut self, _: FollowOpt) {
let Some(file) = self.hovered() else { return };
let Some(link_to) = &file.link_to else { return };

View file

@ -1,6 +1,6 @@
use yazi_parser::tab::CdSource;
use yazi_shared::event::CmdCow;
use super::cd::CdSource;
use crate::tab::Tab;
impl Tab {

View file

@ -1,23 +1,13 @@
use yazi_dds::Pubsub;
use yazi_macro::{err, render};
use yazi_shared::{event::CmdCow, url::{Url, Urn}};
use yazi_parser::tab::HoverOpt;
use yazi_shared::url::{Url, Urn};
use crate::tab::Tab;
struct Opt {
url: Option<Url>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self { Self { url: c.take_first_url() } }
}
impl From<Option<Url>> for Opt {
fn from(url: Option<Url>) -> Self { Self { url } }
}
impl Tab {
#[yazi_codegen::command]
pub fn hover(&mut self, opt: Opt) {
pub fn hover(&mut self, opt: HoverOpt) {
if let Some(u) = opt.url {
self.hover_do(u);
} else {

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow;
use yazi_parser::tab::{CdSource, LeaveOpt};
use super::cd::CdSource;
use crate::tab::Tab;
struct Opt;
impl From<()> for Opt {
fn from(_: ()) -> Self { Self }
}
impl From<CmdCow> for Opt {
fn from(_: CmdCow) -> Self { Self }
}
impl Tab {
#[yazi_codegen::command]
pub fn leave(&mut self, _: Opt) {
pub fn leave(&mut self, _: LeaveOpt) {
self
.current
.hovered()

View file

@ -1,38 +1,12 @@
use yazi_fs::{File, FilesOp, expand_path};
use yazi_fs::{File, FilesOp};
use yazi_parser::tab::RevealOpt;
use yazi_proxy::MgrProxy;
use yazi_shared::{event::CmdCow, url::Url};
use super::cd::CdSource;
use crate::tab::Tab;
struct Opt {
target: Url,
source: CdSource,
no_dummy: bool,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
let mut target = c.take_first_url().unwrap_or_default();
if target.is_regular() && !c.bool("raw") {
target = Url::from(expand_path(target));
}
Self { target, source: CdSource::Reveal, no_dummy: c.bool("no-dummy") }
}
}
impl From<Url> for Opt {
fn from(target: Url) -> Self { Self { target, source: CdSource::Reveal, no_dummy: false } }
}
impl From<(Url, CdSource)> for Opt {
fn from((target, source): (Url, CdSource)) -> Self { Self { target, source, no_dummy: false } }
}
impl Tab {
#[yazi_codegen::command]
pub fn reveal(&mut self, opt: Opt) {
pub fn reveal(&mut self, opt: RevealOpt) {
let Some((parent, child)) = opt.target.pair() else {
return;
};

View file

@ -1,54 +1,19 @@
use std::{borrow::Cow, fmt::Display};
use anyhow::bail;
use yazi_config::{opener::OpenerRule, popup::InputCfg};
use yazi_parser::tab::ShellOpt;
use yazi_proxy::{AppProxy, InputProxy, TasksProxy};
use yazi_shared::{event::{CmdCow, Data}, url::Url};
use crate::tab::Tab;
pub struct Opt {
run: Cow<'static, str>,
cwd: Option<Url>,
block: bool,
orphan: bool,
interactive: bool,
cursor: Option<usize>,
}
impl TryFrom<CmdCow> for Opt {
type Error = anyhow::Error;
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
let me = Self {
run: c.take_first_str().unwrap_or_default(),
cwd: c.take_url("cwd"),
block: c.bool("block"),
orphan: c.bool("orphan"),
interactive: c.bool("interactive"),
cursor: c.get("cursor").and_then(Data::as_usize),
};
if me.cursor.is_some_and(|c| c > me.run.chars().count()) {
bail!("The cursor position is out of bounds.");
}
Ok(me)
}
}
impl Tab {
pub fn shell(&mut self, opt: impl TryInto<Opt, Error = impl Display>) {
pub fn shell(&mut self, opt: impl TryInto<ShellOpt, Error = impl Display>) {
if !self.try_escape_visual() {
return;
}
let mut opt = match opt.try_into() {
Ok(o) => o as Opt,
Ok(o) => o as ShellOpt,
Err(e) => return AppProxy::notify_warn("`shell` command", e),
};

View file

@ -1,30 +1,12 @@
use yazi_macro::render_and;
use yazi_parser::tab::ToggleOpt;
use yazi_proxy::AppProxy;
use yazi_shared::{event::CmdCow, url::Url};
use crate::tab::Tab;
struct Opt {
url: Option<Url>,
state: Option<bool>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
Self {
url: c.take_first_url(),
state: match c.str("state") {
Some("on") => Some(true),
Some("off") => Some(false),
_ => None,
},
}
}
}
impl Tab {
#[yazi_codegen::command]
pub fn toggle(&mut self, opt: Opt) {
pub fn toggle(&mut self, opt: ToggleOpt) {
let Some(url) = opt.url.as_ref().or(self.current.hovered().map(|h| &h.url)) else {
return;
};

View file

@ -1,42 +1,12 @@
use yazi_macro::render;
use yazi_parser::tab::ToggleAllOpt;
use yazi_proxy::AppProxy;
use yazi_shared::{event::CmdCow, url::Url};
use crate::tab::Tab;
struct Opt {
urls: Vec<Url>,
state: Option<bool>,
}
impl From<CmdCow> for Opt {
fn from(mut c: CmdCow) -> Self {
let mut urls = Vec::with_capacity(c.len());
for i in 0..c.len() {
match c.take_url(i) {
Some(url) => urls.push(url),
None => break,
}
}
Self {
urls,
state: match c.str("state") {
Some("on") => Some(true),
Some("off") => Some(false),
_ => None,
},
}
}
}
impl From<Option<bool>> for Opt {
fn from(state: Option<bool>) -> Self { Self { urls: vec![], state } }
}
impl Tab {
#[yazi_codegen::command]
pub fn toggle_all(&mut self, opt: Opt) {
pub fn toggle_all(&mut self, opt: ToggleAllOpt) {
use yazi_shared::Either::*;
let it = self.current.files.iter().map(|f| &f.url);

View file

@ -1,28 +1,15 @@
use yazi_macro::render;
use yazi_plugin::utils::PreviewLock;
use yazi_shared::event::CmdCow;
use yazi_parser::tab::UpdatePeekedOpt;
use crate::tab::Tab;
pub struct Opt {
lock: PreviewLock,
}
impl TryFrom<CmdCow> for Opt {
type Error = ();
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
Ok(Self { lock: c.take_any("lock").ok_or(())? })
}
}
impl Tab {
pub fn update_peeked(&mut self, opt: impl TryInto<Opt>) {
pub fn update_peeked(&mut self, opt: impl TryInto<UpdatePeekedOpt>) {
let Some(hovered) = self.hovered().map(|h| &h.url) else {
return self.preview.reset();
};
let Ok(opt) = opt.try_into() else {
let Ok(opt): Result<UpdatePeekedOpt, _> = opt.try_into() else {
return;
};

Some files were not shown because too many files have changed in this diff Show more