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

View file

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

View file

@ -9,13 +9,21 @@ homepage = "https://yazi-rs.github.io"
repository = "https://github.com/sxyazi/yazi" repository = "https://github.com/sxyazi/yazi"
[dependencies] [dependencies]
yazi-config = { path = "../yazi-config", version = "25.6.11" } yazi-adapter = { path = "../yazi-adapter", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" } yazi-config = { path = "../yazi-config", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", version = "25.6.11" } yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-shared = { path = "../yazi-shared", 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 # External dependencies
mlua = { workspace = true } ansi-to-tui = { workspace = true }
paste = { workspace = true } mlua = { workspace = true }
ratatui = { workspace = true } paste = { workspace = true }
serde_json = { 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)] #[derive(Clone, Debug, Default)]
pub struct Border { pub struct Border {
pub(crate) area: Area, pub area: Area,
pub(crate) edge: Edge, pub edge: Edge,
pub(crate) r#type: ratatui::widgets::BorderType, pub r#type: ratatui::widgets::BorderType,
pub(crate) style: ratatui::style::Style, 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 { impl Border {

View file

@ -22,7 +22,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
b"Rect" => super::Rect::compose(lua)?, b"Rect" => super::Rect::compose(lua)?,
b"Row" => super::Row::compose(lua)?, b"Row" => super::Row::compose(lua)?,
b"Span" => super::Span::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"Table" => super::Table::compose(lua)?,
b"Text" => super::Text::compose(lua)?, b"Text" => super::Text::compose(lua)?,
b"Wrap" => super::Wrap::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 mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget; use ratatui::widgets::Widget;
use yazi_binding::Style;
use super::{Area, Span}; use super::{Area, Span};
use crate::Style;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Gauge { pub struct Gauge {

View file

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

View file

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

View file

@ -69,7 +69,7 @@ impl TryFrom<Value> for Span {
impl UserData for Span { impl UserData for Span {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) { fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
crate::impl_style_method!(methods, 0.style); 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), ()| { methods.add_method("visible", |_, Span(me), ()| {
Ok(me.content.chars().any(|c| c.width().unwrap_or(0) > 0)) 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 mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, UserData, Value};
use ratatui::widgets::StatefulWidget; use ratatui::widgets::StatefulWidget;
use yazi_binding::Style;
use super::{Area, Row}; use super::{Area, Row};
use crate::elements::Constraint; use crate::{Style, elements::Constraint};
const EXPECTED: &str = "expected a table of Rows"; const EXPECTED: &str = "expected a table of Rows";
// --- Table // --- Table
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Table { pub struct Table {
pub(crate) area: Area, pub area: Area,
rows: Vec<Row>, rows: Vec<Row>,
header: Option<ratatui::widgets::Row<'static>>, header: Option<ratatui::widgets::Row<'static>>,
@ -84,15 +83,15 @@ impl Table {
} }
#[inline] #[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 self
.state .state
.select(idx.map(|i| if self.rows.is_empty() { 0 } else { i.min(self.rows.len() - 1) })); .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)) } 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 ansi_to_tui::IntoText;
use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value}; use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use ratatui::widgets::Widget; use ratatui::widgets::Widget;
use yazi_binding::Error;
use super::{Area, Line, Span, Wrap}; 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"; 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) { fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods); crate::impl_area_method!(methods);
crate::impl_style_method!(methods, inner.style); 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)| { methods.add_function_mut("align", |_, (ud, align): (AnyUserData, Align)| {
ud.borrow_mut::<Self>()?.inner.alignment = Some(align.0); 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 yazi_proxy::{AppProxy, HIDER};
use super::{Line, Rect, Span}; use super::{Line, Rect, Span};
use crate::bindings::{Permit, PermitRef}; use crate::{Permit, PermitRef};
pub(super) struct Utils; pub(super) struct Utils;

View file

@ -1,9 +1,8 @@
use std::ops::Deref; use std::ops::Deref;
use mlua::{ExternalError, FromLua, Lua, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; 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>; pub type FileRef = UserDataRef<File>;

View file

@ -1,3 +1,7 @@
#![allow(clippy::unit_arg)]
mod macros; 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_export]
macro_rules! cached_field { macro_rules! cached_field {
($fields:ident, $key:ident, $value:expr) => { ($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_export]
macro_rules! impl_style_shorthands { macro_rules! impl_style_shorthands {
($methods:ident, $($field:tt).+) => { ($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-dds = { path = "../yazi-dds", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" } yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", 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-plugin = { path = "../yazi-plugin", version = "25.6.11" }
yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" } yazi-proxy = { path = "../yazi-proxy", version = "25.6.11" }
yazi-scheduler = { path = "../yazi-scheduler", 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 # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }
bitflags = { workspace = true }
crossterm = { workspace = true } crossterm = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
indexmap = { 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 } parking_lot = { workspace = true }
ratatui = { workspace = true } ratatui = { workspace = true }
scopeguard = { workspace = true } scopeguard = { workspace = true }

View file

@ -1,22 +1,12 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::cmp::ArrowOpt;
use yazi_widgets::{Scrollable, Step}; use yazi_widgets::Scrollable;
use crate::cmp::Cmp; 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 { impl Cmp {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) { pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step)); render!(self.scroll(opt.step));
} }
} }

View file

@ -1,25 +1,14 @@
use std::mem; use std::mem;
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::cmp::CloseOpt;
use yazi_proxy::InputProxy; use yazi_proxy::InputProxy;
use yazi_shared::event::CmdCow;
use crate::cmp::Cmp; 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 { impl Cmp {
#[yazi_codegen::command] #[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) { if let Some(s) = self.selected().filter(|_| opt.submit) {
InputProxy::complete(s, self.ticket); 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_macro::render;
use yazi_parser::cmp::ShowOpt;
use yazi_proxy::options::CmpItem; 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; use crate::cmp::Cmp;
const LIMIT: usize = 30; 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 { impl Cmp {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn show(&mut self, opt: Opt) { pub fn show(&mut self, opt: ShowOpt) {
if self.ticket != opt.ticket { if self.ticket != opt.ticket {
return; 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 tokio::fs;
use yazi_fs::{CWD, expand_path}; use yazi_fs::{CWD, expand_path};
use yazi_macro::{emit, render}; use yazi_macro::{emit, render};
use yazi_parser::cmp::TriggerOpt;
use yazi_proxy::options::CmpItem; use yazi_proxy::options::CmpItem;
use yazi_shared::{Id, event::{Cmd, CmdCow, Data}, natsort}; use yazi_shared::{event::Cmd, natsort};
use crate::cmp::Cmp; 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 { impl Cmp {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn trigger(&mut self, opt: Opt) { pub fn trigger(&mut self, opt: TriggerOpt) {
if opt.ticket < self.ticket { if opt.ticket < self.ticket {
return; return;
} }

View file

@ -1,22 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::confirm::ArrowOpt;
use yazi_widgets::Step;
use crate::{confirm::Confirm, mgr::Mgr}; 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 { impl Confirm {
#[yazi_codegen::command] #[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 area = mgr.area(self.position);
let len = self.list.line_count(area.width); let len = self.list.line_count(area.width);

View file

@ -1,22 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::confirm::CloseOpt;
use crate::confirm::Confirm; 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 { impl Confirm {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) { pub fn close(&mut self, opt: CloseOpt) {
if let Some(cb) = self.callback.take() { if let Some(cb) = self.callback.take() {
_ = cb.send(opt.submit); _ = 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_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::confirm::ShowOpt;
use crate::confirm::Confirm; 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 { impl Confirm {
pub fn show(&mut self, opt: impl TryInto<Opt>) { pub fn show(&mut self, opt: impl TryInto<ShowOpt>) {
let Ok(opt): Result<Opt, _> = opt.try_into() else { let Ok(opt): Result<ShowOpt, _> = opt.try_into() else {
return; return;
}; };

View file

@ -1,27 +1,13 @@
use yazi_adapter::Dimension; use yazi_adapter::Dimension;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::help::ArrowOpt;
use yazi_widgets::{Scrollable, Step}; use yazi_widgets::Scrollable;
use crate::help::{HELP_MARGIN, Help}; 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 { impl Help {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) { pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step)); render!(self.scroll(opt.step));
} }
} }

View file

@ -1,23 +1,13 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::input::CloseOpt;
use yazi_proxy::CmpProxy; use yazi_proxy::CmpProxy;
use yazi_shared::{errors::InputError, event::CmdCow}; use yazi_shared::errors::InputError;
use crate::input::Input; 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 { impl Input {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) { pub fn close(&mut self, opt: CloseOpt) {
self.visible = false; self.visible = false;
self.ticket.next(); self.ticket.next();

View file

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

View file

@ -1,27 +1,14 @@
use tokio::sync::mpsc; use yazi_config::YAZI;
use yazi_config::{YAZI, popup::InputCfg};
use yazi_macro::render; 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 yazi_widgets::input::InputCallback;
use crate::input::Input; 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 { impl Input {
pub fn show(&mut self, opt: impl TryInto<Opt>) { pub fn show(&mut self, opt: impl TryInto<ShowOpt>) {
let Ok(opt): Result<Opt, _> = opt.try_into() else { return }; let Ok(opt): Result<ShowOpt, _> = opt.try_into() else { return };
self.close(false); self.close(false);
self.visible = true; 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}; use crate::{mgr::Mgr, tasks::Tasks};
#[derive(Default)]
struct Opt(quit::Opt);
impl From<CmdCow> for Opt {
fn from(c: CmdCow) -> Self { Self(c.into()) }
}
impl Mgr { impl Mgr {
#[yazi_codegen::command] #[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 { if self.tabs.len() > 1 {
return self.tabs.close(self.tabs.cursor); return self.tabs.close(self.tabs.cursor);
} }

View file

@ -2,23 +2,15 @@ use anyhow::Result;
use tokio::fs; use tokio::fs;
use yazi_config::popup::{ConfirmCfg, InputCfg}; use yazi_config::popup::{ConfirmCfg, InputCfg};
use yazi_fs::{File, FilesOp, maybe_exists, ok_or_not_found, realname}; 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_proxy::{ConfirmProxy, InputProxy, TabProxy, WATCHER};
use yazi_shared::{event::CmdCow, url::{Url, UrnBuf}}; use yazi_shared::url::{Url, UrnBuf};
use crate::mgr::Mgr; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn create(&self, opt: Opt) { pub fn create(&self, opt: CreateOpt) {
let cwd = self.cwd().to_owned(); let cwd = self.cwd().to_owned();
let mut input = InputProxy::show(InputCfg::create(opt.dir)); 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}; 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 { impl Mgr {
#[yazi_codegen::command] #[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 { if self.yanked.cut {
return; return;
} }

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow; use yazi_parser::mgr::LinkOpt;
use crate::{mgr::Mgr, tasks::Tasks}; 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 { impl Mgr {
#[yazi_codegen::command] #[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 { if self.yanked.cut {
return; return;
} }

View file

@ -3,27 +3,16 @@ use std::{borrow::Cow, iter};
use tracing::error; use tracing::error;
use yazi_config::{YAZI, popup::PickCfg}; use yazi_config::{YAZI, popup::PickCfg};
use yazi_fs::File; use yazi_fs::File;
use yazi_parser::mgr::OpenOpt;
use yazi_plugin::isolate; use yazi_plugin::isolate;
use yazi_proxy::{MgrProxy, PickProxy, TasksProxy, options::OpenDoOpt}; use yazi_proxy::{MgrProxy, PickProxy, TasksProxy, options::OpenDoOpt};
use yazi_shared::{MIME_DIR, event::CmdCow, url::Url}; use yazi_shared::{MIME_DIR, event::CmdCow, url::Url};
use crate::{mgr::Mgr, tab::Folder, tasks::Tasks}; 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 { impl Mgr {
#[yazi_codegen::command] #[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() { if !self.active_mut().try_escape_visual() {
return; return;
} }

View file

@ -1,19 +1,10 @@
use yazi_shared::event::CmdCow; use yazi_parser::mgr::PasteOpt;
use crate::{mgr::Mgr, tasks::Tasks}; 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 { impl Mgr {
#[yazi_codegen::command] #[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()); let (src, dest) = (self.yanked.iter().collect::<Vec<_>>(), self.cwd());
if self.yanked.cut { if self.yanked.cut {

View file

@ -1,33 +1,11 @@
use yazi_parser::mgr::PeekOpt;
use yazi_proxy::HIDER; use yazi_proxy::HIDER;
use yazi_shared::{event::{CmdCow, Data}, url::Url};
use crate::mgr::Mgr; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn peek(&mut self, opt: Opt) { pub fn peek(&mut self, opt: PeekOpt) {
let Some(hovered) = self.hovered().cloned() else { let Some(hovered) = self.hovered().cloned() else {
return self.active_mut().preview.reset(); return self.active_mut().preview.reset();
}; };

View file

@ -4,35 +4,15 @@ use tokio::{select, time};
use yazi_boot::ARGS; use yazi_boot::ARGS;
use yazi_config::popup::ConfirmCfg; use yazi_config::popup::ConfirmCfg;
use yazi_macro::emit; use yazi_macro::emit;
use yazi_parser::mgr::{OpenOpt, QuitOpt};
use yazi_proxy::ConfirmProxy; 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}; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn quit(&self, opt: Opt, tasks: &Tasks) { pub fn quit(&self, opt: QuitOpt, tasks: &Tasks) {
let event = opt.into(); let event = opt.into();
let ongoing = tasks.ongoing().clone(); 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 where
I: Iterator<Item = &'a Url>, I: Iterator<Item = &'a Url>,
{ {

View file

@ -1,30 +1,12 @@
use yazi_config::popup::ConfirmCfg; use yazi_config::popup::ConfirmCfg;
use yazi_parser::mgr::RemoveOpt;
use yazi_proxy::{ConfirmProxy, MgrProxy}; use yazi_proxy::{ConfirmProxy, MgrProxy};
use yazi_shared::{event::CmdCow, url::Url};
use crate::{mgr::Mgr, tasks::Tasks}; 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 { impl Mgr {
#[yazi_codegen::command] #[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() { if !self.active_mut().try_escape_visual() {
return; return;
} }
@ -55,7 +37,7 @@ impl Mgr {
} }
#[yazi_codegen::command] #[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| { self.tabs.iter_mut().for_each(|t| {
t.selected.remove_many(&opt.targets); t.selected.remove_many(&opt.targets);
}); });

View file

@ -1,37 +1,18 @@
use std::borrow::Cow;
use anyhow::Result; use anyhow::Result;
use tokio::fs; use tokio::fs;
use yazi_config::popup::{ConfirmCfg, InputCfg}; use yazi_config::popup::{ConfirmCfg, InputCfg};
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::{File, FilesOp, maybe_exists, ok_or_not_found, paths_to_same_file, realname}; use yazi_fs::{File, FilesOp, maybe_exists, ok_or_not_found, paths_to_same_file, realname};
use yazi_macro::err; use yazi_macro::err;
use yazi_parser::mgr::RenameOpt;
use yazi_proxy::{ConfirmProxy, InputProxy, TabProxy, WATCHER}; 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; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn rename(&mut self, opt: Opt) { pub fn rename(&mut self, opt: RenameOpt) {
if !self.active_mut().try_escape_visual() { if !self.active_mut().try_escape_visual() {
return; return;
} else if !opt.hovered && !self.active().selected.is_empty() { } else if !opt.hovered && !self.active().selected.is_empty() {

View file

@ -1,21 +1,12 @@
use yazi_config::YAZI; use yazi_config::YAZI;
use yazi_parser::mgr::SeekOpt;
use yazi_plugin::isolate; use yazi_plugin::isolate;
use yazi_shared::event::{CmdCow, Data};
use crate::mgr::Mgr; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn seek(&mut self, opt: Opt) { pub fn seek(&mut self, opt: SeekOpt) {
let Some(hovered) = self.hovered() else { let Some(hovered) = self.hovered() else {
return self.active_mut().preview.reset(); 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; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn spot(&mut self, opt: Opt) { pub fn spot(&mut self, opt: SpotOpt) {
let Some(hovered) = self.hovered().cloned() else { let Some(hovered) = self.hovered().cloned() else {
return; return;
}; };

View file

@ -1,23 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data}; use yazi_parser::mgr::TabCloseOpt;
use crate::mgr::Tabs; 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 { impl Tabs {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) { pub fn close(&mut self, opt: TabCloseOpt) {
let len = self.items.len(); let len = self.items.len();
if len < 2 || opt.idx >= len { if len < 2 || opt.idx >= len {
return; return;

View file

@ -1,35 +1,14 @@
use yazi_boot::BOOT;
use yazi_fs::expand_path;
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::{mgr::TabCreateOpt, tab::CdSource};
use yazi_proxy::AppProxy; 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; 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 { impl Tabs {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn create(&mut self, opt: Opt) { pub fn create(&mut self, opt: TabCreateOpt) {
if self.items.len() >= MAX_TABS { if self.items.len() >= MAX_TABS {
AppProxy::notify_warn("Too many tabs", "You can only open up to 9 tabs at the same time."); AppProxy::notify_warn("Too many tabs", "You can only open up to 9 tabs at the same time.");
return; return;

View file

@ -1,19 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data}; use yazi_parser::mgr::TabSwapOpt;
use crate::mgr::Tabs; 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 { impl Tabs {
#[yazi_codegen::command] #[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 _; let idx = opt.step.saturating_add_unsigned(self.cursor).rem_euclid(self.items.len() as _) as _;
if idx == self.cursor { if idx == self.cursor {
return; return;

View file

@ -1,22 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data}; use yazi_parser::mgr::TabSwitchOpt;
use crate::mgr::Tabs; 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 { impl Tabs {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn switch(&mut self, opt: Opt) { pub fn switch(&mut self, opt: TabSwitchOpt) {
let idx = if opt.relative { let idx = if opt.relative {
opt.step.saturating_add_unsigned(self.cursor).rem_euclid(self.items.len() as _) as _ opt.step.saturating_add_unsigned(self.cursor).rem_euclid(self.items.len() as _) as _
} else { } else {

View file

@ -1,20 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::mgr::UnyankOpt;
use crate::mgr::Mgr; 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 { impl Mgr {
#[yazi_codegen::command] #[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)); let repeek = self.hovered().is_some_and(|f| f.is_dir() && self.yanked.contains_in(&f.url));
self.yanked.clear(); self.yanked.clear();

View file

@ -1,23 +1,11 @@
use yazi_fs::FilesOp; use yazi_fs::FilesOp;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::mgr::UpdateFilesOpt;
use crate::{mgr::{LINKED, Mgr}, tab::Folder, tasks::Tasks}; 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 { 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 { let Ok(opt) = opt.try_into() else {
return; return;
}; };

View file

@ -2,25 +2,13 @@ use std::collections::HashMap;
use tracing::error; use tracing::error;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::{CmdCow, Data, DataKey}; use yazi_parser::mgr::UpdateMimesOpt;
use crate::{mgr::{LINKED, Mgr}, tasks::Tasks}; 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 { impl Mgr {
pub fn update_mimes(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) { pub fn update_mimes(&mut self, opt: impl TryInto<UpdateMimesOpt>, tasks: &Tasks) {
let Ok(opt): Result<Opt, _> = opt.try_into() else { let Ok(opt): Result<UpdateMimesOpt, _> = opt.try_into() else {
return error!("invalid arguments for update_mimes"); 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}; 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 { impl Mgr {
pub fn update_paged(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) { pub fn update_paged(&mut self, opt: impl TryInto<UpdatePagedOpt>, tasks: &Tasks) {
let Ok(opt): Result<Opt, _> = opt.try_into() else { let Ok(opt): Result<UpdatePagedOpt, _> = opt.try_into() else {
return; return;
}; };

View file

@ -1,21 +1,9 @@
use yazi_shared::{event::CmdCow, url::Url}; use yazi_parser::mgr::UpdateTasksOpt;
use crate::mgr::Mgr; 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 { 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 { let Ok(opt) = opt.try_into() else {
return; return;
}; };

View file

@ -1,30 +1,10 @@
use std::collections::HashSet;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::{event::CmdCow, url::Url}; use yazi_parser::mgr::UpdateYankedOpt;
use crate::mgr::{Mgr, Yanked}; 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 { 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 }; let Ok(opt) = opt.try_into() else { return };
if opt.urls.is_empty() && self.yanked.is_empty() { if opt.urls.is_empty() && self.yanked.is_empty() {

View file

@ -1,21 +1,12 @@
use std::collections::HashSet; use std::collections::HashSet;
use yazi_shared::event::CmdCow; use yazi_parser::mgr::WatchOpt;
use crate::mgr::Mgr; 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 { impl Mgr {
#[yazi_codegen::command] #[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()); let mut to_watch = HashSet::with_capacity(3 * self.tabs.len());
for tab in self.tabs.iter() { for tab in self.tabs.iter() {
to_watch.insert(tab.cwd()); to_watch.insert(tab.cwd());

View file

@ -1,19 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::mgr::YankOpt;
use crate::mgr::{Mgr, Yanked}; 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 { impl Mgr {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn yank(&mut self, opt: Opt) { pub fn yank(&mut self, opt: YankOpt) {
if !self.active_mut().try_escape_visual() { if !self.active_mut().try_escape_visual() {
return; return;
} }

View file

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

View file

@ -1,36 +1,13 @@
use std::time::Duration; use std::time::Duration;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use yazi_parser::notify::TickOpt;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::event::{Cmd, CmdCow, Data};
use crate::notify::Notify; 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 { 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()); self.tick_handle.take().map(|h| h.abort());
let Ok(opt) = opt.try_into() else { let Ok(opt) = opt.try_into() else {
return; return;

View file

@ -1,23 +1,13 @@
use yazi_config::YAZI; use yazi_config::YAZI;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::pick::ArrowOpt;
use yazi_widgets::{Scrollable, Step}; use yazi_widgets::Scrollable;
use crate::pick::Pick; 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 { impl Pick {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) { pub fn arrow(&mut self, opt: ArrowOpt) {
render!(self.scroll(opt.step)); render!(self.scroll(opt.step));
} }
} }

View file

@ -1,23 +1,12 @@
use anyhow::anyhow; use anyhow::anyhow;
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::pick::CloseOpt;
use crate::pick::Pick; 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 { impl Pick {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) { pub fn close(&mut self, opt: CloseOpt) {
if let Some(cb) = self.callback.take() { if let Some(cb) = self.callback.take() {
_ = cb.send(if opt.submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) }); _ = 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_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::pick::ShowOpt;
use crate::pick::Pick; 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 { 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 { let Ok(opt) = opt.try_into() else {
return; return;
}; };

View file

@ -1,23 +1,12 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::spot::ArrowOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use crate::spot::Spot; 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 { impl Spot {
#[yazi_codegen::command] #[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 Some(lock) = &mut self.lock else { return };
let new = opt.step.add(self.skip, lock.len().unwrap_or(u16::MAX as _), 0); 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; 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 { impl Spot {
#[yazi_codegen::command] #[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_parser::spot::CopyOpt;
use yazi_widgets::CLIPBOARD;
use yazi_plugin::CLIPBOARD;
use yazi_shared::event::CmdCow;
use crate::spot::Spot; 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 { impl Spot {
#[yazi_codegen::command] #[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(lock) = &self.lock else { return };
let Some(table) = lock.table() 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_proxy::{MgrProxy, TabProxy};
use yazi_shared::event::CmdCow;
use crate::spot::Spot; 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 { impl Spot {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn swipe(&mut self, opt: Opt) { pub fn swipe(&mut self, opt: SwipeOpt) {
TabProxy::arrow(opt.step); TabProxy::arrow(opt.step);
MgrProxy::spot(None); MgrProxy::spot(None);
} }

View file

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

View file

@ -1,27 +1,12 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::tab::ArrowOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::event::CmdCow;
use yazi_widgets::Step;
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) { pub fn arrow(&mut self, opt: ArrowOpt) {
if !self.current.arrow(opt.step) { if !self.current.arrow(opt.step) {
return; return;
} }

View file

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

View file

@ -6,34 +6,15 @@ use yazi_config::popup::InputCfg;
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_fs::{File, FilesOp, expand_path}; use yazi_fs::{File, FilesOp, expand_path};
use yazi_macro::{err, render}; use yazi_macro::{err, render};
use yazi_parser::tab::CdOpt;
use yazi_proxy::{CmpProxy, InputProxy, MgrProxy, TabProxy}; 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; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn cd(&mut self, opt: Opt) { pub fn cd(&mut self, opt: CdOpt) {
if !self.try_escape_visual() { if !self.try_escape_visual() {
return; 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_parser::tab::CopyOpt;
use yazi_shared::event::CmdCow; use yazi_widgets::CLIPBOARD;
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn copy(&mut self, opt: Opt) { pub fn copy(&mut self, opt: CopyOpt) {
if !self.try_escape_visual() { if !self.try_escape_visual() {
return; return;
} }
@ -57,32 +41,3 @@ 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_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 yazi_shared::event::CmdCow;
use super::cd::CdSource;
use crate::tab::Tab; use crate::tab::Tab;
impl Tab { impl Tab {

View file

@ -1,39 +1,12 @@
use bitflags::bitflags;
use yazi_macro::{render, render_and}; use yazi_macro::{render, render_and};
use yazi_parser::tab::{EscapeOpt, FilterOpt};
use yazi_proxy::{AppProxy, MgrProxy}; use yazi_proxy::{AppProxy, MgrProxy};
use yazi_shared::event::CmdCow;
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn escape(&mut self, opt: Opt) { pub fn escape(&mut self, opt: EscapeOpt) {
if opt.is_empty() { if opt.is_empty() {
_ = self.escape_find() _ = self.escape_find()
|| self.escape_visual() || self.escape_visual()
@ -43,19 +16,19 @@ impl Tab {
return; return;
} }
if opt.contains(Opt::FIND) { if opt.contains(EscapeOpt::FIND) {
self.escape_find(); self.escape_find();
} }
if opt.contains(Opt::VISUAL) { if opt.contains(EscapeOpt::VISUAL) {
self.escape_visual(); self.escape_visual();
} }
if opt.contains(Opt::FILTER) { if opt.contains(EscapeOpt::FILTER) {
self.escape_filter(); self.escape_filter();
} }
if opt.contains(Opt::SELECT) { if opt.contains(EscapeOpt::SELECT) {
self.escape_select(); self.escape_select();
} }
if opt.contains(Opt::SEARCH) { if opt.contains(EscapeOpt::SEARCH) {
self.escape_search(); self.escape_search();
} }
} }
@ -76,7 +49,7 @@ impl Tab {
return false; return false;
} }
self.filter_do(super::filter::Opt::default()); self.filter_do(FilterOpt::default());
render_and!(true) render_and!(true)
} }

View file

@ -1,35 +1,19 @@
use std::{borrow::Cow, time::Duration}; use std::time::Duration;
use tokio::pin; use tokio::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_fs::FilterCase; use yazi_fs::FilterCase;
use yazi_macro::emit; use yazi_macro::emit;
use yazi_parser::tab::FilterOpt;
use yazi_proxy::InputProxy; 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; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn filter(&mut self, opt: Opt) { pub fn filter(&mut self, opt: FilterOpt) {
let input = InputProxy::show(InputCfg::filter()); let input = InputProxy::show(InputCfg::filter());
tokio::spawn(async move { tokio::spawn(async move {

View file

@ -1,13 +1,13 @@
use yazi_fs::Filter; use yazi_fs::Filter;
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::tab::FilterOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use super::filter::Opt;
use crate::tab::Tab; use crate::tab::Tab;
impl Tab { impl Tab {
#[yazi_codegen::command] #[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() { let filter = if opt.query.is_empty() {
None None
} else if let Ok(f) = Filter::new(&opt.query, opt.case) { } 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::pin;
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_fs::FilterCase; use yazi_fs::FilterCase;
use yazi_macro::emit; use yazi_macro::emit;
use yazi_parser::tab::FindOpt;
use yazi_proxy::InputProxy; 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; 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 { impl Tab {
#[yazi_codegen::command] #[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)); let input = InputProxy::show(InputCfg::find(opt.prev));
tokio::spawn(async move { tokio::spawn(async move {

View file

@ -1,19 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_shared::event::CmdCow; use yazi_parser::tab::FindArrowOpt;
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[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 { let Some(finder) = &mut self.finder else {
return; return;
}; };

View file

@ -1,11 +1,11 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::tab::FindOpt;
use super::find::Opt;
use crate::tab::{Finder, Tab}; use crate::tab::{Finder, Tab};
impl Tab { impl Tab {
#[yazi_codegen::command] #[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 { let Some(query) = opt.query else {
return; return;
}; };

View file

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

View file

@ -1,23 +1,13 @@
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_macro::{err, render}; 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; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn hover(&mut self, opt: Opt) { pub fn hover(&mut self, opt: HoverOpt) {
if let Some(u) = opt.url { if let Some(u) = opt.url {
self.hover_do(u); self.hover_do(u);
} else { } 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; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn leave(&mut self, _: Opt) { pub fn leave(&mut self, _: LeaveOpt) {
self self
.current .current
.hovered() .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_proxy::MgrProxy;
use yazi_shared::{event::CmdCow, url::Url};
use super::cd::CdSource;
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[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 { let Some((parent, child)) = opt.target.pair() else {
return; return;
}; };

View file

@ -1,54 +1,19 @@
use std::{borrow::Cow, fmt::Display}; use std::{borrow::Cow, fmt::Display};
use anyhow::bail;
use yazi_config::{opener::OpenerRule, popup::InputCfg}; use yazi_config::{opener::OpenerRule, popup::InputCfg};
use yazi_parser::tab::ShellOpt;
use yazi_proxy::{AppProxy, InputProxy, TasksProxy}; use yazi_proxy::{AppProxy, InputProxy, TasksProxy};
use yazi_shared::{event::{CmdCow, Data}, url::Url};
use crate::tab::Tab; 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 { 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() { if !self.try_escape_visual() {
return; return;
} }
let mut opt = match opt.try_into() { 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), Err(e) => return AppProxy::notify_warn("`shell` command", e),
}; };

View file

@ -1,30 +1,12 @@
use yazi_macro::render_and; use yazi_macro::render_and;
use yazi_parser::tab::ToggleOpt;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::{event::CmdCow, url::Url};
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[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 { let Some(url) = opt.url.as_ref().or(self.current.hovered().map(|h| &h.url)) else {
return; return;
}; };

View file

@ -1,42 +1,12 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_parser::tab::ToggleAllOpt;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::{event::CmdCow, url::Url};
use crate::tab::Tab; 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 { impl Tab {
#[yazi_codegen::command] #[yazi_codegen::command]
pub fn toggle_all(&mut self, opt: Opt) { pub fn toggle_all(&mut self, opt: ToggleAllOpt) {
use yazi_shared::Either::*; use yazi_shared::Either::*;
let it = self.current.files.iter().map(|f| &f.url); let it = self.current.files.iter().map(|f| &f.url);

View file

@ -1,28 +1,15 @@
use yazi_macro::render; use yazi_macro::render;
use yazi_plugin::utils::PreviewLock; use yazi_parser::tab::UpdatePeekedOpt;
use yazi_shared::event::CmdCow;
use crate::tab::Tab; 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 { 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 { let Some(hovered) = self.hovered().map(|h| &h.url) else {
return self.preview.reset(); return self.preview.reset();
}; };
let Ok(opt) = opt.try_into() else { let Ok(opt): Result<UpdatePeekedOpt, _> = opt.try_into() else {
return; return;
}; };

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