feat: new cf and th allow to access user configuration and theme scheme in sync/async plugins consistently (#2389)

This commit is contained in:
三咲雅 · Misaki Masa 2025-02-23 20:37:35 +08:00 committed by GitHub
parent 2410bb9671
commit 7b4c4eae40
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 158 additions and 120 deletions

View file

@ -58,7 +58,6 @@ syntect_theme = ""
# : Mode {{{
[mode]
normal_main = { bg = "blue", bold = true }
normal_alt = { fg = "blue", bg = "gray" }
@ -208,7 +207,6 @@ footer = { fg = "black", bg = "white" }
# : File-specific styles {{{
[filetype]
rules = [
# Images
{ mime = "image/*", fg = "yellow" },
@ -244,7 +242,6 @@ rules = [
# : Icons {{{
[icon]
globs = []
dirs = [
{ name = ".config", text = "" },

View file

@ -58,7 +58,6 @@ syntect_theme = ""
# : Mode {{{
[mode]
normal_main = { bg = "blue", bold = true }
normal_alt = { fg = "blue", bg = "gray" }
@ -208,7 +207,6 @@ footer = { fg = "black", bg = "white" }
# : File-specific styles {{{
[filetype]
rules = [
# Images
{ mime = "image/*", fg = "yellow" },
@ -244,7 +242,6 @@ rules = [
# : Icons {{{
[icon]
globs = []
dirs = [
{ name = ".config", text = "" },

View file

@ -88,7 +88,6 @@ image_bound = [ 0, 0 ]
suppress_preload = false
[plugin]
fetchers = [
# Mimetype
{ id = "mime", name = "*", run = "mime", prio = "high" },

View file

@ -11,8 +11,8 @@ use super::{Filetype, Flavor, Icons};
pub struct Theme {
pub flavor: Flavor,
pub manager: Manager,
mode: Mode,
status: Status,
pub mode: Mode,
pub status: Status,
pub which: Which,
pub confirm: Confirm,
pub spot: Spot,
@ -80,7 +80,7 @@ pub struct Manager {
}
#[derive(Deserialize, Serialize)]
struct Mode {
pub struct Mode {
pub normal_main: Style,
pub normal_alt: Style,
@ -92,7 +92,7 @@ struct Mode {
}
#[derive(Deserialize, Serialize)]
struct Status {
pub struct Status {
pub overall: Style,
pub sep_left: StatusSep,
pub sep_right: StatusSep,
@ -111,7 +111,7 @@ struct Status {
}
#[derive(Deserialize, Serialize)]
struct StatusSep {
pub struct StatusSep {
pub open: String,
pub close: String,
}

View file

@ -28,11 +28,6 @@ impl<'a> From<BodyDelete<'a>> for Body<'a> {
impl IntoLua for BodyDelete<'static> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
let urls = lua.create_table_with_capacity(self.urls.len(), 0)?;
// In most cases, `self.urls` will be `Cow::Owned`, so
// `.into_owned().into_iter()` can avoid any cloning, whereas
// `.iter().cloned()` will clone each element.
#[allow(clippy::unnecessary_to_owned)]
for (i, url) in self.urls.into_owned().into_iter().enumerate() {
urls.raw_set(i + 1, lua.create_any_userdata(url)?)?;
}

View file

@ -28,11 +28,6 @@ impl<'a> From<BodyTrash<'a>> for Body<'a> {
impl IntoLua for BodyTrash<'static> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
let urls = lua.create_table_with_capacity(self.urls.len(), 0)?;
// In most cases, `self.urls` will be `Cow::Owned`, so
// `.into_owned().into_iter()` can avoid any cloning, whereas
// `.iter().cloned()` will clone each element.
#[allow(clippy::unnecessary_to_owned)]
for (i, url) in self.urls.into_owned().into_iter().enumerate() {
urls.raw_set(i + 1, lua.create_any_userdata(url)?)?;
}

View file

@ -1,5 +1,4 @@
#![allow(clippy::module_inception)]
#![allow(clippy::unit_arg)]
#![allow(clippy::module_inception, clippy::unit_arg)]
#[cfg(all(not(target_os = "macos"), not(target_os = "windows")))]
#[global_allocator]

View file

@ -42,7 +42,7 @@ function Entity:highlights()
if h[1] > last then
spans[#spans + 1] = name:sub(last + 1, h[1])
end
spans[#spans + 1] = ui.Span(name:sub(h[1] + 1, h[2])):style(THEME.manager.find_keyword)
spans[#spans + 1] = ui.Span(name:sub(h[1] + 1, h[2])):style(th.manager.find_keyword)
last = h[2]
end
if last < #name then
@ -64,11 +64,11 @@ function Entity:found()
end
local s = string.format("[%d/%s]", found[1] + 1, found[2] >= 100 and "99+" or found[2])
return ui.Line { " ", ui.Span(s):style(THEME.manager.find_position) }
return ui.Line { " ", ui.Span(s):style(th.manager.find_position) }
end
function Entity:symlink()
if not MANAGER.show_symlink then
if not cf.manager.show_symlink then
return ""
end
@ -89,9 +89,9 @@ function Entity:style()
if not self._file:is_hovered() then
return s
elseif self._file:in_preview() then
return s and s:patch(THEME.manager.preview_hovered) or THEME.manager.preview_hovered
return s and s:patch(th.manager.preview_hovered) or th.manager.preview_hovered
else
return s and s:patch(THEME.manager.hovered) or THEME.manager.hovered
return s and s:patch(th.manager.hovered) or th.manager.hovered
end
end

View file

@ -28,7 +28,7 @@ function Header:cwd()
end
local s = ya.readable_path(tostring(self._current.cwd)) .. self:flags()
return ui.Span(ya.truncate(s, { max = max, rtl = true })):style(THEME.manager.cwd)
return ui.Span(ya.truncate(s, { max = max, rtl = true })):style(th.manager.cwd)
end
function Header:flags()
@ -55,13 +55,13 @@ function Header:count()
local count, style
if yanked == 0 then
count = #self._tab.selected
style = THEME.manager.count_selected
style = th.manager.count_selected
elseif cx.yanked.is_cut then
count = yanked
style = THEME.manager.count_cut
style = th.manager.count_cut
else
count = yanked
style = THEME.manager.count_copied
style = th.manager.count_copied
end
if count == 0 then
@ -83,13 +83,13 @@ function Header:tabs()
local spans = {}
for i = 1, tabs do
local text = i
if THEME.manager.tab_width > 2 then
text = ya.truncate(text .. " " .. cx.tabs[i]:name(), { max = THEME.manager.tab_width })
if th.manager.tab_width > 2 then
text = ya.truncate(text .. " " .. cx.tabs[i]:name(), { max = th.manager.tab_width })
end
if i == cx.tabs.idx then
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(THEME.manager.tab_active)
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(th.manager.tab_active)
else
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(THEME.manager.tab_inactive)
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(th.manager.tab_inactive)
end
end
return ui.Line(spans)

View file

@ -50,16 +50,16 @@ end
function Marker:style(file)
local marked = file:is_marked()
if marked == 1 then
return THEME.manager.marker_marked
return th.manager.marker_marked
elseif marked == 0 and file:is_selected() then
return THEME.manager.marker_selected
return th.manager.marker_selected
end
local yanked = file:is_yanked()
if yanked == 1 then
return THEME.manager.marker_copied
return th.manager.marker_copied
elseif yanked == 2 then
return THEME.manager.marker_cut
return th.manager.marker_cut
end
end

View file

@ -29,9 +29,9 @@ function Progress:redraw()
local gauge = ui.Gauge():area(self._area)
if progress.fail == 0 then
gauge = gauge:gauge_style(THEME.status.progress_normal)
gauge = gauge:gauge_style(th.status.progress_normal)
else
gauge = gauge:gauge_style(THEME.status.progress_error)
gauge = gauge:gauge_style(th.status.progress_error)
end
local percent = 99
@ -43,6 +43,6 @@ function Progress:redraw()
return {
gauge
:percent(percent)
:label(ui.Span(string.format("%3d%%, %d left", percent, left)):style(THEME.status.progress_label)),
:label(ui.Span(string.format("%3d%%, %d left", percent, left)):style(th.status.progress_label)),
}
end

View file

@ -10,8 +10,8 @@ end
function Rail:build()
self._base = {
ui.Bar(ui.Bar.RIGHT):area(self._chunks[1]):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
ui.Bar(ui.Bar.LEFT):area(self._chunks[3]):symbol(THEME.manager.border_symbol):style(THEME.manager.border_style),
ui.Bar(ui.Bar.RIGHT):area(self._chunks[1]):symbol(th.manager.border_symbol):style(th.manager.border_style),
ui.Bar(ui.Bar.LEFT):area(self._chunks[3]):symbol(th.manager.border_symbol):style(th.manager.border_style),
}
self._children = {
Marker:new(self._chunks[1], self._tab.parent),

View file

@ -25,7 +25,7 @@ function Status:new(area, tab)
end
function Status:style()
local m = THEME.mode
local m = th.mode
if self._tab.mode.is_select then
return { main = m.select_main, alt = m.select_alt }
elseif self._tab.mode.is_unset then
@ -40,9 +40,9 @@ function Status:mode()
local style = self:style()
return ui.Line {
ui.Span(THEME.status.sep_left.open):fg(style.main.bg):bg("reset"),
ui.Span(th.status.sep_left.open):fg(style.main.bg):bg("reset"),
ui.Span(" " .. mode .. " "):style(style.main),
ui.Span(THEME.status.sep_left.close):fg(style.main.bg):bg(style.alt.bg),
ui.Span(th.status.sep_left.close):fg(style.main.bg):bg(style.alt.bg),
}
end
@ -55,7 +55,7 @@ function Status:size()
local style = self:style()
return ui.Line {
ui.Span(" " .. ya.readable_size(h:size() or h.cha.len) .. " "):style(style.alt),
ui.Span(THEME.status.sep_left.close):fg(style.alt.bg),
ui.Span(th.status.sep_left.close):fg(style.alt.bg),
}
end
@ -82,15 +82,15 @@ function Status:perm()
local spans = {}
for i = 1, #perm do
local c = perm:sub(i, i)
local style = THEME.status.perm_type
local style = th.status.perm_type
if c == "-" or c == "?" then
style = THEME.status.perm_sep
style = th.status.perm_sep
elseif c == "r" then
style = THEME.status.perm_read
style = th.status.perm_read
elseif c == "w" then
style = THEME.status.perm_write
style = th.status.perm_write
elseif c == "x" or c == "s" or c == "S" or c == "t" or c == "T" then
style = THEME.status.perm_exec
style = th.status.perm_exec
end
spans[i] = ui.Span(c):style(style)
end
@ -115,7 +115,7 @@ function Status:percent()
local style = self:style()
return ui.Line {
ui.Span(" " .. THEME.status.sep_right.open):fg(style.alt.bg),
ui.Span(" " .. th.status.sep_right.open):fg(style.alt.bg),
ui.Span(percent):style(style.alt),
}
end
@ -126,9 +126,9 @@ function Status:position()
local style = self:style()
return ui.Line {
ui.Span(THEME.status.sep_right.open):fg(style.main.bg):bg(style.alt.bg),
ui.Span(th.status.sep_right.open):fg(style.main.bg):bg(style.alt.bg),
ui.Span(string.format(" %2d/%-2d ", math.min(cursor + 1, length), length)):style(style.main),
ui.Span(THEME.status.sep_right.close):fg(style.main.bg):bg("reset"),
ui.Span(th.status.sep_right.close):fg(style.main.bg):bg("reset"),
}
end
@ -141,7 +141,7 @@ function Status:redraw()
local right_width = right:width()
return {
ui.Text(""):area(self._area):style(THEME.status.overall),
ui.Text(""):area(self._area):style(th.status.overall),
ui.Text(left):area(self._area),
ui.Text(right):area(self._area):align(ui.Text.RIGHT),
table.unpack(ya.redraw_with(Progress:new(self._area, right_width))),

View file

@ -10,12 +10,13 @@ function Tab:new(area, tab)
end
function Tab:layout()
local ratio = cf.manager.ratio
self._chunks = ui.Layout()
:direction(ui.Layout.HORIZONTAL)
:constraints({
ui.Constraint.Ratio(MANAGER.ratio.parent, MANAGER.ratio.all),
ui.Constraint.Ratio(MANAGER.ratio.current, MANAGER.ratio.all),
ui.Constraint.Ratio(MANAGER.ratio.preview, MANAGER.ratio.all),
ui.Constraint.Ratio(ratio.parent, ratio.all),
ui.Constraint.Ratio(ratio.current, ratio.all),
ui.Constraint.Ratio(ratio.preview, ratio.all),
})
:split(self._area)
end

View file

@ -31,10 +31,10 @@ end
function M:spot_base(job)
local url, cha = job.file.url, job.file.cha
local spotter = PLUGIN.spotter(url, job.mime)
local previewer = PLUGIN.previewer(url, job.mime)
local fetchers = PLUGIN.fetchers(job.file, job.mime)
local preloaders = PLUGIN.preloaders(url, job.mime)
local spotter = cf.plugin.spotter(url, job.mime)
local previewer = cf.plugin.previewer(url, job.mime)
local fetchers = cf.plugin.fetchers(job.file, job.mime)
local preloaders = cf.plugin.preloaders(url, job.mime)
for i, v in ipairs(fetchers) do
fetchers[i] = v.cmd

View file

@ -13,7 +13,7 @@ function M:peek(job)
return
end
ya.sleep(math.max(0, PREVIEW.image_delay / 1000 + start - os.clock()))
ya.sleep(math.max(0, cf.preview.image_delay / 1000 + start - os.clock()))
ya.image_show(cache, job.area)
ya.preview_widgets(job, {})
end

View file

@ -6,7 +6,7 @@ function M:peek(job)
url = job.file.url
end
ya.sleep(math.max(0, PREVIEW.image_delay / 1000 + start - os.clock()))
ya.sleep(math.max(0, cf.preview.image_delay / 1000 + start - os.clock()))
ya.image_show(url, job.area)
ya.preview_widgets(job, {})
end

View file

@ -31,9 +31,9 @@ function M:peek(job)
if job.skip > 0 and i < job.skip + limit then
ya.manager_emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true })
else
lines = lines:gsub("\t", string.rep(" ", PREVIEW.tab_size))
lines = lines:gsub("\t", string.rep(" ", cf.preview.tab_size))
ya.preview_widgets(job, {
ui.Text.parse(lines):area(job.area):wrap(PREVIEW.wrap == "yes" and ui.Text.WRAP or ui.Text.WRAP_NO),
ui.Text.parse(lines):area(job.area):wrap(cf.preview.wrap == "yes" and ui.Text.WRAP or ui.Text.WRAP_NO),
})
end
end

View file

@ -11,7 +11,7 @@ function M:peek(job)
return
end
ya.sleep(math.max(0, PREVIEW.image_delay / 1000 + start - os.clock()))
ya.sleep(math.max(0, cf.preview.image_delay / 1000 + start - os.clock()))
ya.image_show(cache, job.area)
ya.preview_widgets(job, {})
end
@ -31,9 +31,9 @@ function M:preload(job)
tostring(job.file.url),
"-flatten",
"-resize",
string.format("%dx%d^", PREVIEW.max_width, PREVIEW.max_height),
string.format("%dx%d^", cf.preview.max_width, cf.preview.max_height),
"-quality",
PREVIEW.image_quality,
cf.preview.image_quality,
"-auto-orient",
"JPG:" .. tostring(cache),
})

View file

@ -11,7 +11,7 @@ function M:peek(job)
return
end
ya.sleep(math.max(0, PREVIEW.image_delay / 1000 + start - os.clock()))
ya.sleep(math.max(0, cf.preview.image_delay / 1000 + start - os.clock()))
ya.image_show(cache, job.area)
ya.preview_widgets(job, {})
end
@ -36,8 +36,8 @@ function M:preload(job)
"-f", job.skip + 1,
"-l", job.skip + 1,
"-singlefile",
"-jpeg", "-jpegopt", "quality=" .. PREVIEW.image_quality,
"-scale-to-x", PREVIEW.max_width, "-scale-to-y", "-1",
"-jpeg", "-jpegopt", "quality=" .. cf.preview.image_quality,
"-scale-to-x", cf.preview.max_width, "-scale-to-y", "-1",
tostring(job.file.url),
tostring(cache),
})

View file

@ -11,7 +11,7 @@ function M:peek(job)
return
end
ya.sleep(math.max(0, PREVIEW.image_delay / 1000 + start - os.clock()))
ya.sleep(math.max(0, cf.preview.image_delay / 1000 + start - os.clock()))
ya.image_show(cache, job.area)
ya.preview_widgets(job, {})
end
@ -51,7 +51,7 @@ function M:preload(job)
end
local ss = math.floor(meta.format.duration * percent / 100)
local qv = 31 - math.floor(PREVIEW.image_quality * 0.3)
local qv = 31 - math.floor(cf.preview.image_quality * 0.3)
-- stylua: ignore
local status, err = Command("ffmpeg"):args({
"-v", "quiet", "-threads", 1, "-hwaccel", "auto",
@ -60,7 +60,7 @@ function M:preload(job)
"-i", tostring(job.file.url),
"-vframes", 1,
"-q:v", qv,
"-vf", string.format("scale=-1:'min(%d,ih)':flags=fast_bilinear", PREVIEW.max_height),
"-vf", string.format("scale=-1:'min(%d,ih)':flags=fast_bilinear", cf.preview.max_height),
"-f", "image2",
"-y", tostring(cache),
}):status()

View file

@ -1,11 +1,9 @@
use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value};
use yazi_boot::BOOT;
use yazi_config::{MANAGER, PREVIEW, THEME};
use super::Plugin;
use crate::Composer;
pub const SER_OPTS: SerializeOptions =
pub const OPTS: SerializeOptions =
SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false);
pub struct Config<'a> {
@ -13,42 +11,62 @@ pub struct Config<'a> {
}
impl<'a> Config<'a> {
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
Composer::make(lua, 5, |lua, key| {
match key {
b"manager" => Self::manager(lua)?,
b"plugin" => super::Plugin::compose(lua)?,
b"preview" => Self::preview(lua)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})
}
fn manager(lua: &Lua) -> mlua::Result<Value> {
Composer::make(lua, 5, |lua, key| {
match key {
b"ratio" => lua.to_value_with(&MANAGER.ratio, OPTS)?,
b"show_symlink" => lua.to_value_with(&MANAGER.show_symlink, OPTS)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})
}
fn preview(lua: &Lua) -> mlua::Result<Value> {
Composer::make(lua, 10, |lua, key| {
match key {
b"wrap" => lua.to_value_with(&PREVIEW.wrap, OPTS)?,
b"tab_size" => lua.to_value_with(&PREVIEW.tab_size, OPTS)?,
b"max_width" => lua.to_value_with(&PREVIEW.max_width, OPTS)?,
b"max_height" => lua.to_value_with(&PREVIEW.max_height, OPTS)?,
b"image_delay" => lua.to_value_with(&PREVIEW.image_delay, OPTS)?,
b"image_quality" => lua.to_value_with(&PREVIEW.image_quality, OPTS)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})
}
pub fn new(lua: &'a Lua) -> Self { Self { lua } }
pub fn install_boot(self) -> mlua::Result<Self> {
self.lua.globals().raw_set("BOOT", self.lua.to_value_with(&*BOOT, SER_OPTS)?)?;
Ok(self)
}
// TODO: remove this
pub fn install_manager(self) -> mlua::Result<Self> {
self.lua.globals().raw_set("MANAGER", self.lua.to_value_with(&*MANAGER, SER_OPTS)?)?;
self.lua.globals().raw_set("MANAGER", self.lua.to_value_with(&*MANAGER, OPTS)?)?;
Ok(self)
}
// TODO: remove this
pub fn install_theme(self) -> mlua::Result<Self> {
self.lua.globals().raw_set("THEME", self.lua.to_value_with(&*THEME, SER_OPTS)?)?;
self.lua.globals().raw_set("THEME", self.lua.to_value_with(&*THEME, OPTS)?)?;
Ok(self)
}
// TODO: remove this
pub fn install_preview(self) -> mlua::Result<Self> {
self.lua.globals().raw_set("PREVIEW", self.lua.to_value_with(&*PREVIEW, SER_OPTS)?)?;
Ok(self)
}
pub fn install_plugin(self) -> mlua::Result<Self> {
self.lua.globals().raw_set(
"PLUGIN",
Composer::make(self.lua, 5, |lua, name| {
match name {
b"fetchers" => Plugin::fetchers(lua)?,
b"spotter" => Plugin::spotter(lua)?,
b"preloaders" => Plugin::preloaders(lua)?,
b"previewer" => Plugin::previewer(lua)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})?,
)?;
self.lua.globals().raw_set("PREVIEW", self.lua.to_value_with(&*PREVIEW, OPTS)?)?;
Ok(self)
}
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(config plugin);
yazi_macro::mod_flat!(config plugin theme);

View file

@ -1,30 +1,43 @@
use mlua::{Function, Lua, UserData};
use mlua::{Function, IntoLua, Lua, UserData, Value};
use yazi_config::PLUGIN;
use crate::{file::FileRef, url::UrlRef};
use crate::{Composer, file::FileRef, url::UrlRef};
pub(super) struct Plugin;
impl Plugin {
pub(super) fn fetchers(lua: &Lua) -> mlua::Result<Function> {
pub(super) fn compose(lua: &Lua) -> mlua::Result<Value> {
Composer::make(lua, 5, |lua, key| {
match key {
b"fetchers" => Plugin::fetchers(lua)?,
b"spotter" => Plugin::spotter(lua)?,
b"preloaders" => Plugin::preloaders(lua)?,
b"previewer" => Plugin::previewer(lua)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})
}
fn fetchers(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|lua, (file, mime): (FileRef, mlua::String)| {
lua.create_sequence_from(PLUGIN.fetchers(&file.url, &mime.to_str()?).map(Fetcher))
})
}
pub(super) fn spotter(lua: &Lua) -> mlua::Result<Function> {
fn spotter(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| {
Ok(PLUGIN.spotter(&url, &mime.to_str()?).map(Spotter))
})
}
pub(super) fn preloaders(lua: &Lua) -> mlua::Result<Function> {
fn preloaders(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|lua, (url, mime): (UrlRef, mlua::String)| {
lua.create_sequence_from(PLUGIN.preloaders(&url, &mime.to_str()?).map(Preloader))
})
}
pub(super) fn previewer(lua: &Lua) -> mlua::Result<Function> {
fn previewer(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| {
Ok(PLUGIN.previewer(&url, &mime.to_str()?).map(Previewer))
})

View file

@ -0,0 +1,22 @@
use mlua::{IntoLua, Lua, LuaSerdeExt, Value};
use yazi_config::THEME;
use super::OPTS;
use crate::Composer;
pub struct Theme;
impl Theme {
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
Composer::make(lua, 5, |lua, key| {
match key {
b"manager" => lua.to_value_with(&THEME.manager, OPTS)?,
b"mode" => lua.to_value_with(&THEME.mode, OPTS)?,
b"status" => lua.to_value_with(&THEME.status, OPTS)?,
b"spot" => lua.to_value_with(&THEME.spot, OPTS)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
})
}
}

View file

@ -6,13 +6,15 @@ use crate::runtime::Runtime;
pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
let lua = Lua::new();
lua.set_named_registry_value("rt", Runtime::new(name))?;
crate::config::Config::new(&lua).install_preview()?.install_plugin()?;
crate::config::Config::new(&lua).install_preview()?;
// Base
let globals = lua.globals();
globals.raw_set("ui", crate::elements::compose(&lua)?)?;
globals.raw_set("ya", crate::utils::compose(&lua, true)?)?;
globals.raw_set("fs", crate::fs::compose(&lua)?)?;
globals.raw_set("cf", crate::config::Config::compose(&lua)?)?;
globals.raw_set("th", crate::config::Theme::compose(&lua)?)?;
crate::bindings::Cha::install(&lua)?;
crate::file::pour(&lua)?;

View file

@ -18,7 +18,7 @@ pub(super) fn init_lua() -> Result<()> {
fn stage_1(lua: &'static Lua) -> Result<()> {
lua.set_named_registry_value("rt", Runtime::default())?;
crate::config::Config::new(lua).install_boot()?.install_manager()?.install_theme()?;
crate::config::Config::new(lua).install_manager()?.install_theme()?;
// Base
let globals = lua.globals();
@ -26,6 +26,8 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
globals.raw_set("ya", crate::utils::compose(lua, false)?)?;
globals.raw_set("fs", crate::fs::compose(lua)?)?;
globals.raw_set("ps", crate::pubsub::compose(lua)?)?;
globals.raw_set("cf", crate::config::Config::compose(lua)?)?;
globals.raw_set("th", crate::config::Theme::compose(lua)?)?;
crate::Error::install(lua)?;
crate::bindings::Cha::install(lua)?;

View file

@ -1,7 +1,7 @@
use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value};
use super::Utils;
use crate::{Error, config::SER_OPTS};
use crate::{Error, config::OPTS};
impl Utils {
pub(super) fn json_encode(lua: &Lua) -> mlua::Result<Function> {
@ -16,7 +16,7 @@ impl Utils {
pub(super) fn json_decode(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, s: mlua::String| async move {
match serde_json::from_slice::<serde_json::Value>(&s.as_bytes()) {
Ok(v) => (lua.to_value_with(&v, SER_OPTS)?, Value::Nil).into_lua_multi(&lua),
Ok(v) => (lua.to_value_with(&v, OPTS)?, Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Serde(e)).into_lua_multi(&lua),
}
})

View file

@ -8,7 +8,6 @@ pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result<Value> {
Composer::make(lua, 40, move |lua, key| {
match key {
// App
b"__250127" => Utils::hide(lua)?, // TODO: remove this
b"hide" => Utils::hide(lua)?,
// Cache

View file

@ -169,7 +169,6 @@ impl Display for Cmd {
impl FromStr for Cmd {
type Err = anyhow::Error;
#[allow(clippy::explicit_counter_loop)]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut args = crate::shell::split_unix(s)?;
if args.is_empty() || args[0].is_empty() {