mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf!: cacheable iterator (#2997)
This commit is contained in:
parent
5f8a1496fe
commit
0fd74ae44c
51 changed files with 414 additions and 303 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -3670,6 +3670,7 @@ dependencies = [
|
|||
"yazi-boot",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-parser",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3772,7 +3773,6 @@ dependencies = [
|
|||
"yazi-binding",
|
||||
"yazi-boot",
|
||||
"yazi-config",
|
||||
"yazi-dds",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-shared",
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::{ffi::OsString, mem, path::{MAIN_SEPARATOR_STR, Path, PathBuf}};
|
|||
use anyhow::Result;
|
||||
use tokio::fs;
|
||||
use yazi_fs::{CWD, expand_path};
|
||||
use yazi_macro::{act, emit, render, succ};
|
||||
use yazi_macro::{act, render, succ};
|
||||
use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt};
|
||||
use yazi_shared::{event::{Cmd, Data}, natsort};
|
||||
use yazi_proxy::CmpProxy;
|
||||
use yazi_shared::{event::Data, natsort};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
||||
|
|
@ -55,13 +56,7 @@ impl Actor for Trigger {
|
|||
cache.sort_unstable_by(|a, b| {
|
||||
natsort(a.name.as_encoded_bytes(), b.name.as_encoded_bytes(), false)
|
||||
});
|
||||
emit!(Call(
|
||||
Cmd::new("cmp:show")
|
||||
.with_any("cache", cache)
|
||||
.with_any("cache-name", parent)
|
||||
.with("word", word)
|
||||
.with("ticket", ticket)
|
||||
));
|
||||
CmpProxy::show(ShowOpt { cache, cache_name: parent, word: word.into(), ticket });
|
||||
}
|
||||
|
||||
Ok::<_, anyhow::Error>(())
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ use anyhow::Result;
|
|||
use tokio::pin;
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_macro::{emit, succ};
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::tab::FilterOpt;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, Data}};
|
||||
use yazi_proxy::{InputProxy, MgrProxy};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::Data};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
||||
|
|
@ -30,12 +29,7 @@ impl Actor for Filter {
|
|||
let done = result.is_ok();
|
||||
let (Ok(s) | Err(InputError::Typed(s))) = result else { continue };
|
||||
|
||||
emit!(Call(
|
||||
Cmd::args("mgr:filter_do", [s])
|
||||
.with("smart", opt.case == FilterCase::Smart)
|
||||
.with("insensitive", opt.case == FilterCase::Insensitive)
|
||||
.with("done", done)
|
||||
));
|
||||
MgrProxy::filter_do(FilterOpt { query: s.into(), case: opt.case, done });
|
||||
}
|
||||
});
|
||||
succ!();
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ use anyhow::Result;
|
|||
use tokio::pin;
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_macro::{emit, succ};
|
||||
use yazi_parser::tab::FindOpt;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, Data}};
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::tab::{FindDoOpt, FindOpt};
|
||||
use yazi_proxy::{InputProxy, MgrProxy};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::Data};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
||||
|
|
@ -27,12 +26,7 @@ impl Actor for Find {
|
|||
pin!(rx);
|
||||
|
||||
while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await {
|
||||
emit!(Call(
|
||||
Cmd::args("mgr:find_do", [s])
|
||||
.with("previous", opt.prev)
|
||||
.with("smart", opt.case == FilterCase::Smart)
|
||||
.with("insensitive", opt.case == FilterCase::Insensitive)
|
||||
));
|
||||
MgrProxy::find_do(FindDoOpt { query: s.into(), prev: opt.prev, case: opt.case });
|
||||
}
|
||||
});
|
||||
succ!();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use crate::{Actor, Ctx};
|
|||
pub struct UpdateYanked;
|
||||
|
||||
impl Actor for UpdateYanked {
|
||||
type Options = UpdateYankedOpt;
|
||||
type Options = UpdateYankedOpt<'static>;
|
||||
|
||||
const NAME: &'static str = "update_yanked";
|
||||
|
||||
|
|
@ -18,7 +18,7 @@ impl Actor for UpdateYanked {
|
|||
succ!();
|
||||
}
|
||||
|
||||
cx.mgr.yanked = Yanked::new(opt.cut, opt.urls);
|
||||
cx.mgr.yanked = Yanked::new(opt.cut, opt.urls.into_owned());
|
||||
succ!(render!());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
68
yazi-binding/src/iter.rs
Normal file
68
yazi-binding/src/iter.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, IntoLuaMulti, Lua, MetaMethod, UserData, UserDataMethods, UserDataRefMut, Value};
|
||||
|
||||
pub struct Iter<I: Iterator<Item = T>, T> {
|
||||
iter: I,
|
||||
len: Option<usize>,
|
||||
|
||||
count: usize,
|
||||
cache: Vec<Value>,
|
||||
}
|
||||
|
||||
impl<I, T> Iter<I, T>
|
||||
where
|
||||
I: Iterator<Item = T> + 'static,
|
||||
T: IntoLua + 'static,
|
||||
{
|
||||
#[inline]
|
||||
pub fn new(iter: I, len: Option<usize>) -> Self { Self { iter, len, count: 0, cache: vec![] } }
|
||||
}
|
||||
|
||||
impl<I, T> Iter<I, T>
|
||||
where
|
||||
I: Iterator<Item = T> + 'static,
|
||||
T: FromLua + 'static,
|
||||
{
|
||||
#[inline]
|
||||
pub fn into_iter(self, lua: &Lua) -> impl Iterator<Item = mlua::Result<T>> {
|
||||
self
|
||||
.cache
|
||||
.into_iter()
|
||||
.map(|cached| T::from_lua(cached, lua))
|
||||
.chain(self.iter.map(|rest| Ok(rest)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T> UserData for Iter<I, T>
|
||||
where
|
||||
I: Iterator<Item = T> + 'static,
|
||||
T: IntoLua + 'static,
|
||||
{
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| {
|
||||
if let Some(len) = me.len {
|
||||
Ok(len)
|
||||
} else {
|
||||
Err(format!("Length is unknown for {}", std::any::type_name::<Self>()).into_lua_err())
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_meta_function(MetaMethod::Pairs, |lua, ud: AnyUserData| {
|
||||
let iter = lua.create_function(|lua, mut me: UserDataRefMut<Self>| {
|
||||
if let Some(next) = me.cache.get(me.count).cloned() {
|
||||
me.count += 1;
|
||||
(me.count, next).into_lua_multi(lua)
|
||||
} else if let Some(next) = me.iter.next() {
|
||||
let value = next.into_lua(lua)?;
|
||||
me.cache.push(value.clone());
|
||||
me.count += 1;
|
||||
(me.count, value).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
})?;
|
||||
|
||||
ud.borrow_mut::<Self>()?.count = 0;
|
||||
Ok((iter, ud))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -4,4 +4,4 @@ mod macros;
|
|||
|
||||
yazi_macro::mod_pub!(elements);
|
||||
|
||||
yazi_macro::mod_flat!(cha color composer error file icon id permit runtime stage style url urn);
|
||||
yazi_macro::mod_flat!(cha color composer error file icon id iter permit runtime stage style url urn utils);
|
||||
|
|
|
|||
10
yazi-binding/src/utils.rs
Normal file
10
yazi-binding/src/utils.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use mlua::{IntoLua, Lua, Table, Value};
|
||||
|
||||
pub fn get_metatable(lua: &Lua, value: impl IntoLua) -> mlua::Result<Table> {
|
||||
let (_, mt): (Value, Table) = unsafe {
|
||||
lua.exec_raw(value.into_lua(lua)?, |state| {
|
||||
mlua::ffi::lua_getmetatable(state, -1);
|
||||
})
|
||||
}?;
|
||||
Ok(mt)
|
||||
}
|
||||
|
|
@ -3,10 +3,9 @@ use std::{sync::Arc, time::Duration};
|
|||
use parking_lot::Mutex;
|
||||
use tokio::{task::JoinHandle, time::sleep};
|
||||
use yazi_adapter::Dimension;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::app::TasksProgress;
|
||||
use yazi_proxy::AppProxy;
|
||||
use yazi_scheduler::{Ongoing, Scheduler, TaskSummary};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use super::{TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT};
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ impl Tasks {
|
|||
let new = ongoing.lock().progress();
|
||||
if last != new {
|
||||
last = new;
|
||||
emit!(Call(Cmd::new("app:update_progress").with_any("progress", new)));
|
||||
AppProxy::update_progress(new);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
|||
yazi-boot = { path = "../yazi-boot", 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-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
|
||||
# External dependencies
|
||||
|
|
|
|||
7
yazi-dds/src/body/before_quit.rs
Normal file
7
yazi-dds/src/body/before_quit.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use yazi_shared::Source;
|
||||
|
||||
pub struct BeforeQuit {
|
||||
// FIXME
|
||||
// pub opts: BeforeQuitOpt,
|
||||
pub source: Source,
|
||||
}
|
||||
|
|
@ -47,9 +47,9 @@ impl Body<'static> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn from_lua(kind: &str, value: Value) -> mlua::Result<Self> {
|
||||
pub fn from_lua(lua: &Lua, kind: &str, value: Value) -> mlua::Result<Self> {
|
||||
Self::validate(kind).into_lua_err()?;
|
||||
BodyCustom::from_lua(kind, value)
|
||||
BodyCustom::from_lua(lua, kind, value)
|
||||
}
|
||||
|
||||
pub fn validate(kind: &str) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ impl IntoLua for BodyBulk<'static> {
|
|||
}
|
||||
|
||||
// --- Iterator
|
||||
// TODO: use `yazi_binding::Iter` instead
|
||||
pub struct BodyBulkIter {
|
||||
pub inner: hash_map::IntoIter<Cow<'static, Url>, Cow<'static, Url>>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ impl BodyCustom {
|
|||
Ok(Self { kind: kind.to_owned(), data: serde_json::from_str(data)? }.into())
|
||||
}
|
||||
|
||||
pub fn from_lua(kind: &str, data: Value) -> mlua::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), data: Sendable::value_to_data(data)? }.into())
|
||||
pub fn from_lua(lua: &Lua, kind: &str, data: Value) -> mlua::Result<Body<'static>> {
|
||||
Ok(Self { kind: kind.to_owned(), data: Sendable::value_to_data(lua, data)? }.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(
|
||||
body bulk bye cd custom delete hey hi hover load mount r#move rename tab trash yank
|
||||
before_quit body bulk bye cd custom delete hey hi hover load mount r#move rename tab trash yank
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,28 +1,24 @@
|
|||
use std::{borrow::Cow, collections::HashSet};
|
||||
|
||||
use mlua::{IntoLua, Lua, MetaMethod, UserData, Value};
|
||||
use mlua::{IntoLua, Lua, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_parser::mgr::UpdateYankedOpt;
|
||||
use yazi_shared::url::Url;
|
||||
|
||||
use super::Body;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BodyYank<'a> {
|
||||
pub cut: bool,
|
||||
pub urls: Cow<'a, HashSet<Url>>,
|
||||
#[serde(skip)]
|
||||
dummy: bool,
|
||||
}
|
||||
pub struct BodyYank<'a>(UpdateYankedOpt<'a>);
|
||||
|
||||
impl<'a> BodyYank<'a> {
|
||||
pub fn borrowed(cut: bool, urls: &'a HashSet<Url>) -> Body<'a> {
|
||||
Self { cut, urls: Cow::Borrowed(urls), dummy: false }.into()
|
||||
Self(UpdateYankedOpt { cut, urls: Cow::Borrowed(urls) }).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BodyYank<'static> {
|
||||
pub fn owned(cut: bool, _: &HashSet<Url>) -> Body<'static> {
|
||||
Self { cut, urls: Default::default(), dummy: true }.into()
|
||||
Self(UpdateYankedOpt { cut, urls: Default::default() }).into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,36 +27,5 @@ impl<'a> From<BodyYank<'a>> for Body<'a> {
|
|||
}
|
||||
|
||||
impl IntoLua for BodyYank<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
if let Some(Cow::Owned(urls)) = Some(self.urls).filter(|_| !self.dummy) {
|
||||
BodyYankIter { cut: self.cut, urls: urls.into_iter().collect() }.into_lua(lua)
|
||||
} else {
|
||||
lua.create_table()?.into_lua(lua)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Iterator
|
||||
#[derive(Clone)]
|
||||
pub struct BodyYankIter {
|
||||
pub cut: bool,
|
||||
pub urls: Vec<Url>,
|
||||
}
|
||||
|
||||
impl UserData for BodyYankIter {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cut", |_, me| Ok(me.cut));
|
||||
}
|
||||
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.urls.len()));
|
||||
|
||||
methods.add_meta_method(MetaMethod::Index, |_, me, idx: usize| {
|
||||
Ok(if idx > me.urls.len() || idx == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(yazi_binding::Url::new(me.urls[idx - 1].clone()))
|
||||
})
|
||||
});
|
||||
}
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { self.0.into_lua(lua) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_shared::{event::{Data, DataKey}, replace_cow};
|
|||
pub struct Sendable;
|
||||
|
||||
impl Sendable {
|
||||
pub fn value_to_data(value: Value) -> mlua::Result<Data> {
|
||||
pub fn value_to_data(lua: &Lua, value: Value) -> mlua::Result<Data> {
|
||||
Ok(match value {
|
||||
Value::Nil => Data::Nil,
|
||||
Value::Boolean(b) => Data::Boolean(b),
|
||||
|
|
@ -30,7 +30,7 @@ impl Sendable {
|
|||
if k == DataKey::Integer(i) {
|
||||
i += 1;
|
||||
}
|
||||
map.insert(k, Self::value_to_data(v)?);
|
||||
map.insert(k, Self::value_to_data(lua, v)?);
|
||||
}
|
||||
|
||||
if map.len() == i as usize - 1 {
|
||||
|
|
@ -54,8 +54,8 @@ impl Sendable {
|
|||
Some(t) if t == TypeId::of::<yazi_fs::FilesOp>() => {
|
||||
Data::Any(Box::new(ud.take::<yazi_fs::FilesOp>()?))
|
||||
}
|
||||
Some(t) if t == TypeId::of::<super::body::BodyYankIter>() => {
|
||||
Data::Any(Box::new(ud.take::<super::body::BodyYankIter>()?))
|
||||
Some(t) if t == TypeId::of::<yazi_parser::mgr::UpdateYankedIter>() => {
|
||||
Data::Any(Box::new(ud.take::<yazi_parser::mgr::UpdateYankedIter>()?.into_opt(lua)?))
|
||||
}
|
||||
_ => Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?,
|
||||
},
|
||||
|
|
@ -83,13 +83,15 @@ impl Sendable {
|
|||
}
|
||||
Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?,
|
||||
Data::Urn(u) => yazi_binding::Urn::new(u).into_lua(lua)?,
|
||||
Data::Any(a) => Value::UserData(if a.is::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().unwrap())?
|
||||
} else if a.is::<super::body::BodyYankIter>() {
|
||||
lua.create_userdata(*a.downcast::<super::body::BodyYankIter>().unwrap())?
|
||||
} else {
|
||||
Err("unsupported Data::Any included".into_lua_err())?
|
||||
}),
|
||||
Data::Any(a) => {
|
||||
if a.is::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().unwrap())?.into_lua(lua)?
|
||||
} else if a.is::<yazi_parser::mgr::UpdateYankedOpt>() {
|
||||
a.downcast::<yazi_parser::mgr::UpdateYankedOpt>().unwrap().into_lua(lua)?
|
||||
} else {
|
||||
Err("unsupported Data::Any included".into_lua_err())?
|
||||
}
|
||||
}
|
||||
data => Self::data_to_value_ref(lua, &data)?,
|
||||
})
|
||||
}
|
||||
|
|
@ -120,28 +122,30 @@ impl Sendable {
|
|||
Data::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
||||
Data::Urn(u) => yazi_binding::Urn::new(u.clone()).into_lua(lua)?,
|
||||
Data::Bytes(b) => Value::String(lua.create_string(b)?),
|
||||
Data::Any(a) => Value::UserData(if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(t.clone())?
|
||||
} else if let Some(t) = a.downcast_ref::<super::body::BodyYankIter>() {
|
||||
lua.create_userdata(t.clone())?
|
||||
} else {
|
||||
Err("unsupported Data::Any included".into_lua_err())?
|
||||
}),
|
||||
Data::Any(a) => {
|
||||
if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(t.clone())?.into_lua(lua)?
|
||||
} else if let Some(t) = a.downcast_ref::<yazi_parser::mgr::UpdateYankedOpt>() {
|
||||
t.clone().into_lua(lua)?
|
||||
} else {
|
||||
Err("unsupported Data::Any included".into_lua_err())?
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn table_to_args(t: Table) -> mlua::Result<HashMap<DataKey, Data>> {
|
||||
pub fn table_to_args(lua: &Lua, t: Table) -> mlua::Result<HashMap<DataKey, Data>> {
|
||||
let mut args = HashMap::with_capacity(t.raw_len());
|
||||
for pair in t.pairs::<Value, Value>() {
|
||||
let (k, v) = pair?;
|
||||
match k {
|
||||
Value::Integer(i) if i > 0 => {
|
||||
args.insert(DataKey::Integer(i - 1), Self::value_to_data(v)?);
|
||||
args.insert(DataKey::Integer(i - 1), Self::value_to_data(lua, v)?);
|
||||
}
|
||||
Value::String(s) => {
|
||||
args.insert(
|
||||
DataKey::String(Cow::Owned(s.to_str()?.replace('_', "-"))),
|
||||
Self::value_to_data(v)?,
|
||||
Self::value_to_data(lua, v)?,
|
||||
);
|
||||
}
|
||||
_ => return Err("invalid key in Cmd".into_lua_err()),
|
||||
|
|
@ -182,8 +186,8 @@ impl Sendable {
|
|||
data.into_iter().map(|d| Self::data_to_value(lua, d)).collect()
|
||||
}
|
||||
|
||||
pub fn values_to_list(values: MultiValue) -> mlua::Result<Vec<Data>> {
|
||||
values.into_iter().map(Self::value_to_data).collect()
|
||||
pub fn values_to_list(lua: &Lua, values: MultiValue) -> mlua::Result<Vec<Data>> {
|
||||
values.into_iter().map(|v| Self::value_to_data(lua, v)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::{Result, bail};
|
||||
use mlua::IntoLua;
|
||||
use tracing::error;
|
||||
use yazi_binding::runtime_mut;
|
||||
use yazi_dds::{LOCAL, REMOTE};
|
||||
use yazi_dds::{LOCAL, Payload, REMOTE};
|
||||
use yazi_macro::succ;
|
||||
use yazi_parser::app::AcceptPayload;
|
||||
use yazi_plugin::LUA;
|
||||
use yazi_shared::event::Data;
|
||||
use yazi_shared::event::{CmdCow, Data};
|
||||
|
||||
use crate::{app::App, lives::Lives};
|
||||
|
||||
impl App {
|
||||
pub(crate) fn accept_payload(&mut self, opt: AcceptPayload) -> Result<Data> {
|
||||
let kind = opt.payload.body.kind().to_owned();
|
||||
let lock = if opt.payload.receiver == 0 || opt.payload.receiver != opt.payload.sender {
|
||||
pub(crate) fn accept_payload(&mut self, mut c: CmdCow) -> Result<Data> {
|
||||
let Some(payload) = c.take_any2::<Payload>("payload").transpose()? else {
|
||||
bail!("'payload' is required for accept_payload");
|
||||
};
|
||||
|
||||
let kind = payload.body.kind().to_owned();
|
||||
let lock = if payload.receiver == 0 || payload.receiver != payload.sender {
|
||||
REMOTE.read()
|
||||
} else {
|
||||
LOCAL.read()
|
||||
|
|
@ -23,7 +26,7 @@ impl App {
|
|||
drop(lock);
|
||||
|
||||
succ!(Lives::scope(&self.core, || {
|
||||
let body = opt.payload.body.into_lua(&LUA)?;
|
||||
let body = payload.body.into_lua(&LUA)?;
|
||||
for (id, cb) in handlers {
|
||||
runtime_mut!(LUA)?.push(&id);
|
||||
if let Err(e) = cb.call::<()>(body.clone()) {
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
use mlua::{AnyUserData, UserData};
|
||||
|
||||
use super::Lives;
|
||||
|
||||
pub(super) struct Iter<I: Iterator<Item = T>, T> {
|
||||
inner: I,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = T> + 'static, T: 'static> Iter<I, T> {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: I) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner, count: 0 })
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = T>, T> Iterator for Iter<I, T> {
|
||||
type Item = (usize, T);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let next = self.inner.next()?;
|
||||
self.count += 1;
|
||||
Some((self.count, next))
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = T>, T> UserData for Iter<I, T> {}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(core file files filter finder folder iter lives mode preference preview ptr selected tab tabs tasks yanked);
|
||||
yazi_macro::mod_flat!(core file files filter finder folder lives mode preference preview ptr selected tab tabs tasks yanked);
|
||||
|
|
|
|||
|
|
@ -1,45 +1,20 @@
|
|||
use std::ops::Deref;
|
||||
use indexmap::IndexMap;
|
||||
use mlua::AnyUserData;
|
||||
|
||||
use indexmap::{IndexMap, map::Keys};
|
||||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataMethods, UserDataRefMut};
|
||||
use yazi_binding::Url;
|
||||
|
||||
use super::{Iter, Lives, PtrCell};
|
||||
use super::Lives;
|
||||
use crate::lives::PtrCell;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct Selected {
|
||||
inner: PtrCell<IndexMap<yazi_shared::url::Url, u64>>,
|
||||
}
|
||||
|
||||
impl Deref for Selected {
|
||||
type Target = IndexMap<yazi_shared::url::Url, u64>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
pub(super) struct Selected;
|
||||
|
||||
impl Selected {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &IndexMap<yazi_shared::url::Url, u64>) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Selected {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len()));
|
||||
|
||||
methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
||||
let iter = lua.create_function(
|
||||
|lua, mut iter: UserDataRefMut<Iter<Keys<yazi_shared::url::Url, u64>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url::new(next.1.clone())).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok((iter, Iter::make(me.inner.as_static().keys())))
|
||||
});
|
||||
let inner = PtrCell::from(inner);
|
||||
|
||||
Lives::scoped_userdata(yazi_binding::Iter::new(
|
||||
inner.as_static().keys().cloned().map(yazi_binding::Url::new),
|
||||
Some(inner.len()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use std::{collections::hash_set, ops::Deref};
|
||||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRefMut};
|
||||
use yazi_binding::Url;
|
||||
use mlua::{AnyUserData, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods};
|
||||
use yazi_binding::{Iter, get_metatable};
|
||||
|
||||
use super::{Iter, Lives, PtrCell};
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Yanked {
|
||||
inner: PtrCell<yazi_core::mgr::Yanked>,
|
||||
iter: AnyUserData,
|
||||
}
|
||||
|
||||
impl Deref for Yanked {
|
||||
|
|
@ -18,7 +19,15 @@ impl Deref for Yanked {
|
|||
impl Yanked {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::mgr::Yanked) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
let inner = PtrCell::from(inner);
|
||||
|
||||
Lives::scoped_userdata(Self {
|
||||
inner,
|
||||
iter: Lives::scoped_userdata(Iter::new(
|
||||
inner.as_static().iter().cloned().map(yazi_binding::Url::new),
|
||||
Some(inner.len()),
|
||||
))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -30,18 +39,9 @@ impl UserData for Yanked {
|
|||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len()));
|
||||
|
||||
methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| {
|
||||
let iter = lua.create_function(
|
||||
|lua, mut iter: UserDataRefMut<Iter<hash_set::Iter<yazi_shared::url::Url>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url::new(next.1.clone())).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok((iter, Iter::make(me.inner.as_static().iter())))
|
||||
methods.add_meta_function(MetaMethod::Pairs, |lua, ud: AnyUserData| {
|
||||
let me = ud.borrow::<Self>()?;
|
||||
get_metatable(lua, &me.iter)?.call_function::<MultiValue>(MetaMethod::Pairs.name(), ud)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl Display for Filter {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&self.raw) }
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||
pub enum FilterCase {
|
||||
Smart,
|
||||
#[default]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
yazi-binding = { path = "../yazi-binding", version = "25.6.11" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.6.11" }
|
||||
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-shared = { path = "../yazi-shared", version = "25.6.11" }
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
use anyhow::bail;
|
||||
use yazi_dds::Payload;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
pub struct AcceptPayload {
|
||||
pub payload: Payload<'static>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for AcceptPayload {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
let Some(payload) = c.take_any("payload") else {
|
||||
bail!("Invalid 'payload' in AcceptPayload");
|
||||
};
|
||||
|
||||
Ok(Self { payload })
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(accept_payload deprecate mouse notify plugin stop update_progress);
|
||||
yazi_macro::mod_flat!(deprecate mouse notify plugin stop update_progress);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{ffi::OsString, path::{MAIN_SEPARATOR_STR, PathBuf}};
|
||||
|
||||
use yazi_shared::{Id, SStr, event::{Cmd, CmdCow}};
|
||||
use yazi_shared::{Id, SStr, event::CmdCow};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ShowOpt {
|
||||
|
|
@ -10,21 +10,23 @@ pub struct ShowOpt {
|
|||
pub ticket: Id,
|
||||
}
|
||||
|
||||
impl From<CmdCow> for ShowOpt {
|
||||
fn from(mut c: CmdCow) -> Self {
|
||||
Self {
|
||||
impl TryFrom<CmdCow> for ShowOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
Ok(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.id("ticket").unwrap_or_default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Cmd> for ShowOpt {
|
||||
fn from(c: Cmd) -> Self { Self::from(CmdCow::from(c)) }
|
||||
}
|
||||
|
||||
// --- Item
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CmpItem {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
use mlua::{IntoLua, Lua, LuaSerdeExt, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_shared::event::{CmdCow, Data, EventQuit};
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct QuitOpt {
|
||||
pub code: i32,
|
||||
pub no_cwd_file: bool,
|
||||
|
|
@ -20,3 +22,7 @@ impl From<QuitOpt> for EventQuit {
|
|||
EventQuit { code: value.code, no_cwd_file: value.no_cwd_file, ..Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for QuitOpt {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { lua.to_value(&self) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,76 @@
|
|||
use std::collections::HashSet;
|
||||
use std::{borrow::Cow, collections::HashSet};
|
||||
|
||||
use anyhow::bail;
|
||||
use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, MultiValue, ObjectLike, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use yazi_binding::get_metatable;
|
||||
use yazi_shared::{event::CmdCow, url::Url};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct UpdateYankedOpt {
|
||||
type Iter = yazi_binding::Iter<
|
||||
std::iter::Map<std::collections::hash_set::IntoIter<Url>, fn(Url) -> yazi_binding::Url>,
|
||||
yazi_binding::Url,
|
||||
>;
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct UpdateYankedOpt<'a> {
|
||||
pub cut: bool,
|
||||
pub urls: HashSet<Url>,
|
||||
pub urls: Cow<'a, HashSet<Url>>,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for UpdateYankedOpt {
|
||||
impl TryFrom<CmdCow> for UpdateYankedOpt<'_> {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
// TODO: remove `BodyYankIter`
|
||||
if let Some(iter) = c.take_any::<yazi_dds::body::BodyYankIter>("urls") {
|
||||
Ok(Self { urls: iter.urls.into_iter().collect(), cut: iter.cut })
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
opt
|
||||
} else {
|
||||
bail!("Invalid 'urls' argument in UpdateYankedOpt");
|
||||
bail!("'opt' is required for UpdateYankedOpt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for UpdateYankedOpt<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
let len = self.urls.len();
|
||||
let iter = Iter::new(self.urls.into_owned().into_iter().map(yazi_binding::Url::new), Some(len));
|
||||
UpdateYankedIter { cut: self.cut, len, inner: lua.create_userdata(iter)? }.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Iter
|
||||
pub struct UpdateYankedIter {
|
||||
cut: bool,
|
||||
len: usize,
|
||||
inner: AnyUserData,
|
||||
}
|
||||
|
||||
impl UpdateYankedIter {
|
||||
pub fn into_opt(self, lua: &Lua) -> mlua::Result<UpdateYankedOpt<'static>> {
|
||||
Ok(UpdateYankedOpt {
|
||||
cut: self.cut,
|
||||
urls: Cow::Owned(
|
||||
self
|
||||
.inner
|
||||
.take::<Iter>()?
|
||||
.into_iter(lua)
|
||||
.map(|result| result.map(Into::into))
|
||||
.collect::<mlua::Result<_>>()?,
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for UpdateYankedIter {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cut", |_, me| Ok(me.cut));
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len));
|
||||
|
||||
methods.add_meta_function(MetaMethod::Pairs, |lua, ud: AnyUserData| {
|
||||
let me = ud.borrow::<Self>()?;
|
||||
get_metatable(lua, &me.inner)?.call_function::<MultiValue>(MetaMethod::Pairs.name(), ud)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,18 @@ pub struct FilterOpt {
|
|||
pub done: bool,
|
||||
}
|
||||
|
||||
impl From<CmdCow> for FilterOpt {
|
||||
fn from(mut c: CmdCow) -> Self {
|
||||
Self {
|
||||
impl TryFrom<CmdCow> for FilterOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
query: c.take_first_str().unwrap_or_default(),
|
||||
case: FilterCase::from(&*c),
|
||||
done: c.bool("done"),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
use anyhow::bail;
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_shared::{SStr, event::CmdCow};
|
||||
|
||||
pub struct FindDoOpt {
|
||||
pub query: SStr,
|
||||
pub prev: bool,
|
||||
pub case: FilterCase,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for FindDoOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
let Some(query) = c.take_first_str() else {
|
||||
bail!("'query' is required for FindOpt");
|
||||
};
|
||||
|
||||
Ok(Self { query, prev: c.bool("previous"), case: FilterCase::from(&*c) })
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,25 @@
|
|||
use anyhow::bail;
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_shared::{SStr, event::CmdCow};
|
||||
|
||||
pub struct FindDoOpt {
|
||||
pub query: SStr,
|
||||
pub prev: bool,
|
||||
pub case: FilterCase,
|
||||
}
|
||||
|
||||
impl TryFrom<CmdCow> for FindDoOpt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
let Some(query) = c.take_first_str() else {
|
||||
bail!("'query' is required for FindDoOpt");
|
||||
};
|
||||
|
||||
Ok(Self { query, prev: c.bool("previous"), case: FilterCase::from(&*c) })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ yazi_macro::mod_flat!(
|
|||
enter
|
||||
escape
|
||||
filter
|
||||
filter_do
|
||||
find
|
||||
find_arrow
|
||||
find_do
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ impl TryFrom<CmdCow> for UpdatePeekedOpt {
|
|||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
let Some(lock) = c.take_any("lock") else {
|
||||
bail!("Invalid 'lock' argument in UpdatePeekedOpt");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ impl TryFrom<CmdCow> for UpdateSpottedOpt {
|
|||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
let Some(lock) = c.take_any("lock") else {
|
||||
bail!("Invalid 'lock' argument in UpdateSpottedOpt");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ impl TryFrom<CmdCow> for ShowOpt {
|
|||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
if let Some(opt) = c.take_any2("opt") {
|
||||
return opt;
|
||||
}
|
||||
|
||||
Ok(Self { cands: c.take_any("candidates").unwrap_or_default(), silent: c.bool("silent") })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
local function setup(_, opts)
|
||||
if opts.sync_yanked then
|
||||
ps.sub_remote("@yank", function(body) ya.emit("update_yanked", { cut = body.cut, urls = body }) end)
|
||||
ps.sub_remote("@yank", function(opt) ya.emit("update_yanked", { opt = opt }) end)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@ pub struct Pubsub;
|
|||
|
||||
impl Pubsub {
|
||||
pub(super) fn r#pub(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (kind, value): (mlua::String, Value)| {
|
||||
yazi_dds::Pubsub::r#pub(Body::from_lua(&kind.to_str()?, value)?).into_lua_err()
|
||||
lua.create_function(|lua, (kind, value): (mlua::String, Value)| {
|
||||
yazi_dds::Pubsub::r#pub(Body::from_lua(lua, &kind.to_str()?, value)?).into_lua_err()
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn pub_to(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (receiver, kind, value): (Id, mlua::String, Value)| {
|
||||
yazi_dds::Pubsub::pub_to(*receiver, Body::from_lua(&kind.to_str()?, value)?).into_lua_err()
|
||||
lua.create_function(|lua, (receiver, kind, value): (Id, mlua::String, Value)| {
|
||||
yazi_dds::Pubsub::pub_to(*receiver, Body::from_lua(lua, &kind.to_str()?, value)?)
|
||||
.into_lua_err()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,18 +17,18 @@ impl Utils {
|
|||
}
|
||||
|
||||
pub(super) fn emit(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
lua.create_function(|lua, (name, args): (String, Table)| {
|
||||
let mut cmd = Cmd::new_or(name, Layer::Mgr)?;
|
||||
cmd.args = Sendable::table_to_args(args)?;
|
||||
cmd.args = Sendable::table_to_args(lua, args)?;
|
||||
Ok(emit!(Call(cmd)))
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn mgr_emit(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
lua.create_function(|lua, (name, args): (String, Table)| {
|
||||
emit!(Call(Cmd {
|
||||
name: name.into(),
|
||||
args: Sendable::table_to_args(args)?,
|
||||
args: Sendable::table_to_args(lua, args)?,
|
||||
layer: Layer::Mgr,
|
||||
}));
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ use tokio::sync::mpsc;
|
|||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
use yazi_binding::{deprecate, elements::{Line, Pos, Text}};
|
||||
use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}};
|
||||
use yazi_macro::emit;
|
||||
use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy};
|
||||
use yazi_parser::which::ShowOpt;
|
||||
use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, WhichProxy};
|
||||
use yazi_shared::{Debounce, event::Cmd};
|
||||
|
||||
use super::Utils;
|
||||
|
|
@ -29,11 +29,7 @@ impl Utils {
|
|||
}
|
||||
|
||||
drop(tx);
|
||||
emit!(Call(
|
||||
Cmd::new("which:show")
|
||||
.with_any("candidates", cands)
|
||||
.with("silent", t.raw_get::<bool>("silent").unwrap_or_default())
|
||||
));
|
||||
WhichProxy::show(ShowOpt { cands, silent: t.raw_get("silent").unwrap_or_default() });
|
||||
|
||||
Ok(rx.recv().await.map(|idx| idx + 1))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use mlua::{AnyUserData, ExternalError, Function, IntoLuaMulti, Lua, Table, Value};
|
||||
use yazi_binding::{Error, elements::{Area, Renderable, Text}};
|
||||
use yazi_config::YAZI;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::tab::PreviewLock;
|
||||
use yazi_shared::{errors::PeekError, event::Cmd};
|
||||
use yazi_parser::tab::{PreviewLock, UpdatePeekedOpt};
|
||||
use yazi_proxy::MgrProxy;
|
||||
use yazi_shared::errors::PeekError;
|
||||
|
||||
use super::Utils;
|
||||
use crate::external::Highlighter;
|
||||
|
|
@ -29,7 +29,7 @@ impl Utils {
|
|||
scroll: Default::default(),
|
||||
})];
|
||||
|
||||
emit!(Call(Cmd::new("mgr:update_peeked").with_any("lock", lock)));
|
||||
MgrProxy::update_peeked(UpdatePeekedOpt { lock });
|
||||
().into_lua_multi(&lua)
|
||||
})
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ impl Utils {
|
|||
_ => Err("preview widget must be a renderable element or a table of them".into_lua_err())?,
|
||||
};
|
||||
|
||||
emit!(Call(Cmd::new("mgr:update_peeked").with_any("lock", lock)));
|
||||
MgrProxy::update_peeked(UpdatePeekedOpt { lock });
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use mlua::{AnyUserData, Function, Lua, Table};
|
||||
use yazi_binding::elements::{Edge, Renderable};
|
||||
use yazi_config::THEME;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::tab::SpotLock;
|
||||
use yazi_shared::event::Cmd;
|
||||
use yazi_parser::tab::{SpotLock, UpdateSpottedOpt};
|
||||
use yazi_proxy::MgrProxy;
|
||||
|
||||
use super::Utils;
|
||||
|
||||
|
|
@ -32,7 +31,7 @@ impl Utils {
|
|||
}),
|
||||
Renderable::Table(Box::new(table)),
|
||||
];
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("lock", lock)));
|
||||
MgrProxy::update_spotted(UpdateSpottedOpt { lock });
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -43,7 +42,7 @@ impl Utils {
|
|||
let mut lock = SpotLock::try_from(t)?;
|
||||
lock.data = widgets.into_iter().map(Renderable::try_from).collect::<mlua::Result<_>>()?;
|
||||
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("lock", lock)));
|
||||
MgrProxy::update_spotted(UpdateSpottedOpt { lock });
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl Utils {
|
|||
let Some(cur) = runtime!(lua)?.current_owned() else {
|
||||
return Err("block spawned by `ya.sync()` must be called in a plugin").into_lua_err();
|
||||
};
|
||||
Sendable::list_to_values(&lua, Self::retrieve(cur, block, args).await?)
|
||||
Sendable::list_to_values(&lua, Self::retrieve(&lua, cur, block, args).await?)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
|
|
@ -79,8 +79,13 @@ impl Utils {
|
|||
lua.create_async_function(|_lua, _futs: MultiValue| async move { Ok(()) })
|
||||
}
|
||||
|
||||
async fn retrieve(id: String, calls: usize, args: MultiValue) -> mlua::Result<Vec<Data>> {
|
||||
let args = Sendable::values_to_list(args)?;
|
||||
async fn retrieve(
|
||||
lua: &Lua,
|
||||
id: String,
|
||||
calls: usize,
|
||||
args: MultiValue,
|
||||
) -> mlua::Result<Vec<Data>> {
|
||||
let args = Sendable::values_to_list(lua, args)?;
|
||||
let (tx, rx) = oneshot::channel::<Vec<Data>>();
|
||||
|
||||
let callback: PluginCallback = {
|
||||
|
|
@ -95,7 +100,7 @@ impl Utils {
|
|||
.chain(args.into_iter().map(|d| Sendable::data_to_value(lua, d)))
|
||||
.collect::<mlua::Result<MultiValue>>()?;
|
||||
|
||||
let values = Sendable::values_to_list(block.call(args)?)?;
|
||||
let values = Sendable::values_to_list(lua, block.call(args)?)?;
|
||||
tx.send(values).map_err(|_| "send failed".into_lua_err())
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
|||
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::app::{NotifyLevel, NotifyOpt, PluginOpt};
|
||||
use yazi_parser::app::{NotifyLevel, NotifyOpt, PluginOpt, TasksProgress};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub struct AppProxy;
|
||||
|
|
@ -51,4 +51,8 @@ impl AppProxy {
|
|||
pub fn plugin_do(opt: PluginOpt) {
|
||||
emit!(Call(Cmd::new("app:plugin_do").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn update_progress(progress: TasksProgress) {
|
||||
emit!(Call(Cmd::new("app:update_progress").with_any("progress", progress)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_parser::cmp::ShowOpt;
|
||||
use yazi_shared::{Id, event::Cmd};
|
||||
|
||||
pub struct CmpProxy;
|
||||
|
||||
impl CmpProxy {
|
||||
pub fn show(opt: ShowOpt) {
|
||||
emit!(Call(Cmd::new("cmp:show").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn trigger(word: &str, ticket: Id) {
|
||||
emit!(Call(Cmd::args("cmp:trigger", [word]).with("ticket", ticket)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
mod macros;
|
||||
|
||||
yazi_macro::mod_flat!(app cmp confirm input mgr pick semaphore tasks);
|
||||
yazi_macro::mod_flat!(app cmp confirm input mgr pick semaphore tasks which);
|
||||
|
||||
pub fn init() { crate::init_semaphore(); }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use yazi_macro::emit;
|
||||
use yazi_parser::mgr::{OpenDoOpt, SearchOpt};
|
||||
use yazi_parser::{mgr::{OpenDoOpt, SearchOpt}, tab::{FilterOpt, FindDoOpt, UpdatePeekedOpt, UpdateSpottedOpt}};
|
||||
use yazi_shared::{SStr, event::Cmd, url::Url};
|
||||
|
||||
pub struct MgrProxy;
|
||||
|
|
@ -29,6 +29,14 @@ impl MgrProxy {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn find_do(opt: FindDoOpt) {
|
||||
emit!(Call(Cmd::new("mgr:find_do").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn filter_do(opt: FilterOpt) {
|
||||
emit!(Call(Cmd::new("mgr:filter_do").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn search_do(opt: SearchOpt) {
|
||||
emit!(Call(
|
||||
// TODO: use second positional argument instead of `args` parameter
|
||||
|
|
@ -38,6 +46,14 @@ impl MgrProxy {
|
|||
));
|
||||
}
|
||||
|
||||
pub fn update_peeked(opt: UpdatePeekedOpt) {
|
||||
emit!(Call(Cmd::new("mgr:update_peeked").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn update_spotted(opt: UpdateSpottedOpt) {
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
pub fn update_tasks(url: &Url) {
|
||||
emit!(Call(Cmd::new("mgr:update_tasks").with_any("urls", vec![url.clone()])));
|
||||
}
|
||||
|
|
|
|||
11
yazi-proxy/src/which.rs
Normal file
11
yazi-proxy/src/which.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_parser::which::ShowOpt;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub struct WhichProxy;
|
||||
|
||||
impl WhichProxy {
|
||||
pub fn show(opt: ShowOpt) {
|
||||
emit!(Call(Cmd::new("which:show").with_any("opt", opt)));
|
||||
}
|
||||
}
|
||||
|
|
@ -85,20 +85,16 @@ impl Cmd {
|
|||
pub fn get(&self, name: impl Into<DataKey>) -> Option<&Data> { self.args.get(&name.into()) }
|
||||
|
||||
#[inline]
|
||||
pub fn str(&self, name: impl Into<DataKey>) -> Option<&str> {
|
||||
self.get(name).and_then(Data::as_str)
|
||||
}
|
||||
pub fn str(&self, name: impl Into<DataKey>) -> Option<&str> { self.get(name)?.as_str() }
|
||||
|
||||
#[inline]
|
||||
pub fn bool(&self, name: impl Into<DataKey>) -> bool { self.maybe_bool(name).unwrap_or(false) }
|
||||
|
||||
#[inline]
|
||||
pub fn maybe_bool(&self, name: impl Into<DataKey>) -> Option<bool> {
|
||||
self.get(name).and_then(Data::as_bool)
|
||||
}
|
||||
pub fn maybe_bool(&self, name: impl Into<DataKey>) -> Option<bool> { self.get(name)?.as_bool() }
|
||||
|
||||
#[inline]
|
||||
pub fn id(&self, name: impl Into<DataKey>) -> Option<Id> { self.get(name).and_then(Data::as_id) }
|
||||
pub fn id(&self, name: impl Into<DataKey>) -> Option<Id> { self.get(name)?.as_id() }
|
||||
|
||||
#[inline]
|
||||
pub fn first(&self) -> Option<&Data> { self.get(0) }
|
||||
|
|
@ -136,7 +132,12 @@ impl Cmd {
|
|||
|
||||
#[inline]
|
||||
pub fn take_any<T: 'static>(&mut self, name: impl Into<DataKey>) -> Option<T> {
|
||||
self.args.remove(&name.into()).and_then(|d| d.into_any())
|
||||
self.args.remove(&name.into())?.into_any()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_any2<T: 'static>(&mut self, name: impl Into<DataKey>) -> Option<Result<T>> {
|
||||
self.args.remove(&name.into()).map(Data::into_any2)
|
||||
}
|
||||
|
||||
// Parse
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use std::{borrow::Cow, ops::Deref};
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use super::{Cmd, Data, DataKey};
|
||||
use crate::{SStr, url::Url};
|
||||
|
||||
|
|
@ -75,4 +77,12 @@ impl CmdCow {
|
|||
Self::Borrowed(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_any2<T: 'static>(&mut self, name: impl Into<DataKey>) -> Option<Result<T>> {
|
||||
match self {
|
||||
Self::Owned(c) => c.take_any2(name),
|
||||
Self::Borrowed(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{any::Any, borrow::Cow, collections::HashMap};
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use ordered_float::OrderedFloat;
|
||||
use serde::{Deserialize, Serialize, de};
|
||||
|
||||
|
|
@ -80,6 +81,18 @@ impl Data {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: find a better name
|
||||
#[inline]
|
||||
pub fn into_any2<T: 'static>(self) -> Result<T> {
|
||||
if let Self::Any(b) = self
|
||||
&& let Ok(t) = b.downcast::<T>()
|
||||
{
|
||||
Ok(*t)
|
||||
} else {
|
||||
bail!("Failed to downcast Data into {}", std::any::type_name::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_url(&self) -> Option<Url> {
|
||||
match self {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue