From 452b435b719bd6f131eb032d1aab7c06809a2868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Tue, 8 Jul 2025 23:59:50 +0800 Subject: [PATCH] feat: allow dynamic adjustment of layout ratio via `rt.mgr.ratio` (#2964) --- Cargo.lock | 13 +- yazi-binding/Cargo.toml | 3 +- yazi-binding/src/composer.rs | 65 +++- yazi-binding/src/elements/bar.rs | 9 +- yazi-binding/src/elements/border.rs | 8 +- yazi-binding/src/elements/clear.rs | 8 +- yazi-binding/src/elements/elements.rs | 14 +- yazi-binding/src/elements/gauge.rs | 10 +- yazi-binding/src/elements/line.rs | 9 +- yazi-binding/src/elements/list.rs | 10 +- yazi-binding/src/elements/renderable.rs | 45 ++- yazi-binding/src/elements/table.rs | 8 +- yazi-binding/src/elements/text.rs | 7 +- yazi-config/src/mgr/mgr.rs | 21 +- yazi-config/src/mgr/ratio.rs | 6 +- yazi-config/src/popup/offset.rs | 6 +- yazi-core/src/tab/folder.rs | 6 +- yazi-core/src/tab/preference.rs | 12 +- yazi-core/src/tab/preview.rs | 8 +- yazi-fm/src/app/commands/mouse.rs | 2 +- yazi-fm/src/app/commands/resize.rs | 1 - yazi-fm/src/mgr/preview.rs | 7 +- yazi-fm/src/signals.rs | 2 +- yazi-fm/src/spot/spot.rs | 7 +- yazi-fm/src/term.rs | 6 +- yazi-plugin/src/config/mod.rs | 1 - yazi-plugin/src/config/runtime.rs | 100 ------ yazi-plugin/src/config/term.rs | 25 -- yazi-plugin/src/config/theme.rs | 280 --------------- yazi-plugin/src/fs/fs.rs | 8 +- yazi-plugin/src/isolate/isolate.rs | 4 +- yazi-plugin/src/lib.rs | 2 +- yazi-plugin/src/lua.rs | 4 +- yazi-plugin/src/pubsub/mod.rs | 8 +- yazi-plugin/src/runtime/mod.rs | 1 + yazi-plugin/src/{config => runtime}/plugin.rs | 68 ++-- yazi-plugin/src/runtime/runtime.rs | 127 +++++++ yazi-plugin/src/runtime/term.rs | 27 ++ yazi-plugin/src/theme/mod.rs | 1 + yazi-plugin/src/theme/theme.rs | 334 ++++++++++++++++++ yazi-plugin/src/utils/json.rs | 2 +- yazi-plugin/src/utils/utils.rs | 8 +- yazi-shared/src/sync_cell.rs | 20 ++ 43 files changed, 728 insertions(+), 585 deletions(-) delete mode 100644 yazi-plugin/src/config/mod.rs delete mode 100644 yazi-plugin/src/config/runtime.rs delete mode 100644 yazi-plugin/src/config/term.rs delete mode 100644 yazi-plugin/src/config/theme.rs create mode 100644 yazi-plugin/src/runtime/mod.rs rename yazi-plugin/src/{config => runtime}/plugin.rs (59%) create mode 100644 yazi-plugin/src/runtime/runtime.rs create mode 100644 yazi-plugin/src/runtime/term.rs create mode 100644 yazi-plugin/src/theme/mod.rs create mode 100644 yazi-plugin/src/theme/theme.rs diff --git a/Cargo.lock b/Cargo.lock index d43a550d..951e7f5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1853,9 +1853,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.2" +version = "1.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d77244ce2d584cd84f6a15f86195b8c9b2a0dfbfd817c09e0464244091a58ed" +checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" dependencies = [ "base64", "indexmap", @@ -1972,9 +1972,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.37.5" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +checksum = "8927b0664f5c5a98265138b7e3f90aa19a6b21353182469ace36d4ac527b7b1b" dependencies = [ "memchr", ] @@ -2207,9 +2207,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rgb" -version = "0.8.50" +version = "0.8.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +checksum = "a457e416a0f90d246a4c3288bd7a25b2304ca727f253f95be383dd17af56be8f" [[package]] name = "rustc-demangle" @@ -3456,6 +3456,7 @@ name = "yazi-binding" version = "25.6.11" dependencies = [ "ansi-to-tui", + "foldhash", "mlua", "paste", "ratatui", diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index a6cf4d2f..34814470 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -18,11 +18,12 @@ yazi-shared = { path = "../yazi-shared", version = "25.6.11" } # External dependencies ansi-to-tui = { workspace = true } +foldhash = { workspace = true } mlua = { workspace = true } paste = { workspace = true } ratatui = { workspace = true } serde_json = { workspace = true } -tokio = { workspace = true } +tokio = { workspace = true } unicode-width = { workspace = true } # Logging diff --git a/yazi-binding/src/composer.rs b/yazi-binding/src/composer.rs index 70c76f1b..456cf2e8 100644 --- a/yazi-binding/src/composer.rs +++ b/yazi-binding/src/composer.rs @@ -1,20 +1,53 @@ -use mlua::{IntoLua, Lua, MetaMethod, Table, Value}; +use foldhash::HashMap; +use mlua::{IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Value}; -pub struct Composer; +pub struct Composer { + get: G, + set: S, + cache: HashMap, Value>, +} -impl Composer { - pub fn make(lua: &Lua, f: F) -> mlua::Result - where - F: Fn(&Lua, &[u8]) -> mlua::Result + 'static, - { - let index = lua.create_function(move |lua, (ts, key): (Table, mlua::String)| { - let v = f(lua, &key.as_bytes())?; - ts.raw_set(key, v.clone())?; - Ok(v) - })?; - - let tbl = lua.create_table()?; - tbl.set_metatable(Some(lua.create_table_from([(MetaMethod::Index.name(), index)])?)); - tbl.into_lua(lua) +impl Composer +where + G: Fn(&Lua, &[u8]) -> mlua::Result + 'static, + S: Fn(&Lua, &[u8], Value) -> mlua::Result + 'static, +{ + pub fn make(lua: &Lua, get: G, set: S) -> mlua::Result { + Self { get, set, cache: Default::default() }.into_lua(lua) + } +} + +impl UserData for Composer +where + G: Fn(&Lua, &[u8]) -> mlua::Result + 'static, + S: Fn(&Lua, &[u8], Value) -> mlua::Result + 'static, +{ + fn add_methods>(methods: &mut M) { + methods.add_meta_method_mut(MetaMethod::Index, |lua, me, key: mlua::String| { + let key = key.as_bytes(); + if let Some(v) = me.cache.get(key.as_ref()) { + return Ok(v.clone()); + } + + let v = (me.get)(lua, &key)?; + me.cache.insert(key.to_owned(), v.clone()); + Ok(v) + }); + + methods.add_meta_method_mut( + MetaMethod::NewIndex, + |lua, me, (key, value): (mlua::String, Value)| { + let key = key.as_bytes(); + + let value = (me.set)(lua, key.as_ref(), value)?; + if value.is_nil() { + me.cache.remove(key.as_ref()); + } else { + me.cache.insert(key.to_owned(), value); + } + + Ok(()) + }, + ); } } diff --git a/yazi-binding/src/elements/bar.rs b/yazi-binding/src/elements/bar.rs index 97dd3425..634c9f87 100644 --- a/yazi-binding/src/elements/bar.rs +++ b/yazi-binding/src/elements/bar.rs @@ -5,7 +5,7 @@ use super::{Area, Edge}; #[derive(Clone, Debug, Default)] pub struct Bar { - area: Area, + pub(super) area: Area, edge: Edge, symbol: String, @@ -22,12 +22,7 @@ impl Bar { bar.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { - let rect = self.area.transform(trans); + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { if rect.area() == 0 { return; } diff --git a/yazi-binding/src/elements/border.rs b/yazi-binding/src/elements/border.rs index 1c3324aa..97e49940 100644 --- a/yazi-binding/src/elements/border.rs +++ b/yazi-binding/src/elements/border.rs @@ -42,11 +42,7 @@ impl Border { border.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { let mut block = ratatui::widgets::Block::default() .borders(self.edge.0) .border_type(self.r#type) @@ -59,7 +55,7 @@ impl Border { }; } - block.render(self.area.transform(trans), buf); + block.render(rect, buf); } } diff --git a/yazi-binding/src/elements/clear.rs b/yazi-binding/src/elements/clear.rs index 1de82560..d917cade 100644 --- a/yazi-binding/src/elements/clear.rs +++ b/yazi-binding/src/elements/clear.rs @@ -22,12 +22,8 @@ impl Clear { clear.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { - ::render(Default::default(), self.area.transform(trans), buf); + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { + ::render(Default::default(), rect, buf); } } diff --git a/yazi-binding/src/elements/elements.rs b/yazi-binding/src/elements/elements.rs index 25c10674..814dcb94 100644 --- a/yazi-binding/src/elements/elements.rs +++ b/yazi-binding/src/elements/elements.rs @@ -5,7 +5,7 @@ use super::Renderable; use crate::Composer; pub fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { match key { b"Align" => super::Align::compose(lua)?, b"Bar" => super::Bar::compose(lua)?, @@ -36,12 +36,16 @@ pub fn compose(lua: &Lua) -> mlua::Result { _ => return Ok(Value::Nil), } .into_lua(lua) - }) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) } pub fn render_once(value: Value, buf: &mut ratatui::buffer::Buffer, trans: F) where - F: Fn(yazi_config::popup::Position) -> ratatui::layout::Rect + Copy, + F: FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect + Copy, { match value { Value::Table(tbl) => { @@ -52,13 +56,13 @@ where }; match Renderable::try_from(widget) { - Ok(w) => w.render(buf, trans), + Ok(w) => w.render_with(buf, trans), Err(e) => error!("{e}"), } } } Value::UserData(ud) => match Renderable::try_from(ud) { - Ok(w) => w.render(buf, trans), + Ok(w) => w.render_with(buf, trans), Err(e) => error!("{e}"), }, _ => error!("Expected a renderable UserData, or a table of them, got: {value:?}"), diff --git a/yazi-binding/src/elements/gauge.rs b/yazi-binding/src/elements/gauge.rs index 13aabaa6..b1bdbb0f 100644 --- a/yazi-binding/src/elements/gauge.rs +++ b/yazi-binding/src/elements/gauge.rs @@ -6,7 +6,7 @@ use crate::Style; #[derive(Clone, Debug, Default)] pub struct Gauge { - area: Area, + pub(super) area: Area, ratio: f64, label: Option>, @@ -24,11 +24,7 @@ impl Gauge { gauge.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { let mut gauge = ratatui::widgets::Gauge::default() .ratio(self.ratio) .style(self.style) @@ -38,7 +34,7 @@ impl Gauge { gauge = gauge.label(s) } - gauge.render(self.area.transform(trans), buf); + gauge.render(rect, buf); } } diff --git a/yazi-binding/src/elements/line.rs b/yazi-binding/src/elements/line.rs index ec6287d4..d584d302 100644 --- a/yazi-binding/src/elements/line.rs +++ b/yazi-binding/src/elements/line.rs @@ -12,7 +12,7 @@ const EXPECTED: &str = "expected a string, Span, Line, or a table of them"; #[derive(Clone, Debug, Default)] pub struct Line { - area: Area, + pub(super) area: Area, pub(super) inner: ratatui::text::Line<'static>, } @@ -40,12 +40,7 @@ impl Line { line.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl Fn(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { - let rect = self.area.transform(trans); + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { self.inner.render(rect, buf); } } diff --git a/yazi-binding/src/elements/list.rs b/yazi-binding/src/elements/list.rs index 5fa9612d..72b8e157 100644 --- a/yazi-binding/src/elements/list.rs +++ b/yazi-binding/src/elements/list.rs @@ -8,7 +8,7 @@ const EXPECTED: &str = "expected a table of strings, Texts, Lines or Spans"; // --- List #[derive(Clone, Debug, Default)] pub struct List { - area: Area, + pub(super) area: Area, inner: ratatui::widgets::List<'static>, } @@ -30,12 +30,8 @@ impl List { list.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { - self.inner.render(self.area.transform(trans), buf); + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { + self.inner.render(rect, buf); } } diff --git a/yazi-binding/src/elements/renderable.rs b/yazi-binding/src/elements/renderable.rs index 0f86bb8b..aac9882c 100644 --- a/yazi-binding/src/elements/renderable.rs +++ b/yazi-binding/src/elements/renderable.rs @@ -3,7 +3,7 @@ use std::any::TypeId; use mlua::{AnyUserData, ExternalError}; use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text}; -use crate::{Error, elements::Rect}; +use crate::{Error, elements::{Area, Rect}}; #[derive(Clone, Debug)] pub enum Renderable { @@ -18,22 +18,39 @@ pub enum Renderable { } impl Renderable { - pub fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl Fn(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { + pub fn area(&self) -> Area { match self { - Self::Line(line) => line.render(buf, trans), - Self::Text(text) => text.render(buf, trans), - Self::List(list) => list.render(buf, trans), - Self::Bar(bar) => bar.render(buf, trans), - Self::Clear(clear) => clear.render(buf, trans), - Self::Border(border) => border.render(buf, trans), - Self::Gauge(gauge) => gauge.render(buf, trans), - Self::Table(table) => table.render(buf, trans), + Self::Line(line) => line.area, + Self::Text(text) => text.area, + Self::List(list) => list.area, + Self::Bar(bar) => bar.area, + Self::Clear(clear) => clear.area, + Self::Border(border) => border.area, + Self::Gauge(gauge) => gauge.area, + Self::Table(table) => table.area, } } + + pub fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { + match self { + Self::Line(line) => line.render(rect, buf), + Self::Text(text) => text.render(rect, buf), + Self::List(list) => list.render(rect, buf), + Self::Bar(bar) => bar.render(rect, buf), + Self::Clear(clear) => clear.render(rect, buf), + Self::Border(border) => border.render(rect, buf), + Self::Gauge(gauge) => gauge.render(rect, buf), + Self::Table(table) => table.render(rect, buf), + } + } + + pub fn render_with(self, buf: &mut ratatui::buffer::Buffer, trans: T) + where + T: FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, + { + let rect = self.area().transform(trans); + self.render(rect, buf); + } } impl TryFrom<&AnyUserData> for Renderable { diff --git a/yazi-binding/src/elements/table.rs b/yazi-binding/src/elements/table.rs index f96dcb0f..2160692b 100644 --- a/yazi-binding/src/elements/table.rs +++ b/yazi-binding/src/elements/table.rs @@ -54,11 +54,7 @@ impl Table { if row.cells.is_empty() { None } else { Some(&row.cells[col.min(row.cells.len() - 1)].text) } } - pub(super) fn render( - mut self, - buf: &mut ratatui::buffer::Buffer, - trans: impl FnOnce(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { + pub(super) fn render(mut self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { let mut table = ratatui::widgets::Table::new(self.rows, self.widths) .column_spacing(self.column_spacing) .style(self.style) @@ -79,7 +75,7 @@ impl Table { table = table.block(block); } - table.render(self.area.transform(trans), buf, &mut self.state); + table.render(rect, buf, &mut self.state); } #[inline] diff --git a/yazi-binding/src/elements/text.rs b/yazi-binding/src/elements/text.rs index c96e0d57..73e921db 100644 --- a/yazi-binding/src/elements/text.rs +++ b/yazi-binding/src/elements/text.rs @@ -32,12 +32,7 @@ impl Text { text.into_lua(lua) } - pub(super) fn render( - self, - buf: &mut ratatui::buffer::Buffer, - trans: impl Fn(yazi_config::popup::Position) -> ratatui::layout::Rect, - ) { - let rect = self.area.transform(trans); + pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) { if self.wrap.is_none() && self.scroll == Default::default() { self.inner.render(rect, buf); } else { diff --git a/yazi-config/src/mgr/mgr.rs b/yazi-config/src/mgr/mgr.rs index 32c1cc5b..2277a934 100644 --- a/yazi-config/src/mgr/mgr.rs +++ b/yazi-config/src/mgr/mgr.rs @@ -2,26 +2,27 @@ use anyhow::{Result, bail}; use serde::Deserialize; use yazi_codegen::DeserializeOver2; use yazi_fs::{CWD, SortBy}; +use yazi_shared::SyncCell; use super::{MgrRatio, MouseEvents}; #[derive(Debug, Deserialize, DeserializeOver2)] pub struct Mgr { - pub ratio: MgrRatio, + pub ratio: SyncCell, // Sorting - pub sort_by: SortBy, - pub sort_sensitive: bool, - pub sort_reverse: bool, - pub sort_dir_first: bool, - pub sort_translit: bool, + pub sort_by: SyncCell, + pub sort_sensitive: SyncCell, + pub sort_reverse: SyncCell, + pub sort_dir_first: SyncCell, + pub sort_translit: SyncCell, // Display pub linemode: String, - pub show_hidden: bool, - pub show_symlink: bool, - pub scrolloff: u8, - pub mouse_events: MouseEvents, + pub show_hidden: SyncCell, + pub show_symlink: SyncCell, + pub scrolloff: SyncCell, + pub mouse_events: SyncCell, pub title_format: String, } diff --git a/yazi-config/src/mgr/ratio.rs b/yazi-config/src/mgr/ratio.rs index e28391e1..c27c50f8 100644 --- a/yazi-config/src/mgr/ratio.rs +++ b/yazi-config/src/mgr/ratio.rs @@ -2,7 +2,7 @@ use anyhow::bail; use serde::{Deserialize, Serialize}; #[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] -#[serde(try_from = "Vec")] +#[serde(try_from = "[u16; 3]")] pub struct MgrRatio { pub parent: u16, pub current: u16, @@ -10,10 +10,10 @@ pub struct MgrRatio { pub all: u16, } -impl TryFrom> for MgrRatio { +impl TryFrom<[u16; 3]> for MgrRatio { type Error = anyhow::Error; - fn try_from(ratio: Vec) -> Result { + fn try_from(ratio: [u16; 3]) -> Result { if ratio.len() != 3 { bail!("invalid layout ratio: {:?}", ratio); } diff --git a/yazi-config/src/popup/offset.rs b/yazi-config/src/popup/offset.rs index c81e5ddd..23c4be2c 100644 --- a/yazi-config/src/popup/offset.rs +++ b/yazi-config/src/popup/offset.rs @@ -2,7 +2,7 @@ use anyhow::bail; use serde::Deserialize; #[derive(Clone, Copy, Debug, Default, Deserialize)] -#[serde(try_from = "Vec")] +#[serde(try_from = "[i16; 4]")] pub struct Offset { pub x: i16, pub y: i16, @@ -10,10 +10,10 @@ pub struct Offset { pub height: u16, } -impl TryFrom> for Offset { +impl TryFrom<[i16; 4]> for Offset { type Error = anyhow::Error; - fn try_from(values: Vec) -> Result { + fn try_from(values: [i16; 4]) -> Result { if values.len() != 4 { bail!("offset must have 4 values: {:?}", values); } diff --git a/yazi-core/src/tab/folder.rs b/yazi-core/src/tab/folder.rs index 89218798..a228d7be 100644 --- a/yazi-core/src/tab/folder.rs +++ b/yazi-core/src/tab/folder.rs @@ -26,7 +26,7 @@ impl Default for Folder { Self { url: Default::default(), cha: Default::default(), - files: Files::new(YAZI.mgr.show_hidden), + files: Files::new(YAZI.mgr.show_hidden.get()), stage: Default::default(), offset: Default::default(), cursor: Default::default(), @@ -140,7 +140,7 @@ impl Folder { let len = self.files.len(); let limit = LAYOUT.get().limit(); - let scrolloff = (limit / 2).min(YAZI.mgr.scrolloff as usize); + let scrolloff = (limit / 2).min(YAZI.mgr.scrolloff.get() as usize); self.offset = if self.cursor < (self.offset + limit).min(len).saturating_sub(scrolloff) { len.saturating_sub(limit).min(self.offset) @@ -174,7 +174,7 @@ impl Scrollable for Folder { fn limit(&self) -> usize { LAYOUT.get().limit() } #[inline] - fn scrolloff(&self) -> usize { (self.limit() / 2).min(YAZI.mgr.scrolloff as usize) } + fn scrolloff(&self) -> usize { (self.limit() / 2).min(YAZI.mgr.scrolloff.get() as usize) } #[inline] fn cursor_mut(&mut self) -> &mut usize { &mut self.cursor } diff --git a/yazi-core/src/tab/preference.rs b/yazi-core/src/tab/preference.rs index cf040666..5297582b 100644 --- a/yazi-core/src/tab/preference.rs +++ b/yazi-core/src/tab/preference.rs @@ -19,15 +19,15 @@ impl Default for Preference { fn default() -> Self { Self { // Sorting - sort_by: YAZI.mgr.sort_by, - sort_sensitive: YAZI.mgr.sort_sensitive, - sort_reverse: YAZI.mgr.sort_reverse, - sort_dir_first: YAZI.mgr.sort_dir_first, - sort_translit: YAZI.mgr.sort_translit, + sort_by: YAZI.mgr.sort_by.get(), + sort_sensitive: YAZI.mgr.sort_sensitive.get(), + sort_reverse: YAZI.mgr.sort_reverse.get(), + sort_dir_first: YAZI.mgr.sort_dir_first.get(), + sort_translit: YAZI.mgr.sort_translit.get(), // Display linemode: YAZI.mgr.linemode.to_owned(), - show_hidden: YAZI.mgr.show_hidden, + show_hidden: YAZI.mgr.show_hidden.get(), } } } diff --git a/yazi-core/src/tab/preview.rs b/yazi-core/src/tab/preview.rs index d9100a58..ddf4952c 100644 --- a/yazi-core/src/tab/preview.rs +++ b/yazi-core/src/tab/preview.rs @@ -4,7 +4,7 @@ use tokio::{pin, task::JoinHandle}; use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream}; use tokio_util::sync::CancellationToken; use yazi_adapter::ADAPTOR; -use yazi_config::YAZI; +use yazi_config::{LAYOUT, YAZI}; use yazi_fs::{File, Files, FilesOp, cha::Cha}; use yazi_macro::render; use yazi_parser::tab::PreviewLock; @@ -88,16 +88,16 @@ impl Preview { } #[inline] - pub fn same_url(&self, url: &Url) -> bool { self.lock.as_ref().is_some_and(|l| *url == l.url) } + pub fn same_url(&self, url: &Url) -> bool { matches!(&self.lock, Some(l) if l.url == *url) } #[inline] pub fn same_file(&self, file: &File, mime: &str) -> bool { self.same_url(&file.url) - && self.lock.as_ref().is_some_and(|l| file.cha.hits(l.cha) && mime == l.mime) + && matches!(&self.lock , Some(l) if l.cha.hits(file.cha) && l.mime == mime && *l.area == LAYOUT.get().preview) } #[inline] pub fn same_lock(&self, file: &File, mime: &str) -> bool { - self.same_file(file, mime) && self.lock.as_ref().is_some_and(|l| self.skip == l.skip) + self.same_file(file, mime) && matches!(&self.lock, Some(l) if l.skip == self.skip) } } diff --git a/yazi-fm/src/app/commands/mouse.rs b/yazi-fm/src/app/commands/mouse.rs index 61523f1e..79397f5b 100644 --- a/yazi-fm/src/app/commands/mouse.rs +++ b/yazi-fm/src/app/commands/mouse.rs @@ -24,7 +24,7 @@ impl App { let area = yazi_binding::elements::Rect::from(size); let root = LUA.globals().raw_get::("Root")?.call_method::
("new", area)?; - if matches!(event.kind, MouseEventKind::Down(_) if YAZI.mgr.mouse_events.draggable()) { + if matches!(event.kind, MouseEventKind::Down(_) if YAZI.mgr.mouse_events.get().draggable()) { root.raw_set("_drag_start", event)?; } diff --git a/yazi-fm/src/app/commands/resize.rs b/yazi-fm/src/app/commands/resize.rs index 2d2b2d5a..deb00416 100644 --- a/yazi-fm/src/app/commands/resize.rs +++ b/yazi-fm/src/app/commands/resize.rs @@ -15,7 +15,6 @@ impl From<()> for Opt { impl App { #[yazi_codegen::command] pub fn resize(&mut self, _: Opt) { - self.cx.active_mut().preview.reset(); self.reflow(()); self.cx.current_mut().sync_page(true); diff --git a/yazi-fm/src/mgr/preview.rs b/yazi-fm/src/mgr/preview.rs index b5ce2666..3ef1c419 100644 --- a/yazi-fm/src/mgr/preview.rs +++ b/yazi-fm/src/mgr/preview.rs @@ -13,7 +13,7 @@ impl<'a> Preview<'a> { } impl Widget for Preview<'_> { - fn render(self, _: ratatui::layout::Rect, buf: &mut Buffer) { + fn render(self, win: ratatui::layout::Rect, buf: &mut Buffer) { let Some(lock) = &self.cx.active().preview.lock else { return; }; @@ -23,7 +23,10 @@ impl Widget for Preview<'_> { } for w in &lock.data { - w.clone().render(buf, |p| self.cx.mgr.area(p)); + let rect = w.area().transform(|p| self.cx.mgr.area(p)); + if win.intersects(rect) { + w.clone().render(rect, buf); + } } } } diff --git a/yazi-fm/src/signals.rs b/yazi-fm/src/signals.rs index f01de8a0..84beb91f 100644 --- a/yazi-fm/src/signals.rs +++ b/yazi-fm/src/signals.rs @@ -62,7 +62,7 @@ impl Signals { Event::Key(key).emit() } CrosstermEvent::Mouse(mouse) => { - if YAZI.mgr.mouse_events.contains(mouse.kind.into()) { + if YAZI.mgr.mouse_events.get().contains(mouse.kind.into()) { Event::Mouse(mouse).emit(); } } diff --git a/yazi-fm/src/spot/spot.rs b/yazi-fm/src/spot/spot.rs index 5cf1b776..682c8c0d 100644 --- a/yazi-fm/src/spot/spot.rs +++ b/yazi-fm/src/spot/spot.rs @@ -11,13 +11,16 @@ impl<'a> Spot<'a> { } impl Widget for Spot<'_> { - fn render(self, _: Rect, buf: &mut Buffer) { + fn render(self, win: Rect, buf: &mut Buffer) { let Some(lock) = &self.cx.active().spot.lock else { return; }; for w in &lock.data { - w.clone().render(buf, |p| self.cx.mgr.area(p)); + let rect = w.area().transform(|p| self.cx.mgr.area(p)); + if win.intersects(rect) { + w.clone().render(rect, buf); + } } } } diff --git a/yazi-fm/src/term.rs b/yazi-fm/src/term.rs index 0c25e74d..8c92431c 100644 --- a/yazi-fm/src/term.rs +++ b/yazi-fm/src/term.rs @@ -39,7 +39,7 @@ impl Term { Print(Mux::csi("\x1b[0c")), // Request device attributes yazi_term::If(TMUX.get(), EnterAlternateScreen), EnableBracketedPaste, - yazi_term::If(!YAZI.mgr.mouse_events.is_empty(), EnableMouseCapture), + yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), EnableMouseCapture), )?; let resp = Emulator::read_until_da1(); @@ -76,7 +76,7 @@ impl Term { execute!( TTY.writer(), - yazi_term::If(!YAZI.mgr.mouse_events.is_empty(), DisableMouseCapture), + yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), DisableMouseCapture), yazi_term::RestoreCursor, DisableBracketedPaste, LeaveAlternateScreen, @@ -97,7 +97,7 @@ impl Term { execute!( TTY.writer(), - yazi_term::If(!YAZI.mgr.mouse_events.is_empty(), DisableMouseCapture), + yazi_term::If(!YAZI.mgr.mouse_events.get().is_empty(), DisableMouseCapture), yazi_term::RestoreCursor, DisableBracketedPaste, LeaveAlternateScreen, diff --git a/yazi-plugin/src/config/mod.rs b/yazi-plugin/src/config/mod.rs deleted file mode 100644 index 047fa62e..00000000 --- a/yazi-plugin/src/config/mod.rs +++ /dev/null @@ -1 +0,0 @@ -yazi_macro::mod_flat!(plugin runtime term theme); diff --git a/yazi-plugin/src/config/runtime.rs b/yazi-plugin/src/config/runtime.rs deleted file mode 100644 index 62824938..00000000 --- a/yazi-plugin/src/config/runtime.rs +++ /dev/null @@ -1,100 +0,0 @@ -use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value}; -use yazi_binding::{Composer, Url}; -use yazi_boot::ARGS; -use yazi_config::YAZI; - -pub const OPTS: SerializeOptions = - SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false); - -pub struct Runtime; - -impl Runtime { - pub fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - match key { - b"args" => Self::args(lua)?, - b"term" => super::Term::compose(lua)?, - b"mgr" => Self::mgr(lua)?, - b"plugin" => super::Plugin::compose(lua)?, - b"preview" => Self::preview(lua)?, - b"tasks" => Self::tasks(lua)?, - _ => return Ok(Value::Nil), - } - .into_lua(lua) - }) - } - - fn args(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| match key { - b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::new))?.into_lua(lua), - b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::new).into_lua(lua), - b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::new).into_lua(lua), - _ => Ok(Value::Nil), - }) - } - - fn mgr(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let m = &YAZI.mgr; - match key { - b"ratio" => lua.to_value_with(&m.ratio, OPTS)?, - - b"sort_by" => lua.to_value_with(&m.sort_by, OPTS)?, - b"sort_sensitive" => lua.to_value_with(&m.sort_sensitive, OPTS)?, - b"sort_reverse" => lua.to_value_with(&m.sort_reverse, OPTS)?, - b"sort_dir_first" => lua.to_value_with(&m.sort_dir_first, OPTS)?, - b"sort_translit" => lua.to_value_with(&m.sort_translit, OPTS)?, - - b"linemode" => lua.to_value_with(&m.linemode, OPTS)?, - b"show_hidden" => lua.to_value_with(&m.show_hidden, OPTS)?, - b"show_symlink" => lua.to_value_with(&m.show_symlink, OPTS)?, - b"scrolloff" => lua.to_value_with(&m.scrolloff, OPTS)?, - b"mouse_events" => lua.to_value_with(&m.mouse_events, OPTS)?, - b"title_format" => lua.to_value_with(&m.title_format, OPTS)?, - _ => return Ok(Value::Nil), - } - .into_lua(lua) - }) - } - - fn preview(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let p = &YAZI.preview; - match key { - b"wrap" => lua.to_value_with(&p.wrap, OPTS)?, - b"tab_size" => lua.to_value_with(&p.tab_size, OPTS)?, - b"max_width" => lua.to_value_with(&p.max_width, OPTS)?, - b"max_height" => lua.to_value_with(&p.max_height, OPTS)?, - - b"cache_dir" => lua.to_value_with(&p.cache_dir, OPTS)?, - - b"image_delay" => lua.to_value_with(&p.image_delay, OPTS)?, - b"image_filter" => lua.to_value_with(&p.image_filter, OPTS)?, - b"image_quality" => lua.to_value_with(&p.image_quality, OPTS)?, - - b"ueberzug_scale" => lua.to_value_with(&p.ueberzug_scale, OPTS)?, - b"ueberzug_offset" => lua.to_value_with(&p.ueberzug_offset, OPTS)?, - _ => return Ok(Value::Nil), - } - .into_lua(lua) - }) - } - - fn tasks(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &YAZI.tasks; - match key { - b"micro_workers" => lua.to_value_with(&t.micro_workers, OPTS)?, - b"macro_workers" => lua.to_value_with(&t.macro_workers, OPTS)?, - b"bizarre_retry" => lua.to_value_with(&t.bizarre_retry, OPTS)?, - - b"image_alloc" => lua.to_value_with(&t.image_alloc, OPTS)?, - b"image_bound" => lua.to_value_with(&t.image_bound, OPTS)?, - - b"suppress_preload" => lua.to_value_with(&t.suppress_preload, OPTS)?, - _ => return Ok(Value::Nil), - } - .into_lua(lua) - }) - } -} diff --git a/yazi-plugin/src/config/term.rs b/yazi-plugin/src/config/term.rs deleted file mode 100644 index 766d09f0..00000000 --- a/yazi-plugin/src/config/term.rs +++ /dev/null @@ -1,25 +0,0 @@ -use mlua::{Function, IntoLua, IntoLuaMulti, Lua, Value}; -use yazi_adapter::{Dimension, EMULATOR}; -use yazi_binding::Composer; - -pub(super) struct Term; - -impl Term { - pub(super) fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| match key { - b"light" => EMULATOR.get().light.into_lua(lua), - b"cell_size" => Self::cell_size(lua)?.into_lua(lua), - _ => Ok(Value::Nil), - }) - } - - fn cell_size(lua: &Lua) -> mlua::Result { - lua.create_function(|lua, ()| { - if let Some(s) = Dimension::cell_size() { - s.into_lua_multi(lua) - } else { - ().into_lua_multi(lua) - } - }) - } -} diff --git a/yazi-plugin/src/config/theme.rs b/yazi-plugin/src/config/theme.rs deleted file mode 100644 index 59e02503..00000000 --- a/yazi-plugin/src/config/theme.rs +++ /dev/null @@ -1,280 +0,0 @@ -use mlua::{IntoLua, Lua, Value}; -use yazi_binding::{Composer, Style, Url}; -use yazi_config::THEME; - -pub struct Theme; - -impl Theme { - pub fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| match key { - b"mgr" => Self::mgr(lua), - b"tabs" => Self::tabs(lua), - b"mode" => Self::mode(lua), - b"status" => Self::status(lua), - b"which" => Self::which(lua), - b"confirm" => Self::confirm(lua), - b"spot" => Self::spot(lua), - b"notify" => Self::notify(lua), - b"pick" => Self::pick(lua), - b"input" => Self::input(lua), - b"cmp" => Self::cmp(lua), - b"tasks" => Self::tasks(lua), - b"help" => Self::help(lua), - _ => Ok(Value::Nil), - }) - } - - fn mgr(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let m = &THEME.mgr; - match key { - b"cwd" => Style::from(m.cwd).into_lua(lua), - - b"hovered" => Style::from(m.hovered).into_lua(lua), - b"preview_hovered" => Style::from(m.preview_hovered).into_lua(lua), - - b"find_keyword" => Style::from(m.find_keyword).into_lua(lua), - b"find_position" => Style::from(m.find_position).into_lua(lua), - - b"symlink_target" => Style::from(m.symlink_target).into_lua(lua), - - b"marker_copied" => Style::from(m.marker_copied).into_lua(lua), - b"marker_cut" => Style::from(m.marker_cut).into_lua(lua), - b"marker_marked" => Style::from(m.marker_marked).into_lua(lua), - b"marker_selected" => Style::from(m.marker_selected).into_lua(lua), - - b"count_copied" => Style::from(m.count_copied).into_lua(lua), - b"count_cut" => Style::from(m.count_cut).into_lua(lua), - b"count_selected" => Style::from(m.count_selected).into_lua(lua), - - b"border_symbol" => lua.create_string(&m.border_symbol)?.into_lua(lua), - b"border_style" => Style::from(m.border_style).into_lua(lua), - - b"syntect_theme" => Url::new(&m.syntect_theme).into_lua(lua), - _ => Ok(Value::Nil), - } - }) - } - - fn tabs(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.tabs; - match key { - b"active" => Style::from(t.active).into_lua(lua), - b"inactive" => Style::from(t.inactive).into_lua(lua), - - b"sep_inner" => lua - .create_table_from([ - ("open", lua.create_string(&t.sep_inner.open)?), - ("close", lua.create_string(&t.sep_inner.close)?), - ])? - .into_lua(lua), - b"sep_outer" => lua - .create_table_from([ - ("open", lua.create_string(&t.sep_outer.open)?), - ("close", lua.create_string(&t.sep_outer.close)?), - ])? - .into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn mode(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.mode; - match key { - b"normal_main" => Style::from(t.normal_main).into_lua(lua), - b"normal_alt" => Style::from(t.normal_alt).into_lua(lua), - - b"select_main" => Style::from(t.select_main).into_lua(lua), - b"select_alt" => Style::from(t.select_alt).into_lua(lua), - - b"unset_main" => Style::from(t.unset_main).into_lua(lua), - b"unset_alt" => Style::from(t.unset_alt).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn status(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.status; - match key { - b"overall" => Style::from(t.overall).into_lua(lua), - b"sep_left" => lua - .create_table_from([ - ("open", lua.create_string(&t.sep_left.open)?), - ("close", lua.create_string(&t.sep_left.close)?), - ])? - .into_lua(lua), - b"sep_right" => lua - .create_table_from([ - ("open", lua.create_string(&t.sep_right.open)?), - ("close", lua.create_string(&t.sep_right.close)?), - ])? - .into_lua(lua), - - b"perm_sep" => Style::from(t.perm_sep).into_lua(lua), - b"perm_type" => Style::from(t.perm_type).into_lua(lua), - b"perm_read" => Style::from(t.perm_read).into_lua(lua), - b"perm_write" => Style::from(t.perm_write).into_lua(lua), - b"perm_exec" => Style::from(t.perm_exec).into_lua(lua), - - b"progress_label" => Style::from(t.progress_label).into_lua(lua), - b"progress_normal" => Style::from(t.progress_normal).into_lua(lua), - b"progress_error" => Style::from(t.progress_error).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn which(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.which; - match key { - b"cols" => t.cols.into_lua(lua), - b"mask" => Style::from(t.mask).into_lua(lua), - b"cand" => Style::from(t.cand).into_lua(lua), - b"rest" => Style::from(t.rest).into_lua(lua), - b"desc" => Style::from(t.desc).into_lua(lua), - - b"separator" => lua.create_string(&t.separator)?.into_lua(lua), - b"separator_style" => Style::from(t.separator_style).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn confirm(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.confirm; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"title" => Style::from(t.title).into_lua(lua), - b"body" => Style::from(t.body).into_lua(lua), - b"list" => Style::from(t.list).into_lua(lua), - - b"btn_yes" => Style::from(t.btn_yes).into_lua(lua), - b"btn_no" => Style::from(t.btn_no).into_lua(lua), - b"btn_labels" => lua - .create_sequence_from([ - lua.create_string(&t.btn_labels[0])?, - lua.create_string(&t.btn_labels[1])?, - ])? - .into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn spot(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.spot; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"title" => Style::from(t.title).into_lua(lua), - - b"tbl_col" => Style::from(t.tbl_col).into_lua(lua), - b"tbl_cell" => Style::from(t.tbl_cell).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn notify(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.notify; - match key { - b"title_info" => Style::from(t.title_info).into_lua(lua), - b"title_warn" => Style::from(t.title_warn).into_lua(lua), - b"title_error" => Style::from(t.title_error).into_lua(lua), - - b"icon_info" => lua.create_string(&t.icon_info)?.into_lua(lua), - b"icon_warn" => lua.create_string(&t.icon_warn)?.into_lua(lua), - b"icon_error" => lua.create_string(&t.icon_error)?.into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn pick(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.pick; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"active" => Style::from(t.active).into_lua(lua), - b"inactive" => Style::from(t.inactive).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn input(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.input; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"title" => Style::from(t.title).into_lua(lua), - b"value" => Style::from(t.value).into_lua(lua), - b"selected" => Style::from(t.selected).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn cmp(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.cmp; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"active" => Style::from(t.active).into_lua(lua), - b"inactive" => Style::from(t.inactive).into_lua(lua), - - b"icon_file" => lua.create_string(&t.icon_file)?.into_lua(lua), - b"icon_folder" => lua.create_string(&t.icon_folder)?.into_lua(lua), - b"icon_command" => lua.create_string(&t.icon_command)?.into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn tasks(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.tasks; - match key { - b"border" => Style::from(t.border).into_lua(lua), - b"title" => Style::from(t.title).into_lua(lua), - b"hovered" => Style::from(t.hovered).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } - - fn help(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { - let t = &THEME.help; - match key { - b"on" => Style::from(t.on).into_lua(lua), - b"run" => Style::from(t.run).into_lua(lua), - b"desc" => Style::from(t.desc).into_lua(lua), - - b"hovered" => Style::from(t.hovered).into_lua(lua), - b"footer" => Style::from(t.footer).into_lua(lua), - - _ => Ok(Value::Nil), - } - }) - } -} diff --git a/yazi-plugin/src/fs/fs.rs b/yazi-plugin/src/fs/fs.rs index 2e5fc2ad..4df4261e 100644 --- a/yazi-plugin/src/fs/fs.rs +++ b/yazi-plugin/src/fs/fs.rs @@ -7,7 +7,7 @@ use yazi_fs::{mounts::PARTITIONS, remove_dir_clean}; use crate::bindings::SizeCalculator; pub fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { match key { b"op" => op(lua)?, b"cwd" => cwd(lua)?, @@ -23,7 +23,11 @@ pub fn compose(lua: &Lua) -> mlua::Result { _ => return Ok(Value::Nil), } .into_lua(lua) - }) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) } fn op(lua: &Lua) -> mlua::Result { diff --git a/yazi-plugin/src/isolate/isolate.rs b/yazi-plugin/src/isolate/isolate.rs index dd228728..5b54989b 100644 --- a/yazi-plugin/src/isolate/isolate.rs +++ b/yazi-plugin/src/isolate/isolate.rs @@ -11,8 +11,8 @@ pub fn slim_lua(name: &str) -> mlua::Result { globals.raw_set("ui", yazi_binding::elements::compose(&lua)?)?; globals.raw_set("ya", crate::utils::compose(&lua, true)?)?; globals.raw_set("fs", crate::fs::compose(&lua)?)?; - globals.raw_set("rt", crate::config::Runtime::compose(&lua)?)?; - globals.raw_set("th", crate::config::Theme::compose(&lua)?)?; + globals.raw_set("rt", crate::runtime::compose(&lua)?)?; + globals.raw_set("th", crate::theme::compose(&lua)?)?; yazi_binding::Cha::install(&lua)?; yazi_binding::File::install(&lua)?; diff --git a/yazi-plugin/src/lib.rs b/yazi-plugin/src/lib.rs index cc581e8b..2216b907 100644 --- a/yazi-plugin/src/lib.rs +++ b/yazi-plugin/src/lib.rs @@ -1,6 +1,6 @@ #![allow(clippy::if_same_then_else, clippy::unit_arg)] -yazi_macro::mod_pub!(bindings config external fs isolate loader process pubsub utils); +yazi_macro::mod_pub!(bindings external fs isolate loader process pubsub runtime theme utils); yazi_macro::mod_flat!(lua twox); diff --git a/yazi-plugin/src/lua.rs b/yazi-plugin/src/lua.rs index ebdb6791..11db15e3 100644 --- a/yazi-plugin/src/lua.rs +++ b/yazi-plugin/src/lua.rs @@ -24,8 +24,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("rt", crate::config::Runtime::compose(lua)?)?; - globals.raw_set("th", crate::config::Theme::compose(lua)?)?; + globals.raw_set("rt", crate::runtime::compose(lua)?)?; + globals.raw_set("th", crate::theme::compose(lua)?)?; yazi_binding::Error::install(lua)?; yazi_binding::Cha::install(lua)?; diff --git a/yazi-plugin/src/pubsub/mod.rs b/yazi-plugin/src/pubsub/mod.rs index 42d8c425..f9ccaa03 100644 --- a/yazi-plugin/src/pubsub/mod.rs +++ b/yazi-plugin/src/pubsub/mod.rs @@ -6,7 +6,7 @@ use yazi_binding::Composer; yazi_macro::mod_flat!(pubsub); pub(super) fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |lua, key| { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { match key { b"pub" => Pubsub::r#pub(lua)?, b"pub_to" => Pubsub::pub_to(lua)?, @@ -17,5 +17,9 @@ pub(super) fn compose(lua: &Lua) -> mlua::Result { _ => return Ok(Value::Nil), } .into_lua(lua) - }) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) } diff --git a/yazi-plugin/src/runtime/mod.rs b/yazi-plugin/src/runtime/mod.rs new file mode 100644 index 00000000..f9eb4864 --- /dev/null +++ b/yazi-plugin/src/runtime/mod.rs @@ -0,0 +1 @@ +yazi_macro::mod_flat!(plugin runtime term); diff --git a/yazi-plugin/src/config/plugin.rs b/yazi-plugin/src/runtime/plugin.rs similarity index 59% rename from yazi-plugin/src/config/plugin.rs rename to yazi-plugin/src/runtime/plugin.rs index 5aff3789..13a6d088 100644 --- a/yazi-plugin/src/config/plugin.rs +++ b/yazi-plugin/src/runtime/plugin.rs @@ -2,45 +2,45 @@ use mlua::{Function, IntoLua, Lua, UserData, Value}; use yazi_binding::{Composer, FileRef, UrlRef, cached_field}; use yazi_config::YAZI; -pub(super) struct Plugin; - -impl Plugin { - pub(super) fn compose(lua: &Lua) -> mlua::Result { - Composer::make(lua, |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) - }) +pub(super) fn plugin(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + match key { + b"fetchers" => fetchers(lua)?, + b"spotter" => spotter(lua)?, + b"preloaders" => preloaders(lua)?, + b"previewer" => previewer(lua)?, + _ => return Ok(Value::Nil), + } + .into_lua(lua) } - fn fetchers(lua: &Lua) -> mlua::Result { - lua.create_function(|lua, (file, mime): (FileRef, mlua::String)| { - lua.create_sequence_from(YAZI.plugin.fetchers(&file.url, &mime.to_str()?).map(Fetcher::new)) - }) - } + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } - fn spotter(lua: &Lua) -> mlua::Result { - lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| { - Ok(YAZI.plugin.spotter(&url, &mime.to_str()?).map(Spotter::new)) - }) - } + Composer::make(lua, get, set) +} - fn preloaders(lua: &Lua) -> mlua::Result { - lua.create_function(|lua, (url, mime): (UrlRef, mlua::String)| { - lua.create_sequence_from(YAZI.plugin.preloaders(&url, &mime.to_str()?).map(Preloader::new)) - }) - } +fn fetchers(lua: &Lua) -> mlua::Result { + lua.create_function(|lua, (file, mime): (FileRef, mlua::String)| { + lua.create_sequence_from(YAZI.plugin.fetchers(&file.url, &mime.to_str()?).map(Fetcher::new)) + }) +} - fn previewer(lua: &Lua) -> mlua::Result { - lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| { - Ok(YAZI.plugin.previewer(&url, &mime.to_str()?).map(Previewer::new)) - }) - } +fn spotter(lua: &Lua) -> mlua::Result { + lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| { + Ok(YAZI.plugin.spotter(&url, &mime.to_str()?).map(Spotter::new)) + }) +} + +fn preloaders(lua: &Lua) -> mlua::Result { + lua.create_function(|lua, (url, mime): (UrlRef, mlua::String)| { + lua.create_sequence_from(YAZI.plugin.preloaders(&url, &mime.to_str()?).map(Preloader::new)) + }) +} + +fn previewer(lua: &Lua) -> mlua::Result { + lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| { + Ok(YAZI.plugin.previewer(&url, &mime.to_str()?).map(Previewer::new)) + }) } // --- Fetcher diff --git a/yazi-plugin/src/runtime/runtime.rs b/yazi-plugin/src/runtime/runtime.rs new file mode 100644 index 00000000..07e4bcc0 --- /dev/null +++ b/yazi-plugin/src/runtime/runtime.rs @@ -0,0 +1,127 @@ +use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value}; +use yazi_binding::{Composer, Url}; +use yazi_boot::ARGS; +use yazi_config::YAZI; + +pub const OPTS: SerializeOptions = + SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false); + +pub fn compose(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + match key { + b"args" => args(lua)?, + b"term" => super::term(lua)?, + b"mgr" => mgr(lua)?, + b"plugin" => super::plugin(lua)?, + b"preview" => preview(lua)?, + b"tasks" => tasks(lua)?, + _ => return Ok(Value::Nil), + } + .into_lua(lua) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn args(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + match key { + b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::new))?.into_lua(lua), + b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::new).into_lua(lua), + b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::new).into_lua(lua), + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn mgr(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let m = &YAZI.mgr; + match key { + b"ratio" => lua.to_value_with(&m.ratio, OPTS)?, + + b"sort_by" => lua.to_value_with(&m.sort_by, OPTS)?, + b"sort_sensitive" => lua.to_value_with(&m.sort_sensitive, OPTS)?, + b"sort_reverse" => lua.to_value_with(&m.sort_reverse, OPTS)?, + b"sort_dir_first" => lua.to_value_with(&m.sort_dir_first, OPTS)?, + b"sort_translit" => lua.to_value_with(&m.sort_translit, OPTS)?, + + b"linemode" => lua.to_value_with(&m.linemode, OPTS)?, + b"show_hidden" => lua.to_value_with(&m.show_hidden, OPTS)?, + b"show_symlink" => lua.to_value_with(&m.show_symlink, OPTS)?, + b"scrolloff" => lua.to_value_with(&m.scrolloff, OPTS)?, + b"mouse_events" => lua.to_value_with(&m.mouse_events, OPTS)?, + b"title_format" => lua.to_value_with(&m.title_format, OPTS)?, + _ => return Ok(Value::Nil), + } + .into_lua(lua) + } + + fn set(lua: &Lua, key: &[u8], value: Value) -> mlua::Result { + let m = &YAZI.mgr; + Ok(match key { + b"ratio" => { + m.ratio.set(lua.from_value(value)?); + Value::Nil + } + _ => value, + }) + } + + Composer::make(lua, get, set) +} + +fn preview(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let p = &YAZI.preview; + match key { + b"wrap" => lua.to_value_with(&p.wrap, OPTS)?, + b"tab_size" => lua.to_value_with(&p.tab_size, OPTS)?, + b"max_width" => lua.to_value_with(&p.max_width, OPTS)?, + b"max_height" => lua.to_value_with(&p.max_height, OPTS)?, + + b"cache_dir" => lua.to_value_with(&p.cache_dir, OPTS)?, + + b"image_delay" => lua.to_value_with(&p.image_delay, OPTS)?, + b"image_filter" => lua.to_value_with(&p.image_filter, OPTS)?, + b"image_quality" => lua.to_value_with(&p.image_quality, OPTS)?, + + b"ueberzug_scale" => lua.to_value_with(&p.ueberzug_scale, OPTS)?, + b"ueberzug_offset" => lua.to_value_with(&p.ueberzug_offset, OPTS)?, + _ => return Ok(Value::Nil), + } + .into_lua(lua) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn tasks(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &YAZI.tasks; + match key { + b"micro_workers" => lua.to_value_with(&t.micro_workers, OPTS)?, + b"macro_workers" => lua.to_value_with(&t.macro_workers, OPTS)?, + b"bizarre_retry" => lua.to_value_with(&t.bizarre_retry, OPTS)?, + + b"image_alloc" => lua.to_value_with(&t.image_alloc, OPTS)?, + b"image_bound" => lua.to_value_with(&t.image_bound, OPTS)?, + + b"suppress_preload" => lua.to_value_with(&t.suppress_preload, OPTS)?, + _ => return Ok(Value::Nil), + } + .into_lua(lua) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} diff --git a/yazi-plugin/src/runtime/term.rs b/yazi-plugin/src/runtime/term.rs new file mode 100644 index 00000000..bd0e3b63 --- /dev/null +++ b/yazi-plugin/src/runtime/term.rs @@ -0,0 +1,27 @@ +use mlua::{Function, IntoLua, IntoLuaMulti, Lua, Value}; +use yazi_adapter::{Dimension, EMULATOR}; +use yazi_binding::Composer; + +pub(super) fn term(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + match key { + b"light" => EMULATOR.get().light.into_lua(lua), + b"cell_size" => cell_size(lua)?.into_lua(lua), + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn cell_size(lua: &Lua) -> mlua::Result { + lua.create_function(|lua, ()| { + if let Some(s) = Dimension::cell_size() { + s.into_lua_multi(lua) + } else { + ().into_lua_multi(lua) + } + }) +} diff --git a/yazi-plugin/src/theme/mod.rs b/yazi-plugin/src/theme/mod.rs new file mode 100644 index 00000000..c0a6b7f5 --- /dev/null +++ b/yazi-plugin/src/theme/mod.rs @@ -0,0 +1 @@ +yazi_macro::mod_flat!(theme); diff --git a/yazi-plugin/src/theme/theme.rs b/yazi-plugin/src/theme/theme.rs new file mode 100644 index 00000000..f187e869 --- /dev/null +++ b/yazi-plugin/src/theme/theme.rs @@ -0,0 +1,334 @@ +use mlua::{IntoLua, Lua, Value}; +use yazi_binding::{Composer, Style, Url}; +use yazi_config::THEME; + +pub fn compose(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + match key { + b"mgr" => mgr(lua), + b"tabs" => tabs(lua), + b"mode" => mode(lua), + b"status" => status(lua), + b"which" => which(lua), + b"confirm" => confirm(lua), + b"spot" => spot(lua), + b"notify" => notify(lua), + b"pick" => pick(lua), + b"input" => input(lua), + b"cmp" => cmp(lua), + b"tasks" => tasks(lua), + b"help" => help(lua), + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn mgr(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let m = &THEME.mgr; + match key { + b"cwd" => Style::from(m.cwd).into_lua(lua), + + b"hovered" => Style::from(m.hovered).into_lua(lua), + b"preview_hovered" => Style::from(m.preview_hovered).into_lua(lua), + + b"find_keyword" => Style::from(m.find_keyword).into_lua(lua), + b"find_position" => Style::from(m.find_position).into_lua(lua), + + b"symlink_target" => Style::from(m.symlink_target).into_lua(lua), + + b"marker_copied" => Style::from(m.marker_copied).into_lua(lua), + b"marker_cut" => Style::from(m.marker_cut).into_lua(lua), + b"marker_marked" => Style::from(m.marker_marked).into_lua(lua), + b"marker_selected" => Style::from(m.marker_selected).into_lua(lua), + + b"count_copied" => Style::from(m.count_copied).into_lua(lua), + b"count_cut" => Style::from(m.count_cut).into_lua(lua), + b"count_selected" => Style::from(m.count_selected).into_lua(lua), + + b"border_symbol" => lua.create_string(&m.border_symbol)?.into_lua(lua), + b"border_style" => Style::from(m.border_style).into_lua(lua), + + b"syntect_theme" => Url::new(&m.syntect_theme).into_lua(lua), + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn tabs(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.tabs; + match key { + b"active" => Style::from(t.active).into_lua(lua), + b"inactive" => Style::from(t.inactive).into_lua(lua), + + b"sep_inner" => lua + .create_table_from([ + ("open", lua.create_string(&t.sep_inner.open)?), + ("close", lua.create_string(&t.sep_inner.close)?), + ])? + .into_lua(lua), + b"sep_outer" => lua + .create_table_from([ + ("open", lua.create_string(&t.sep_outer.open)?), + ("close", lua.create_string(&t.sep_outer.close)?), + ])? + .into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn mode(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.mode; + match key { + b"normal_main" => Style::from(t.normal_main).into_lua(lua), + b"normal_alt" => Style::from(t.normal_alt).into_lua(lua), + + b"select_main" => Style::from(t.select_main).into_lua(lua), + b"select_alt" => Style::from(t.select_alt).into_lua(lua), + + b"unset_main" => Style::from(t.unset_main).into_lua(lua), + b"unset_alt" => Style::from(t.unset_alt).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn status(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.status; + match key { + b"overall" => Style::from(t.overall).into_lua(lua), + b"sep_left" => lua + .create_table_from([ + ("open", lua.create_string(&t.sep_left.open)?), + ("close", lua.create_string(&t.sep_left.close)?), + ])? + .into_lua(lua), + b"sep_right" => lua + .create_table_from([ + ("open", lua.create_string(&t.sep_right.open)?), + ("close", lua.create_string(&t.sep_right.close)?), + ])? + .into_lua(lua), + + b"perm_sep" => Style::from(t.perm_sep).into_lua(lua), + b"perm_type" => Style::from(t.perm_type).into_lua(lua), + b"perm_read" => Style::from(t.perm_read).into_lua(lua), + b"perm_write" => Style::from(t.perm_write).into_lua(lua), + b"perm_exec" => Style::from(t.perm_exec).into_lua(lua), + + b"progress_label" => Style::from(t.progress_label).into_lua(lua), + b"progress_normal" => Style::from(t.progress_normal).into_lua(lua), + b"progress_error" => Style::from(t.progress_error).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn which(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.which; + match key { + b"cols" => t.cols.into_lua(lua), + b"mask" => Style::from(t.mask).into_lua(lua), + b"cand" => Style::from(t.cand).into_lua(lua), + b"rest" => Style::from(t.rest).into_lua(lua), + b"desc" => Style::from(t.desc).into_lua(lua), + + b"separator" => lua.create_string(&t.separator)?.into_lua(lua), + b"separator_style" => Style::from(t.separator_style).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn confirm(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.confirm; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"title" => Style::from(t.title).into_lua(lua), + b"body" => Style::from(t.body).into_lua(lua), + b"list" => Style::from(t.list).into_lua(lua), + + b"btn_yes" => Style::from(t.btn_yes).into_lua(lua), + b"btn_no" => Style::from(t.btn_no).into_lua(lua), + b"btn_labels" => lua + .create_sequence_from([ + lua.create_string(&t.btn_labels[0])?, + lua.create_string(&t.btn_labels[1])?, + ])? + .into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn spot(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.spot; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"title" => Style::from(t.title).into_lua(lua), + + b"tbl_col" => Style::from(t.tbl_col).into_lua(lua), + b"tbl_cell" => Style::from(t.tbl_cell).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn notify(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.notify; + match key { + b"title_info" => Style::from(t.title_info).into_lua(lua), + b"title_warn" => Style::from(t.title_warn).into_lua(lua), + b"title_error" => Style::from(t.title_error).into_lua(lua), + + b"icon_info" => lua.create_string(&t.icon_info)?.into_lua(lua), + b"icon_warn" => lua.create_string(&t.icon_warn)?.into_lua(lua), + b"icon_error" => lua.create_string(&t.icon_error)?.into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn pick(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.pick; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"active" => Style::from(t.active).into_lua(lua), + b"inactive" => Style::from(t.inactive).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn input(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.input; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"title" => Style::from(t.title).into_lua(lua), + b"value" => Style::from(t.value).into_lua(lua), + b"selected" => Style::from(t.selected).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn cmp(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.cmp; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"active" => Style::from(t.active).into_lua(lua), + b"inactive" => Style::from(t.inactive).into_lua(lua), + + b"icon_file" => lua.create_string(&t.icon_file)?.into_lua(lua), + b"icon_folder" => lua.create_string(&t.icon_folder)?.into_lua(lua), + b"icon_command" => lua.create_string(&t.icon_command)?.into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn tasks(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.tasks; + match key { + b"border" => Style::from(t.border).into_lua(lua), + b"title" => Style::from(t.title).into_lua(lua), + b"hovered" => Style::from(t.hovered).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} + +fn help(lua: &Lua) -> mlua::Result { + fn get(lua: &Lua, key: &[u8]) -> mlua::Result { + let t = &THEME.help; + match key { + b"on" => Style::from(t.on).into_lua(lua), + b"run" => Style::from(t.run).into_lua(lua), + b"desc" => Style::from(t.desc).into_lua(lua), + + b"hovered" => Style::from(t.hovered).into_lua(lua), + b"footer" => Style::from(t.footer).into_lua(lua), + + _ => Ok(Value::Nil), + } + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, get, set) +} diff --git a/yazi-plugin/src/utils/json.rs b/yazi-plugin/src/utils/json.rs index b930f33c..239a59e9 100644 --- a/yazi-plugin/src/utils/json.rs +++ b/yazi-plugin/src/utils/json.rs @@ -2,7 +2,7 @@ use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value}; use yazi_binding::Error; use super::Utils; -use crate::config::OPTS; +use crate::runtime::OPTS; impl Utils { pub(super) fn json_encode(lua: &Lua) -> mlua::Result { diff --git a/yazi-plugin/src/utils/utils.rs b/yazi-plugin/src/utils/utils.rs index 426ee7dc..45b2781f 100644 --- a/yazi-plugin/src/utils/utils.rs +++ b/yazi-plugin/src/utils/utils.rs @@ -4,7 +4,7 @@ use yazi_binding::Composer; pub(super) struct Utils; pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result { - Composer::make(lua, move |lua, key| { + fn get(lua: &Lua, key: &[u8], isolate: bool) -> mlua::Result { match key { // App b"id" => Utils::id(lua)?, @@ -84,5 +84,9 @@ pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result { _ => return Ok(Value::Nil), } .into_lua(lua) - }) + } + + fn set(_: &Lua, _: &[u8], value: Value) -> mlua::Result { Ok(value) } + + Composer::make(lua, move |lua, key| get(lua, key, isolate), set) } diff --git a/yazi-shared/src/sync_cell.rs b/yazi-shared/src/sync_cell.rs index e8722621..9ea55e37 100644 --- a/yazi-shared/src/sync_cell.rs +++ b/yazi-shared/src/sync_cell.rs @@ -1,5 +1,7 @@ use std::{cell::Cell, fmt::{Debug, Display, Formatter}, ops::Deref}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + /// [`SyncCell`], but [`Sync`]. /// /// This is just an `Cell`, except it implements `Sync` @@ -36,3 +38,21 @@ impl Debug for SyncCell { impl Display for SyncCell { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.get(), f) } } + +impl Serialize for SyncCell +where + T: Copy + Serialize, +{ + fn serialize(&self, serializer: S) -> Result { + self.0.serialize(serializer) + } +} + +impl<'de, T> Deserialize<'de> for SyncCell +where + T: Copy + Deserialize<'de>, +{ + fn deserialize>(deserializer: D) -> Result { + Ok(Self::new(T::deserialize(deserializer)?)) + } +}