mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: plugin-specific state persistence (#590)
This commit is contained in:
parent
c325c332de
commit
68ffd82c0d
19 changed files with 130 additions and 89 deletions
|
|
@ -23,7 +23,7 @@ impl App {
|
||||||
|
|
||||||
Lives::register()?;
|
Lives::register()?;
|
||||||
let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
|
let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
|
||||||
app.render()?;
|
app.render();
|
||||||
|
|
||||||
let mut times = 0;
|
let mut times = 0;
|
||||||
let mut events = Vec::with_capacity(200);
|
let mut events = Vec::with_capacity(200);
|
||||||
|
|
@ -39,13 +39,13 @@ impl App {
|
||||||
|
|
||||||
if times >= 50 {
|
if times >= 50 {
|
||||||
times = 0;
|
times = 0;
|
||||||
app.render()?;
|
app.render();
|
||||||
} else if let Ok(event) = app.signals.rx.try_recv() {
|
} else if let Ok(event) = app.signals.rx.try_recv() {
|
||||||
events.push(event);
|
events.push(event);
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
} else {
|
} else {
|
||||||
times = 0;
|
times = 0;
|
||||||
app.render()?;
|
app.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -58,7 +58,7 @@ impl App {
|
||||||
Event::Seq(execs, layer) => self.dispatch_seq(execs, layer),
|
Event::Seq(execs, layer) => self.dispatch_seq(execs, layer),
|
||||||
Event::Render => self.dispatch_render(),
|
Event::Render => self.dispatch_render(),
|
||||||
Event::Key(key) => self.dispatch_key(key),
|
Event::Key(key) => self.dispatch_key(key),
|
||||||
Event::Resize => self.resize()?,
|
Event::Resize => self.resize(()),
|
||||||
Event::Paste(str) => self.dispatch_paste(str),
|
Event::Paste(str) => self.dispatch_paste(str),
|
||||||
Event::Quit(opt) => self.quit(opt),
|
Event::Quit(opt) => self.quit(opt),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use mlua::{ExternalError, ExternalResult, IntoLua, Table, TableExt, Value, Variadic};
|
use mlua::{ExternalError, ExternalResult, IntoLua, Table, TableExt, Variadic};
|
||||||
use tracing::{error, warn};
|
use tracing::warn;
|
||||||
use yazi_plugin::{LOADED, LUA};
|
use yazi_plugin::{LOADED, LUA};
|
||||||
use yazi_shared::{emit, event::Exec, Layer};
|
use yazi_shared::{emit, event::Exec, Layer};
|
||||||
|
|
||||||
|
|
@ -36,31 +36,26 @@ impl App {
|
||||||
};
|
};
|
||||||
|
|
||||||
let args = Variadic::from_iter(opt.data.args.into_iter().filter_map(|v| v.into_lua(&LUA).ok()));
|
let args = Variadic::from_iter(opt.data.args.into_iter().filter_map(|v| v.into_lua(&LUA).ok()));
|
||||||
let mut ret: mlua::Result<Value> = Err("uninitialized plugin".into_lua_err());
|
let result = Lives::scope(&self.cx, |_| {
|
||||||
|
LUA.globals().set("YAZI_PLUGIN_NAME", LUA.create_string(&opt.name)?)?;
|
||||||
|
|
||||||
Lives::scope(&self.cx, |_| {
|
|
||||||
let mut plugin: Option<Table> = None;
|
let mut plugin: Option<Table> = None;
|
||||||
if let Some(b) = LOADED.read().get(&opt.name) {
|
if let Some(b) = LOADED.read().get(&opt.name) {
|
||||||
match LUA.load(b).call(args) {
|
plugin = LUA.load(b).call(args)?;
|
||||||
Ok(t) => plugin = Some(t),
|
|
||||||
Err(e) => ret = Err(e),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(plugin) = plugin {
|
|
||||||
ret = if let Some(cb) = opt.data.cb { cb(plugin) } else { plugin.call_method("entry", ()) };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Err(e) = ret {
|
let Some(plugin) = plugin else {
|
||||||
error!("{e}");
|
return Err("plugin not found".into_lua_err());
|
||||||
return;
|
};
|
||||||
}
|
|
||||||
|
if let Some(cb) = opt.data.cb { cb(plugin) } else { plugin.call_method("entry", ()) }
|
||||||
|
});
|
||||||
|
|
||||||
let Some(tx) = opt.data.tx else {
|
let Some(tx) = opt.data.tx else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(v) = ret.and_then(|v| v.try_into().into_lua_err()) {
|
if let Ok(v) = result.and_then(|v| v.try_into().into_lua_err()) {
|
||||||
tx.send(v).ok();
|
tx.send(v).ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,31 @@
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use ratatui::backend::Backend;
|
use ratatui::backend::Backend;
|
||||||
|
|
||||||
use crate::{app::App, lives::Lives, root::{Root, COLLISION}};
|
use crate::{app::App, lives::Lives, root::{Root, COLLISION}};
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub(crate) fn render(&mut self) -> Result<()> {
|
pub(crate) fn render(&mut self) {
|
||||||
let Some(term) = &mut self.term else {
|
let Some(term) = &mut self.term else {
|
||||||
return Ok(());
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let collision = COLLISION.swap(false, Ordering::Relaxed);
|
let collision = COLLISION.swap(false, Ordering::Relaxed);
|
||||||
let frame = term.draw(|f| {
|
let frame = term
|
||||||
Lives::scope(&self.cx, |_| {
|
.draw(|f| {
|
||||||
f.render_widget(Root::new(&self.cx), f.size());
|
_ = Lives::scope(&self.cx, |_| Ok(f.render_widget(Root::new(&self.cx), f.size())));
|
||||||
});
|
if let Some((x, y)) = self.cx.cursor() {
|
||||||
|
f.set_cursor(x, y);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if let Some((x, y)) = self.cx.cursor() {
|
|
||||||
f.set_cursor(x, y);
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
if !COLLISION.load(Ordering::Relaxed) {
|
if !COLLISION.load(Ordering::Relaxed) {
|
||||||
if collision {
|
if collision {
|
||||||
// Reload preview if collision is resolved
|
// Reload preview if collision is resolved
|
||||||
self.cx.manager.peek(true);
|
self.cx.manager.peek(true);
|
||||||
}
|
}
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut patch = vec![];
|
let mut patch = vec![];
|
||||||
|
|
@ -39,12 +38,11 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
term.backend_mut().draw(patch.iter().map(|(x, y, cell)| (*x, *y, cell)))?;
|
term.backend_mut().draw(patch.iter().map(|(x, y, cell)| (*x, *y, cell))).ok();
|
||||||
if let Some((x, y)) = self.cx.cursor() {
|
if let Some((x, y)) = self.cx.cursor() {
|
||||||
term.show_cursor()?;
|
term.show_cursor().ok();
|
||||||
term.set_cursor(x, y)?;
|
term.set_cursor(x, y).ok();
|
||||||
}
|
}
|
||||||
term.backend_mut().flush()?;
|
term.backend_mut().flush().ok();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,23 @@
|
||||||
use anyhow::Result;
|
use yazi_shared::event::Exec;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
|
|
||||||
|
pub struct Opt;
|
||||||
|
|
||||||
|
impl From<Exec> for Opt {
|
||||||
|
fn from(_: Exec) -> Self { Self }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<()> for Opt {
|
||||||
|
fn from(_: ()) -> Self { Self }
|
||||||
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub(crate) fn resize(&mut self) -> Result<()> {
|
pub(crate) fn resize(&mut self, _: impl Into<Opt>) {
|
||||||
self.cx.manager.active_mut().preview.reset();
|
self.cx.manager.active_mut().preview.reset();
|
||||||
self.render()?;
|
self.render();
|
||||||
|
|
||||||
self.cx.manager.current_mut().sync_page(true);
|
self.cx.manager.current_mut().sync_page(true);
|
||||||
self.cx.manager.hover(None);
|
self.cx.manager.hover(None);
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ impl App {
|
||||||
|
|
||||||
// While the app resumes, it's possible that the terminal size has changed.
|
// While the app resumes, it's possible that the terminal size has changed.
|
||||||
// We need to trigger a resize, and render the UI based on the resized area.
|
// We need to trigger a resize, and render the UI based on the resized area.
|
||||||
self.resize().unwrap();
|
self.resize(());
|
||||||
|
|
||||||
self.signals.resume();
|
self.signals.resume();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ impl<'a> Executor<'a> {
|
||||||
on!(plugin);
|
on!(plugin);
|
||||||
on!(plugin_do);
|
on!(plugin_do);
|
||||||
on!(update_progress);
|
on!(update_progress);
|
||||||
|
on!(resize);
|
||||||
on!(stop);
|
on!(stop);
|
||||||
on!(resume);
|
on!(resume);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,10 @@ impl Lives {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn scope<'a>(cx: &'a Ctx, f: impl FnOnce(&Scope<'a, 'a>)) {
|
pub(crate) fn scope<'a, T>(
|
||||||
|
cx: &'a Ctx,
|
||||||
|
f: impl FnOnce(&Scope<'a, 'a>) -> mlua::Result<T>,
|
||||||
|
) -> mlua::Result<T> {
|
||||||
let result = LUA.scope(|scope| {
|
let result = LUA.scope(|scope| {
|
||||||
LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?;
|
LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?;
|
||||||
|
|
||||||
|
|
@ -37,7 +40,7 @@ impl Lives {
|
||||||
])?,
|
])?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
f(scope);
|
let ret = f(scope)?;
|
||||||
|
|
||||||
LAYOUT.store(Arc::new(yazi_config::Layout {
|
LAYOUT.store(Arc::new(yazi_config::Layout {
|
||||||
header: *global.get::<_, Table>("Header")?.get::<_, RectRef>("area")?,
|
header: *global.get::<_, Table>("Header")?.get::<_, RectRef>("area")?,
|
||||||
|
|
@ -47,12 +50,13 @@ impl Lives {
|
||||||
status: *global.get::<_, Table>("Status")?.get::<_, RectRef>("area")?,
|
status: *global.get::<_, Table>("Status")?.get::<_, RectRef>("area")?,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Ok(())
|
Ok(ret)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(ref e) = result {
|
||||||
error!("{e}");
|
error!("{e}");
|
||||||
}
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn partial_scope<'a>(cx: &'a Ctx, f: impl FnOnce(&Scope<'a, 'a>)) {
|
pub(crate) fn partial_scope<'a>(cx: &'a Ctx, f: impl FnOnce(&Scope<'a, 'a>)) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::module_inception)]
|
||||||
|
#![allow(clippy::unit_arg)]
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod completion;
|
mod completion;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,26 @@ function Folder:icon(file)
|
||||||
return icon and ui.Span(" " .. icon.text .. " "):style(icon.style) or ui.Span("")
|
return icon and ui.Span(" " .. icon.text .. " "):style(icon.style) or ui.Span("")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Folder:highlight_ranges(s, ranges)
|
||||||
|
if ranges == nil or #ranges == 0 then
|
||||||
|
return { ui.Span(s) }
|
||||||
|
end
|
||||||
|
|
||||||
|
local spans = {}
|
||||||
|
local last = 0
|
||||||
|
for _, r in ipairs(ranges) do
|
||||||
|
if r[1] > last then
|
||||||
|
spans[#spans + 1] = ui.Span(s:sub(last + 1, r[1]))
|
||||||
|
end
|
||||||
|
spans[#spans + 1] = ui.Span(s:sub(r[1] + 1, r[2])):style(THEME.manager.find_keyword)
|
||||||
|
last = r[2]
|
||||||
|
end
|
||||||
|
if last < #s then
|
||||||
|
spans[#spans + 1] = ui.Span(s:sub(last + 1))
|
||||||
|
end
|
||||||
|
return spans
|
||||||
|
end
|
||||||
|
|
||||||
function Folder:highlighted_name(file)
|
function Folder:highlighted_name(file)
|
||||||
-- Complete prefix when searching across directories
|
-- Complete prefix when searching across directories
|
||||||
local prefix = file:prefix() or ""
|
local prefix = file:prefix() or ""
|
||||||
|
|
@ -28,7 +48,7 @@ function Folder:highlighted_name(file)
|
||||||
|
|
||||||
-- Range highlighting for filenames
|
-- Range highlighting for filenames
|
||||||
local highlights = file:highlights()
|
local highlights = file:highlights()
|
||||||
local spans = ui.highlight_ranges(prefix .. file.name, highlights)
|
local spans = self:highlight_ranges(prefix .. file.name, highlights)
|
||||||
|
|
||||||
-- Show symlink target
|
-- Show symlink target
|
||||||
if MANAGER.show_symlink and file.link_to ~= nil then
|
if MANAGER.show_symlink and file.link_to ~= nil then
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,17 @@ function Header:tabs()
|
||||||
return ui.Line(spans)
|
return ui.Line(spans)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Header:render(area)
|
function Header:layout(area)
|
||||||
self.area = area
|
self.area = area
|
||||||
|
|
||||||
local chunks = ui.Layout()
|
return ui.Layout()
|
||||||
:direction(ui.Layout.HORIZONTAL)
|
:direction(ui.Layout.HORIZONTAL)
|
||||||
:constraints({ ui.Constraint.Percentage(50), ui.Constraint.Percentage(50) })
|
:constraints({ ui.Constraint.Percentage(50), ui.Constraint.Percentage(50) })
|
||||||
:split(area)
|
:split(area)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Header:render(area)
|
||||||
|
local chunks = self:layout(area)
|
||||||
|
|
||||||
local left = ui.Line { self:cwd() }
|
local left = ui.Line { self:cwd() }
|
||||||
local right = ui.Line { self:tabs() }
|
local right = ui.Line { self:tabs() }
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ Manager = {
|
||||||
area = ui.Rect.default,
|
area = ui.Rect.default,
|
||||||
}
|
}
|
||||||
|
|
||||||
function Manager:render(area)
|
function Manager:layout(area)
|
||||||
self.area = area
|
self.area = area
|
||||||
|
|
||||||
local chunks = ui.Layout()
|
return ui.Layout()
|
||||||
:direction(ui.Layout.HORIZONTAL)
|
:direction(ui.Layout.HORIZONTAL)
|
||||||
:constraints({
|
:constraints({
|
||||||
ui.Constraint.Ratio(MANAGER.ratio.parent, MANAGER.ratio.all),
|
ui.Constraint.Ratio(MANAGER.ratio.parent, MANAGER.ratio.all),
|
||||||
|
|
@ -13,6 +13,10 @@ function Manager:render(area)
|
||||||
ui.Constraint.Ratio(MANAGER.ratio.preview, MANAGER.ratio.all),
|
ui.Constraint.Ratio(MANAGER.ratio.preview, MANAGER.ratio.all),
|
||||||
})
|
})
|
||||||
:split(area)
|
:split(area)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Manager:render(area)
|
||||||
|
local chunks = self:layout(area)
|
||||||
|
|
||||||
return ya.flat {
|
return ya.flat {
|
||||||
-- Borders
|
-- Borders
|
||||||
|
|
|
||||||
16
yazi-plugin/preset/state.lua
Normal file
16
yazi-plugin/preset/state.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
local cache = {}
|
||||||
|
|
||||||
|
state = setmetatable({
|
||||||
|
clear = function() cache[YAZI_PLUGIN_NAME] = nil end,
|
||||||
|
}, {
|
||||||
|
__index = function(_, k)
|
||||||
|
local bucket = YAZI_PLUGIN_NAME
|
||||||
|
return cache[bucket] and cache[bucket][k]
|
||||||
|
end,
|
||||||
|
|
||||||
|
__newindex = function(_, k, v)
|
||||||
|
local bucket = YAZI_PLUGIN_NAME
|
||||||
|
cache[bucket] = cache[bucket] or {}
|
||||||
|
cache[bucket][k] = v
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
ui = {}
|
|
||||||
|
|
||||||
function ui.highlight_ranges(s, ranges)
|
|
||||||
if ranges == nil or #ranges == 0 then
|
|
||||||
return { ui.Span(s) }
|
|
||||||
end
|
|
||||||
|
|
||||||
local spans = {}
|
|
||||||
local last = 0
|
|
||||||
for _, r in ipairs(ranges) do
|
|
||||||
if r[1] > last then
|
|
||||||
spans[#spans + 1] = ui.Span(s:sub(last + 1, r[1]))
|
|
||||||
end
|
|
||||||
spans[#spans + 1] = ui.Span(s:sub(r[1] + 1, r[2])):style(THEME.manager.find_keyword)
|
|
||||||
last = r[2]
|
|
||||||
end
|
|
||||||
if last < #s then
|
|
||||||
spans[#spans + 1] = ui.Span(s:sub(last + 1))
|
|
||||||
end
|
|
||||||
return spans
|
|
||||||
end
|
|
||||||
|
|
@ -39,7 +39,7 @@ function ya.sync(f)
|
||||||
end
|
end
|
||||||
|
|
||||||
local calls = ya.SYNC_CALLS
|
local calls = ya.SYNC_CALLS
|
||||||
return function(...) return plugin_retrieve(ya.PLUGIN_NAME, calls, ...) end
|
return function(...) return plugin_retrieve(YAZI_PLUGIN_NAME, calls, ...) end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ya.basename(str) return string.gsub(str, "(.*[/\\])(.*)", "%2") end
|
function ya.basename(str) return string.gsub(str, "(.*[/\\])(.*)", "%2") end
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ use mlua::{AnyUserData, Lua, Table};
|
||||||
use crate::cast_to_renderable;
|
use crate::cast_to_renderable;
|
||||||
|
|
||||||
pub fn init(lua: &Lua) -> mlua::Result<()> {
|
pub fn init(lua: &Lua) -> mlua::Result<()> {
|
||||||
let globals = lua.globals();
|
let ui: Table = lua.create_table()?;
|
||||||
let ui: Table = globals.get("ui").or_else(|_| lua.create_table())?;
|
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
super::Padding::register(lua)?;
|
super::Padding::register(lua)?;
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,7 @@ impl UserData for Layout {
|
||||||
ud.borrow_mut::<Self>()?.constraints = value.into_iter().map(|c| c.0).collect();
|
ud.borrow_mut::<Self>()?.constraints = value.into_iter().map(|c| c.0).collect();
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
methods.add_function("split", |lua, (ud, value): (AnyUserData, RectRef)| {
|
methods.add_method("split", |lua, me, value: RectRef| {
|
||||||
let me = ud.borrow::<Self>()?;
|
|
||||||
|
|
||||||
let mut layout = ratatui::layout::Layout::new(
|
let mut layout = ratatui::layout::Layout::new(
|
||||||
if me.direction == VERTICAL {
|
if me.direction == VERTICAL {
|
||||||
ratatui::layout::Direction::Vertical
|
ratatui::layout::Direction::Vertical
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ pub async fn entry(name: String, args: Vec<ValueSendable>) -> mlua::Result<()> {
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let lua = slim_lua()?;
|
let lua = slim_lua()?;
|
||||||
let args = Variadic::from_iter(args.into_iter().filter_map(|v| v.into_lua(&lua).ok()));
|
lua.globals().set("YAZI_PLUGIN_NAME", lua.create_string(&name)?)?;
|
||||||
|
|
||||||
|
let args = Variadic::from_iter(args.into_iter().filter_map(|v| v.into_lua(&lua).ok()));
|
||||||
let plugin: Table = if let Some(b) = LOADED.read().get(&name) {
|
let plugin: Table = if let Some(b) = LOADED.read().get(&name) {
|
||||||
lua.load(b).call(args)?
|
lua.load(b).call(args)?
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub fn init() {
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
lua.load(include_str!("../preset/inspect/inspect.lua")).exec()?;
|
lua.load(include_str!("../preset/inspect/inspect.lua")).exec()?;
|
||||||
lua.load(include_str!("../preset/ui.lua")).exec()?;
|
lua.load(include_str!("../preset/state.lua")).exec()?;
|
||||||
lua.load(include_str!("../preset/ya.lua")).exec()?;
|
lua.load(include_str!("../preset/ya.lua")).exec()?;
|
||||||
crate::elements::init(lua)?;
|
crate::elements::init(lua)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,17 @@ impl Utils {
|
||||||
Ok((args, named))
|
Ok((args, named))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn create_exec(cmd: String, table: Table, data: Option<Value>) -> mlua::Result<Exec> {
|
||||||
|
let (args, named) = Self::parse_args(table)?;
|
||||||
|
let mut exec = Exec { cmd, args, named, ..Default::default() };
|
||||||
|
|
||||||
|
if let Some(data) = data.and_then(|v| ValueSendable::try_from(v).ok()) {
|
||||||
|
exec = exec.with_data(data);
|
||||||
|
}
|
||||||
|
Ok(exec)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn call(lua: &Lua, ya: &Table) -> mlua::Result<()> {
|
pub(super) fn call(lua: &Lua, ya: &Table) -> mlua::Result<()> {
|
||||||
ya.set(
|
ya.set(
|
||||||
"render",
|
"render",
|
||||||
|
|
@ -37,17 +48,18 @@ impl Utils {
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
ya.set(
|
||||||
|
"app_emit",
|
||||||
|
lua.create_function(|_, (cmd, table, data): (String, Table, Option<Value>)| {
|
||||||
|
emit!(Call(Self::create_exec(cmd, table, data)?, Layer::App));
|
||||||
|
Ok(())
|
||||||
|
})?,
|
||||||
|
)?;
|
||||||
|
|
||||||
ya.set(
|
ya.set(
|
||||||
"manager_emit",
|
"manager_emit",
|
||||||
lua.create_function(|_, (cmd, table, data): (String, Table, Option<Value>)| {
|
lua.create_function(|_, (cmd, table, data): (String, Table, Option<Value>)| {
|
||||||
let (args, named) = Self::parse_args(table)?;
|
emit!(Call(Self::create_exec(cmd, table, data)?, Layer::Manager));
|
||||||
let mut exec = Exec { cmd, args, named, ..Default::default() };
|
|
||||||
|
|
||||||
if let Some(data) = data.and_then(|v| ValueSendable::try_from(v).ok()) {
|
|
||||||
exec = exec.with_data(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit!(Call(exec, Layer::Manager));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})?,
|
})?,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue