diff --git a/CHANGELOG.md b/CHANGELOG.md
index a25b0096..6bf1272f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
- Upgrade Lua to 5.5 ([#3633])
- Change preset t for creating tabs to t ⇒ t to avoid conflict with new t ⇒ r for renaming tabs ([#3666])
+- Make `ui.Style` immutable ([#3862])
- Remove `title_format` in favor of new `ind-app-title` DDS event for flexible title customization ([#3684])
- Remove `micro_workers` and `macro_workers` in favor of finer control over concurrent workers ([#3661])
@@ -1697,3 +1698,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
[#3813]: https://github.com/sxyazi/yazi/pull/3813
[#3846]: https://github.com/sxyazi/yazi/pull/3846
[#3854]: https://github.com/sxyazi/yazi/pull/3854
+[#3862]: https://github.com/sxyazi/yazi/pull/3862
diff --git a/yazi-actor/src/lives/core.rs b/yazi-actor/src/lives/core.rs
index 46af6383..a32022c9 100644
--- a/yazi-actor/src/lives/core.rs
+++ b/yazi-actor/src/lives/core.rs
@@ -1,6 +1,6 @@
use std::ops::Deref;
-use mlua::{AnyUserData, IntoLua, MetaMethod, UserData, Value};
+use mlua::{AnyUserData, IntoLua, MetaMethod, UserData, UserDataMethods, Value};
use paste::paste;
use super::{Lives, PtrCell};
@@ -38,7 +38,7 @@ impl Core {
}
impl UserData for Core {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_meta_method_mut(MetaMethod::Index, |lua, me, key: mlua::String| {
macro_rules! reuse {
($key:ident, $value:expr) => {
diff --git a/yazi-binding/src/chan.rs b/yazi-binding/src/chan.rs
index 7c2d0376..afea9dc8 100644
--- a/yazi-binding/src/chan.rs
+++ b/yazi-binding/src/chan.rs
@@ -1,4 +1,4 @@
-use mlua::{ExternalError, FromLua, IntoLua, IntoLuaMulti, UserData, Value};
+use mlua::{ExternalError, FromLua, IntoLua, IntoLuaMulti, UserData, UserDataMethods, Value};
use yazi_codegen::FromLuaOwned;
use crate::Error;
@@ -8,7 +8,7 @@ pub struct MpscTx(pub tokio::sync::mpsc::Sender);
pub struct MpscRx(pub tokio::sync::mpsc::Receiver);
impl UserData for MpscTx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_async_method("send", |lua, me, value: Value| async move {
match me.0.send(T::from_lua(value, &lua)?).await {
Ok(()) => true.into_lua_multi(&lua),
@@ -19,7 +19,7 @@ impl UserData for MpscTx {
}
impl UserData for MpscRx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_async_method_mut("recv", |lua, mut me, ()| async move {
match me.0.recv().await {
Some(value) => (value, true).into_lua_multi(&lua),
@@ -34,7 +34,7 @@ pub struct MpscUnboundedTx(pub tokio::sync::mpsc::Unbounde
pub struct MpscUnboundedRx(pub tokio::sync::mpsc::UnboundedReceiver);
impl UserData for MpscUnboundedTx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_method("send", |lua, me, value: Value| match me.0.send(T::from_lua(value, lua)?) {
Ok(()) => true.into_lua_multi(lua),
Err(e) => (false, Error::custom(e.to_string())).into_lua_multi(lua),
@@ -43,7 +43,7 @@ impl UserData for MpscUnboundedTx {
}
impl UserData for MpscUnboundedRx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_async_method_mut("recv", |lua, mut me, ()| async move {
match me.0.recv().await {
Some(value) => (value, true).into_lua_multi(&lua),
@@ -58,7 +58,7 @@ pub struct OneshotTx(pub Option(pub Option>);
impl UserData for OneshotTx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_method_mut("send", |lua, me, value: Value| {
let Some(tx) = me.0.take() else {
return Err("Oneshot sender already used".into_lua_err());
@@ -72,7 +72,7 @@ impl UserData for OneshotTx {
}
impl UserData for OneshotRx {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_async_method_mut("recv", |lua, mut me, ()| async move {
let Some(rx) = me.0.take() else {
return Err("Oneshot receiver already used".into_lua_err());
diff --git a/yazi-binding/src/color.rs b/yazi-binding/src/color.rs
deleted file mode 100644
index 5f9f1aaf..00000000
--- a/yazi-binding/src/color.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use std::str::FromStr;
-
-use mlua::{ExternalError, ExternalResult, FromLua, Lua, UserData, Value};
-
-#[derive(Clone, Copy, Default)]
-pub struct Color(pub ratatui::style::Color);
-
-impl FromLua for Color {
- fn from_lua(value: Value, _: &Lua) -> mlua::Result {
- Ok(Self(match value {
- Value::String(s) => ratatui::style::Color::from_str(&s.to_str()?).into_lua_err()?,
- Value::UserData(ud) => ud.borrow::()?.0,
- _ => Err("expected a Color".into_lua_err())?,
- }))
- }
-}
-
-impl UserData for Color {}
diff --git a/yazi-binding/src/elements/bar.rs b/yazi-binding/src/elements/bar.rs
index 5d24a774..a3eb15a1 100644
--- a/yazi-binding/src/elements/bar.rs
+++ b/yazi-binding/src/elements/bar.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::{Borders, Widget};
use super::{Area, Edge};
@@ -77,7 +77,7 @@ impl Widget for &Bar {
}
impl UserData for Bar {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
diff --git a/yazi-binding/src/elements/border.rs b/yazi-binding/src/elements/border.rs
index d4b1f940..f32d0038 100644
--- a/yazi-binding/src/elements/border.rs
+++ b/yazi-binding/src/elements/border.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::{Borders, Widget};
use super::{Area, Edge};
@@ -75,7 +75,7 @@ impl Widget for &Border {
}
impl UserData for Border {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
diff --git a/yazi-binding/src/elements/clear.rs b/yazi-binding/src/elements/clear.rs
index 3fb2c8e0..5bcf0c2b 100644
--- a/yazi-binding/src/elements/clear.rs
+++ b/yazi-binding/src/elements/clear.rs
@@ -1,4 +1,4 @@
-use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;
use super::Area;
@@ -38,7 +38,7 @@ impl Widget for &Clear {
}
impl UserData for Clear {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
}
}
diff --git a/yazi-binding/src/elements/color.rs b/yazi-binding/src/elements/color.rs
new file mode 100644
index 00000000..8594443c
--- /dev/null
+++ b/yazi-binding/src/elements/color.rs
@@ -0,0 +1,30 @@
+use std::str::FromStr;
+
+use mlua::{ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+
+#[derive(Clone, Copy, Default)]
+pub struct Color(pub ratatui::style::Color);
+
+impl Color {
+ pub fn compose(lua: &Lua) -> mlua::Result {
+ let new = lua.create_function(|_, (_, color): (Table, Color)| Ok(color))?;
+
+ let color = lua.create_table()?;
+ color.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?))?;
+
+ color.into_lua(lua)
+ }
+}
+
+impl FromLua for Color {
+ fn from_lua(value: Value, _: &Lua) -> mlua::Result {
+ Ok(Self(match value {
+ Value::Nil => ratatui::style::Color::Reset,
+ Value::String(s) => ratatui::style::Color::from_str(&s.to_str()?).into_lua_err()?,
+ Value::UserData(ud) => ud.borrow::()?.0,
+ _ => Err("expected a Color".into_lua_err())?,
+ }))
+ }
+}
+
+impl UserData for Color {}
diff --git a/yazi-binding/src/elements/elements.rs b/yazi-binding/src/elements/elements.rs
index 04032c26..45971550 100644
--- a/yazi-binding/src/elements/elements.rs
+++ b/yazi-binding/src/elements/elements.rs
@@ -11,6 +11,7 @@ pub fn compose(p_get: ComposerGet, p_set: ComposerSet) -> Composer super::Bar::compose(lua)?,
b"Border" => super::Border::compose(lua)?,
b"Clear" => super::Clear::compose(lua)?,
+ b"Color" => super::Color::compose(lua)?,
b"Constraint" => super::Constraint::compose(lua)?,
b"Edge" => super::Edge::compose(lua)?,
b"Gauge" => super::Gauge::compose(lua)?,
diff --git a/yazi-binding/src/elements/list.rs b/yazi-binding/src/elements/list.rs
index 2af2d0d2..09f7b973 100644
--- a/yazi-binding/src/elements/list.rs
+++ b/yazi-binding/src/elements/list.rs
@@ -1,4 +1,4 @@
-use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;
use super::{Area, Text};
@@ -43,7 +43,7 @@ impl Widget for &List {
}
impl UserData for List {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
}
}
diff --git a/yazi-binding/src/elements/mod.rs b/yazi-binding/src/elements/mod.rs
index 6cdcbd9c..61dcd02f 100644
--- a/yazi-binding/src/elements/mod.rs
+++ b/yazi-binding/src/elements/mod.rs
@@ -1 +1 @@
-yazi_macro::mod_flat!(align area bar border cell clear constraint edge elements gauge layout line list pad pos rect renderable row span table text wrap);
+yazi_macro::mod_flat!(align area bar border cell clear color constraint edge elements gauge layout line list pad pos rect renderable row span table text wrap);
diff --git a/yazi-binding/src/elements/pos.rs b/yazi-binding/src/elements/pos.rs
index ba7d12bd..5912f223 100644
--- a/yazi-binding/src/elements/pos.rs
+++ b/yazi-binding/src/elements/pos.rs
@@ -1,6 +1,6 @@
use std::{ops::Deref, str::FromStr};
-use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use yazi_shim::strum::IntoStr;
use super::Pad;
@@ -90,7 +90,7 @@ impl UserData for Pos {
fields.add_field_method_get("h", |_, me| Ok(me.offset.height));
}
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_function_mut("pad", |_, (ud, pad): (AnyUserData, Pad)| {
ud.borrow_mut::()?.pad = pad;
Ok(ud)
diff --git a/yazi-binding/src/elements/rect.rs b/yazi-binding/src/elements/rect.rs
index 44f902d4..0a280c8d 100644
--- a/yazi-binding/src/elements/rect.rs
+++ b/yazi-binding/src/elements/rect.rs
@@ -1,6 +1,6 @@
use std::ops::Deref;
-use mlua::{FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use super::Pad;
@@ -68,7 +68,7 @@ impl UserData for Rect {
fields.add_field_method_get("bottom", |_, me| Ok(me.bottom()));
}
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_method("pad", |_, me, pad: Pad| Ok(me.pad(pad)));
methods.add_method("contains", |_, me, Self(rect)| Ok(me.contains(rect.into())));
}
diff --git a/yazi-binding/src/elements/row.rs b/yazi-binding/src/elements/row.rs
index 7e0ebbbc..9120eeb7 100644
--- a/yazi-binding/src/elements/row.rs
+++ b/yazi-binding/src/elements/row.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use super::Cell;
@@ -52,7 +52,7 @@ impl FromLua for Row {
}
impl UserData for Row {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_style_method!(methods, style);
methods.add_function_mut("height", |_, (ud, value): (AnyUserData, u16)| {
diff --git a/yazi-binding/src/elements/table.rs b/yazi-binding/src/elements/table.rs
index 37a8b0e4..9fa5ead1 100644
--- a/yazi-binding/src/elements/table.rs
+++ b/yazi-binding/src/elements/table.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, UserData, Value};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, UserData, UserDataMethods, Value};
use ratatui::widgets::{StatefulWidget, Widget};
use super::{Area, Row};
@@ -105,7 +105,7 @@ impl Widget for &Table {
}
impl UserData for Table {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
methods.add_function_mut("header", |_, (ud, header): (AnyUserData, Row)| {
diff --git a/yazi-binding/src/elements/text.rs b/yazi-binding/src/elements/text.rs
index 646d3291..47e824f3 100644
--- a/yazi-binding/src/elements/text.rs
+++ b/yazi-binding/src/elements/text.rs
@@ -1,7 +1,7 @@
use std::{any::TypeId, mem};
use ansi_to_tui::IntoText;
-use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;
use super::{Area, Line, Span, Wrap};
@@ -119,7 +119,7 @@ impl FromLua for Text {
}
impl UserData for Text {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, inner.style);
crate::impl_style_shorthands!(methods, inner.style);
diff --git a/yazi-binding/src/image.rs b/yazi-binding/src/image.rs
index ced8d498..ff21c70b 100644
--- a/yazi-binding/src/image.rs
+++ b/yazi-binding/src/image.rs
@@ -1,6 +1,6 @@
use std::ops::Deref;
-use mlua::{MetaMethod, UserData};
+use mlua::{MetaMethod, UserData, UserDataMethods};
pub struct ImageInfo(yazi_adapter::ImageInfo);
@@ -28,7 +28,7 @@ impl UserData for ImageInfo {
struct ImageFormat(yazi_adapter::ImageFormat);
impl UserData for ImageFormat {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| {
use yazi_adapter::ImageFormat as F;
@@ -58,7 +58,7 @@ impl UserData for ImageFormat {
struct ImageColor(yazi_adapter::ImageColor);
impl UserData for ImageColor {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| {
use yazi_adapter::ImageColor as C;
diff --git a/yazi-binding/src/layer.rs b/yazi-binding/src/layer.rs
index 002b248f..1e85aa92 100644
--- a/yazi-binding/src/layer.rs
+++ b/yazi-binding/src/layer.rs
@@ -1,4 +1,4 @@
-use mlua::{MetaMethod, UserData};
+use mlua::{MetaMethod, UserData, UserDataMethods};
use yazi_shim::strum::IntoStr;
#[derive(Clone, Copy)]
@@ -9,7 +9,7 @@ impl From for Layer {
}
impl UserData for Layer {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.0.into_str()));
}
}
diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs
index f696a98b..fc046f2d 100644
--- a/yazi-binding/src/lib.rs
+++ b/yazi-binding/src/lib.rs
@@ -2,4 +2,4 @@ mod macros;
yazi_macro::mod_pub!(elements process);
-yazi_macro::mod_flat!(access calculator cha chan chord_cow color composer error fd file handle icon id image input iter layer mouse path permit range runtime scheme stage style url utils);
+yazi_macro::mod_flat!(access calculator cha chan chord_cow composer error fd file handle icon id image input iter layer mouse path permit range runtime scheme stage style url utils);
diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs
index af02e660..69f4d64e 100644
--- a/yazi-binding/src/macros.rs
+++ b/yazi-binding/src/macros.rs
@@ -117,37 +117,39 @@ macro_rules! impl_style_method {
macro_rules! impl_style_shorthands {
($methods:ident, $($field:tt).+) => {
$methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
+ use $crate::elements::Color;
use mlua::FromLua;
use ratatui::style::Modifier;
let me = &mut ud.borrow_mut::()?.$($field).+;
match value {
- mlua::Value::Boolean(true) if me.add_modifier.contains(Modifier::REVERSED) && !me.sub_modifier.contains(Modifier::REVERSED) => {
- me.bg.map($crate::Color).into_lua(lua)
+ mlua::Value::Boolean(true) if me.has_modifier(Modifier::REVERSED) => {
+ me.bg.map(Color).into_lua(lua)
}
mlua::Value::Nil | mlua::Value::Boolean(_) => {
- me.fg.map($crate::Color).into_lua(lua)
+ me.fg.map(Color).into_lua(lua)
}
_ => {
- me.fg = Some($crate::Color::from_lua(value, lua)?.0);
+ me.fg = Some(Color::from_lua(value, lua)?.0);
ud.into_lua(lua)
}
}
});
$methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| {
+ use $crate::elements::Color;
use mlua::FromLua;
use ratatui::style::Modifier;
let me = &mut ud.borrow_mut::()?.$($field).+;
match value {
- mlua::Value::Boolean(true) if me.add_modifier.contains(Modifier::REVERSED) && !me.sub_modifier.contains(Modifier::REVERSED) => {
- me.fg.map($crate::Color).into_lua(lua)
+ mlua::Value::Boolean(true) if me.has_modifier(Modifier::REVERSED) => {
+ me.fg.map(Color).into_lua(lua)
}
mlua::Value::Nil | mlua::Value::Boolean(_) => {
- me.bg.map($crate::Color).into_lua(lua)
+ me.bg.map(Color).into_lua(lua)
}
_ => {
- me.bg = Some($crate::Color::from_lua(value, lua)?.0);
+ me.bg = Some(Color::from_lua(value, lua)?.0);
ud.into_lua(lua)
}
}
diff --git a/yazi-binding/src/process/command.rs b/yazi-binding/src/process/command.rs
index 97fa5577..5dd4fdbc 100644
--- a/yazi-binding/src/process/command.rs
+++ b/yazi-binding/src/process/command.rs
@@ -1,12 +1,11 @@
use std::{any::TypeId, ffi::OsStr, io, process::Stdio};
-use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
-use crate::Error;
use yazi_shared::wtf8::FromWtf8;
use super::{Child, output::Output};
-use crate::process::Status;
+use crate::{Error, process::Status};
pub struct Command {
inner: tokio::process::Command,
@@ -108,7 +107,7 @@ impl Command {
}
impl UserData for Command {
- fn add_methods>(methods: &mut M) {
+ fn add_methods>(methods: &mut M) {
#[inline]
fn make_stdio(v: Value) -> mlua::Result {
match v {
diff --git a/yazi-binding/src/style.rs b/yazi-binding/src/style.rs
index 7585ce23..07e325b3 100644
--- a/yazi-binding/src/style.rs
+++ b/yazi-binding/src/style.rs
@@ -1,10 +1,27 @@
-use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, MetaMethod, Table, UserData, UserDataMethods, Value};
+use std::ops::Deref;
-use crate::SER_OPT;
+use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, MetaMethod, Table, UserData, UserDataMethods, Value};
+use ratatui::style::Modifier;
+
+use crate::{SER_OPT, elements::Color};
#[derive(Clone, Copy, Default)]
pub struct Style(pub ratatui::style::Style);
+impl Deref for Style {
+ type Target = ratatui::style::Style;
+
+ fn deref(&self) -> &Self::Target { &self.0 }
+}
+
+impl From for Style {
+ fn from(value: yazi_config::Style) -> Self { Self(value.into()) }
+}
+
+impl From