feat: support calling methods in builtin plugins with arbitrary types of arguments (self can now be omitted) (#1666)

This commit is contained in:
三咲雅 · Misaki Masa 2024-09-21 00:23:46 +08:00 committed by GitHub
parent e858d11ce0
commit ac196f211e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 27 deletions

View File

@ -13,7 +13,7 @@ function M:peek()
:spawn()
if not child then
return self:fallback_to_builtin()
return require("code").peek(self)
end
local limit = self.area.h
@ -21,7 +21,7 @@ function M:peek()
repeat
local next, event = child:read_line()
if event == 1 then
return self:fallback_to_builtin()
return require("code").peek(self)
elseif event ~= 0 then
break
end
@ -52,15 +52,4 @@ function M:seek(units)
end
end
function M:fallback_to_builtin()
local err, bound = ya.preview_code(self)
if bound then
ya.manager_emit("peek", { bound, only_if = self.file.url, upper_bound = true })
elseif err and not err:find("cancelled", 1, true) then
ya.preview_widgets(self, {
ui.Paragraph(self.area, { ui.Line(err):reverse() }),
})
end
end
return M

View File

@ -41,13 +41,11 @@ impl Require {
}
fn create_mt<'a>(lua: &'a Lua, id: &str, mod_: Table<'a>, sync: bool) -> mlua::Result<Table<'a>> {
let ts = lua.create_table_from([("_mod", mod_.into_lua(lua)?)])?;
let id: Arc<str> = Arc::from(id);
let mt = lua.create_table_from([(
"__index",
lua.create_function(move |lua, (ts, key): (Table, mlua::String)| {
match ts.raw_get::<_, Table>("_mod")?.raw_get::<_, Value>(&key)? {
match ts.raw_get::<_, Table>("__mod")?.raw_get::<_, Value>(&key)? {
Value::Function(_) => {
Self::create_wrapper(lua, id.clone(), key.to_str()?, sync)?.into_lua(lua)
}
@ -56,6 +54,7 @@ impl Require {
})?,
)])?;
let ts = lua.create_table_from([("__mod", mod_)])?;
ts.set_metatable(Some(mt));
Ok(ts)
}
@ -69,24 +68,45 @@ impl Require {
let f: Arc<str> = Arc::from(f);
if sync {
lua.create_function(move |lua, (ts, args): (Table, MultiValue)| {
let mod_: Table = ts.raw_get::<_, Table>("_mod")?;
lua.create_function(move |lua, args: MultiValue| {
let (mod_, args) = Self::split_mod_and_args(lua, &id, args)?;
lua.named_registry_value::<RtRef>("rt")?.push(&id);
let result = mod_.call_method::<_, MultiValue>(&f, args);
let result = mod_.call_function::<_, MultiValue>(&f, args);
lua.named_registry_value::<RtRef>("rt")?.pop();
result
})
} else {
lua.create_async_function(move |lua, (ts, args): (Table, MultiValue)| {
lua.create_async_function(move |lua, args: MultiValue| {
let (id, f) = (id.clone(), f.clone());
async move {
let mod_: Table = ts.raw_get::<_, Table>("_mod")?;
let (mod_, args) = Self::split_mod_and_args(lua, &id, args)?;
lua.named_registry_value::<RtRef>("rt")?.push(&id);
let result = mod_.call_async_method::<_, MultiValue>(&f, args).await;
let result = mod_.call_async_function::<_, MultiValue>(&f, args).await;
lua.named_registry_value::<RtRef>("rt")?.pop();
result
}
})
}
}
fn split_mod_and_args<'a>(
lua: &'a Lua,
id: &str,
mut args: MultiValue<'a>,
) -> mlua::Result<(Table<'a>, MultiValue<'a>)> {
let Some(front) = args.pop_front() else {
return Ok((LOADER.load(lua, id)?, args));
};
let Value::Table(tbl) = front else {
args.push_front(front);
return Ok((LOADER.load(lua, id)?, args));
};
Ok(if let Ok(mod_) = tbl.raw_get::<_, Table>("__mod") {
args.push_front(Value::Table(mod_.clone()));
(mod_, args)
} else {
args.push_front(Value::Table(tbl));
(LOADER.load(lua, id)?, args)
})
}
}

View File

@ -1,4 +1,4 @@
use mlua::{ExternalError, ExternalResult, Function, IntoLua, Lua, MultiValue, Table, Value};
use mlua::{ExternalError, ExternalResult, Function, Lua, MultiValue, Table, Value};
use tokio::sync::oneshot;
use yazi_dds::Sendable;
use yazi_shared::{emit, event::{Cmd, Data}, Layer};
@ -17,10 +17,9 @@ impl Utils {
}
let cur = rt.current().unwrap().to_owned();
lua.create_function(move |lua, args: MultiValue| {
f.call::<_, MultiValue>(MultiValue::from_iter(
[LOADER.load(lua, &cur)?.into_lua(lua)?].into_iter().chain(args),
))
lua.create_function(move |lua, mut args: MultiValue| {
args.push_front(Value::Table(LOADER.load(lua, &cur)?));
f.call::<_, MultiValue>(args)
})
})?,
)?;