diff --git a/yazi-fm/src/app/commands/mouse.rs b/yazi-fm/src/app/commands/mouse.rs index f90c8716b..ba3ed71ae 100644 --- a/yazi-fm/src/app/commands/mouse.rs +++ b/yazi-fm/src/app/commands/mouse.rs @@ -22,7 +22,7 @@ impl App { let Ok(evt) = yazi_plugin::bindings::MouseEvent::cast(&LUA, event) else { return }; let res = Lives::scope(&self.cx, move |_| { - let area = yazi_plugin::elements::Rect::cast(&LUA, size)?; + let area = yazi_plugin::elements::Rect::from(size); let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?; if matches!(event.kind, MouseEventKind::Down(_) if MANAGER.mouse_events.draggable()) { diff --git a/yazi-fm/src/root.rs b/yazi-fm/src/root.rs index 723f67990..a10f57424 100644 --- a/yazi-fm/src/root.rs +++ b/yazi-fm/src/root.rs @@ -1,7 +1,7 @@ use mlua::{Table, TableExt}; use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; use tracing::error; -use yazi_plugin::{LUA, bindings::Cast, elements::render_widgets}; +use yazi_plugin::{LUA, elements::render_widgets}; use super::{completion, confirm, input, select, tasks, which}; use crate::{Ctx, components, help}; @@ -17,7 +17,7 @@ impl<'a> Root<'a> { impl<'a> Widget for Root<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let mut f = || { - let area = yazi_plugin::elements::Rect::cast(&LUA, area)?; + let area = yazi_plugin::elements::Rect::from(area); let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?; render_widgets(root.call_method("render", ())?, buf); diff --git a/yazi-plugin/src/elements/bar.rs b/yazi-plugin/src/elements/bar.rs index f59087ed7..ad5bfa09e 100644 --- a/yazi-plugin/src/elements/bar.rs +++ b/yazi-plugin/src/elements/bar.rs @@ -1,11 +1,11 @@ use mlua::{AnyUserData, Lua, Table, UserData}; use ratatui::widgets::Borders; -use super::{RectRef, Renderable}; +use super::{Rect, Renderable}; #[derive(Clone)] pub struct Bar { - area: ratatui::layout::Rect, + area: Rect, direction: ratatui::widgets::Borders, symbol: String, @@ -14,13 +14,13 @@ pub struct Bar { impl Bar { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|_, (_, area, direction): (Table, RectRef, u8)| { + let new = lua.create_function(|_, (_, area, direction): (Table, Rect, u8)| { Ok(Self { - area: *area, + area, direction: Borders::from_bits_truncate(direction), - symbol: Default::default(), - style: Default::default(), + symbol: Default::default(), + style: Default::default(), }) })?; @@ -57,7 +57,7 @@ impl UserData for Bar { } impl Renderable for Bar { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { if self.area.area() == 0 { diff --git a/yazi-plugin/src/elements/border.rs b/yazi-plugin/src/elements/border.rs index 0c30c91ac..1414cf9bb 100644 --- a/yazi-plugin/src/elements/border.rs +++ b/yazi-plugin/src/elements/border.rs @@ -1,7 +1,7 @@ use mlua::{AnyUserData, Lua, Table, UserData}; use ratatui::widgets::{Borders, Widget}; -use super::{RectRef, Renderable}; +use super::{Rect, Renderable}; // Type const PLAIN: u8 = 0; @@ -13,7 +13,7 @@ const QUADRANT_OUTSIDE: u8 = 5; #[derive(Clone, Default)] pub struct Border { - area: ratatui::layout::Rect, + area: Rect, position: ratatui::widgets::Borders, type_: ratatui::widgets::BorderType, @@ -22,9 +22,9 @@ pub struct Border { impl Border { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|_, (_, area, position): (Table, RectRef, u8)| { + let new = lua.create_function(|_, (_, area, position): (Table, Rect, u8)| { Ok(Border { - area: *area, + area, position: ratatui::widgets::Borders::from_bits_truncate(position), ..Default::default() }) @@ -77,14 +77,14 @@ impl UserData for Border { } impl Renderable for Border { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { ratatui::widgets::Block::default() .borders(self.position) .border_type(self.type_) .border_style(self.style) - .render(self.area, buf); + .render(*self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf); } diff --git a/yazi-plugin/src/elements/clear.rs b/yazi-plugin/src/elements/clear.rs index 9e1121bf8..c11c43ac8 100644 --- a/yazi-plugin/src/elements/clear.rs +++ b/yazi-plugin/src/elements/clear.rs @@ -1,21 +1,20 @@ use std::sync::atomic::{AtomicBool, Ordering}; use mlua::{Lua, Table, UserData}; -use ratatui::layout::Rect; use yazi_adapter::ADAPTOR; -use super::{RectRef, Renderable}; +use super::{Rect, Renderable}; pub static COLLISION: AtomicBool = AtomicBool::new(false); #[derive(Clone, Copy, Default)] pub struct Clear { - pub area: ratatui::layout::Rect, + pub area: Rect, } impl Clear { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|_, (_, area): (Table, RectRef)| Ok(Clear { area: *area }))?; + let new = lua.create_function(|_, (_, area): (Table, Rect)| Ok(Clear { area }))?; let clear = lua.create_table()?; clear.set_metatable(Some(lua.create_table_from([("__call", new)])?)); @@ -25,13 +24,13 @@ impl Clear { } impl ratatui::widgets::Widget for Clear { - fn render(self, area: Rect, buf: &mut ratatui::prelude::Buffer) + fn render(self, area: ratatui::layout::Rect, buf: &mut ratatui::prelude::Buffer) where Self: Sized, { ratatui::widgets::Clear.render(area, buf); - let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(&area, &r)) else { + let Some(r) = ADAPTOR.shown_load().and_then(|r| overlap(area, r)) else { return; }; @@ -46,10 +45,10 @@ impl ratatui::widgets::Widget for Clear { } impl Renderable for Clear { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { - ::render(Default::default(), self.area, buf); + ::render(Default::default(), *self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(*self).render(buf); } @@ -62,11 +61,11 @@ impl UserData for Clear { } #[inline] -const fn is_overlapping(a: &Rect, b: &Rect) -> bool { +const fn is_overlapping(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> bool { a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y } -fn overlap(a: &Rect, b: &Rect) -> Option { +fn overlap(a: ratatui::layout::Rect, b: ratatui::layout::Rect) -> Option { if !is_overlapping(a, b) { return None; } @@ -75,5 +74,5 @@ fn overlap(a: &Rect, b: &Rect) -> Option { let y = a.y.max(b.y); let width = (a.x + a.width).min(b.x + b.width) - x; let height = (a.y + a.height).min(b.y + b.height) - y; - Some(Rect { x, y, width, height }) + Some(ratatui::layout::Rect { x, y, width, height }) } diff --git a/yazi-plugin/src/elements/constraint.rs b/yazi-plugin/src/elements/constraint.rs index 69b25ff1b..6bb86da59 100644 --- a/yazi-plugin/src/elements/constraint.rs +++ b/yazi-plugin/src/elements/constraint.rs @@ -5,35 +5,36 @@ pub struct Constraint(pub(super) ratatui::layout::Constraint); impl Constraint { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let constraint = lua.create_table()?; - - constraint.raw_set( - "Min", - lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Min(n))))?, - )?; - constraint.raw_set( - "Max", - lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Max(n))))?, - )?; - constraint.raw_set( - "Length", - lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Length(n))))?, - )?; - constraint.raw_set( - "Percentage", - lua - .create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Percentage(n))))?, - )?; - constraint.raw_set( - "Ratio", - lua.create_function(|_, (a, b): (u32, u32)| { - Ok(Constraint(ratatui::layout::Constraint::Ratio(a, b))) - })?, - )?; - constraint.raw_set( - "Fill", - lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Fill(n))))?, - )?; + let constraint = lua.create_table_from([ + ( + "Min", + lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Min(n))))?, + ), + ( + "Max", + lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Max(n))))?, + ), + ( + "Length", + lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Length(n))))?, + ), + ( + "Percentage", + lua.create_function(|_, n: u16| { + Ok(Constraint(ratatui::layout::Constraint::Percentage(n))) + })?, + ), + ( + "Ratio", + lua.create_function(|_, (a, b): (u32, u32)| { + Ok(Constraint(ratatui::layout::Constraint::Ratio(a, b))) + })?, + ), + ( + "Fill", + lua.create_function(|_, n: u16| Ok(Constraint(ratatui::layout::Constraint::Fill(n))))?, + ), + ])?; ui.raw_set("Constraint", constraint) } diff --git a/yazi-plugin/src/elements/elements.rs b/yazi-plugin/src/elements/elements.rs index c835174e6..1fe406e7a 100644 --- a/yazi-plugin/src/elements/elements.rs +++ b/yazi-plugin/src/elements/elements.rs @@ -6,10 +6,6 @@ use crate::cast_to_renderable; pub fn pour(lua: &Lua) -> mlua::Result<()> { let ui = lua.create_table()?; - // Register - super::Padding::register(lua)?; - super::Rect::register(lua)?; - // Install super::Bar::install(lua, &ui)?; super::Border::install(lua, &ui)?; diff --git a/yazi-plugin/src/elements/gauge.rs b/yazi-plugin/src/elements/gauge.rs index 86af590aa..4443e2b66 100644 --- a/yazi-plugin/src/elements/gauge.rs +++ b/yazi-plugin/src/elements/gauge.rs @@ -1,12 +1,12 @@ use mlua::{AnyUserData, ExternalError, Lua, Table, UserData, UserDataMethods, Value}; use ratatui::widgets::Widget; -use super::{RectRef, Renderable, Span}; +use super::{Rect, Renderable, Span}; use crate::elements::Style; #[derive(Clone, Default)] pub struct Gauge { - area: ratatui::layout::Rect, + area: Rect, ratio: f64, label: Option>, @@ -18,7 +18,7 @@ impl Gauge { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { ui.raw_set( "Gauge", - lua.create_function(|_, area: RectRef| Ok(Gauge { area: *area, ..Default::default() }))?, + lua.create_function(|_, area: Rect| Ok(Gauge { area, ..Default::default() }))?, ) } } @@ -59,7 +59,7 @@ impl UserData for Gauge { } impl Renderable for Gauge { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { let mut gauge = ratatui::widgets::Gauge::default() @@ -71,7 +71,7 @@ impl Renderable for Gauge { gauge = gauge.label(s) } - gauge.render(self.area, buf); + gauge.render(*self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf) } diff --git a/yazi-plugin/src/elements/layout.rs b/yazi-plugin/src/elements/layout.rs index 8b3eaa463..f39578855 100644 --- a/yazi-plugin/src/elements/layout.rs +++ b/yazi-plugin/src/elements/layout.rs @@ -1,7 +1,6 @@ use mlua::{AnyUserData, Lua, Table, UserData, UserDataMethods}; -use super::{Constraint, Rect, RectRef}; -use crate::bindings::Cast; +use super::{Constraint, Rect}; const HORIZONTAL: bool = true; const VERTICAL: bool = false; @@ -61,7 +60,7 @@ impl UserData for Layout { ud.borrow_mut::()?.constraints = value.into_iter().map(|c| c.0).collect(); Ok(ud) }); - methods.add_method("split", |lua, me, value: RectRef| { + methods.add_method("split", |lua, me, value: Rect| { let mut layout = ratatui::layout::Layout::new( if me.direction == VERTICAL { ratatui::layout::Direction::Vertical @@ -76,11 +75,7 @@ impl UserData for Layout { layout = layout.vertical_margin(margin.vertical); } - let mut chunks = Vec::with_capacity(me.constraints.len()); - for chunk in &*layout.split(*value) { - chunks.push(Rect::cast(lua, *chunk)?); - } - Ok(chunks) + lua.create_sequence_from(layout.split(*value).iter().map(|chunk| Rect::from(*chunk))) }); } } diff --git a/yazi-plugin/src/elements/list.rs b/yazi-plugin/src/elements/list.rs index 9f95d8b84..20f91932d 100644 --- a/yazi-plugin/src/elements/list.rs +++ b/yazi-plugin/src/elements/list.rs @@ -1,12 +1,12 @@ use mlua::{ExternalError, FromLua, Lua, Table, UserData, Value}; use ratatui::widgets::Widget; -use super::{Line, RectRef, Renderable, Span}; +use super::{Line, Rect, Renderable, Span}; // --- List #[derive(Clone)] pub struct List { - area: ratatui::layout::Rect, + area: Rect, inner: ratatui::widgets::List<'static>, } @@ -15,8 +15,8 @@ impl List { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { ui.raw_set( "List", - lua.create_function(|_, (area, items): (RectRef, Vec)| { - Ok(Self { area: *area, inner: ratatui::widgets::List::new(items) }) + lua.create_function(|_, (area, items): (Rect, Vec)| { + Ok(Self { area, inner: ratatui::widgets::List::new(items) }) })?, ) } @@ -29,10 +29,10 @@ impl UserData for List { } impl Renderable for List { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { - self.inner.render(self.area, buf); + self.inner.render(*self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf) } diff --git a/yazi-plugin/src/elements/padding.rs b/yazi-plugin/src/elements/padding.rs index 212eba024..01a4e47a3 100644 --- a/yazi-plugin/src/elements/padding.rs +++ b/yazi-plugin/src/elements/padding.rs @@ -1,58 +1,43 @@ -use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataRef}; +use std::ops::Deref; -use crate::bindings::Cast; +use mlua::{FromLua, Lua, Table, UserData}; -pub type PaddingRef<'lua> = UserDataRef<'lua, ratatui::widgets::Padding>; +#[derive(Clone, Copy, FromLua)] +pub struct Padding(ratatui::widgets::Padding); -pub struct Padding; +impl Deref for Padding { + type Target = ratatui::widgets::Padding; + + fn deref(&self) -> &Self::Target { &self.0 } +} impl Padding { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|lua, args: (Table, u16, u16, u16, u16)| { - Self::cast(lua, ratatui::widgets::Padding::new(args.1, args.2, args.3, args.4)) + let new = lua.create_function(|_, args: (Table, u16, u16, u16, u16)| { + Ok(Self(ratatui::widgets::Padding::new(args.1, args.2, args.3, args.4))) })?; let padding = lua.create_table_from([ ( "left", - lua.create_function(|lua, left: u16| { - Self::cast(lua, ratatui::widgets::Padding::left(left)) - })?, + lua.create_function(|_, left: u16| Ok(Self(ratatui::widgets::Padding::left(left))))?, ), ( "right", - lua.create_function(|lua, right: u16| { - Self::cast(lua, ratatui::widgets::Padding::right(right)) - })?, - ), - ( - "top", - lua - .create_function(|lua, top: u16| Self::cast(lua, ratatui::widgets::Padding::top(top)))?, + lua.create_function(|_, right: u16| Ok(Self(ratatui::widgets::Padding::right(right))))?, ), + ("top", lua.create_function(|_, top: u16| Ok(Self(ratatui::widgets::Padding::top(top))))?), ( "bottom", - lua.create_function(|lua, bottom: u16| { - Self::cast(lua, ratatui::widgets::Padding::bottom(bottom)) - })?, - ), - ( - "x", - lua.create_function(|lua, x: u16| { - Self::cast(lua, ratatui::widgets::Padding::new(x, x, 0, 0)) - })?, - ), - ( - "y", - lua.create_function(|lua, y: u16| { - Self::cast(lua, ratatui::widgets::Padding::new(0, 0, y, y)) - })?, + lua + .create_function(|_, bottom: u16| Ok(Self(ratatui::widgets::Padding::bottom(bottom))))?, ), + ("x", lua.create_function(|_, x: u16| Ok(Self(ratatui::widgets::Padding::new(x, x, 0, 0))))?), + ("y", lua.create_function(|_, y: u16| Ok(Self(ratatui::widgets::Padding::new(0, 0, y, y))))?), ( "xy", - lua.create_function(|lua, xy: u16| { - Self::cast(lua, ratatui::widgets::Padding::new(xy, xy, xy, xy)) - })?, + lua + .create_function(|_, xy: u16| Ok(Self(ratatui::widgets::Padding::new(xy, xy, xy, xy))))?, ), ])?; @@ -60,20 +45,13 @@ impl Padding { ui.raw_set("Padding", padding) } - - pub fn register(lua: &Lua) -> mlua::Result<()> { - // TODO: remove this - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("left", |_, me| Ok(me.left)); - reg.add_field_method_get("right", |_, me| Ok(me.right)); - reg.add_field_method_get("top", |_, me| Ok(me.top)); - reg.add_field_method_get("bottom", |_, me| Ok(me.bottom)); - }) - } } -impl Cast for Padding { - fn cast(lua: &Lua, data: ratatui::widgets::Padding) -> mlua::Result { - lua.create_any_userdata(data) +impl UserData for Padding { + fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("left", |_, me| Ok(me.left)); + fields.add_field_method_get("right", |_, me| Ok(me.right)); + fields.add_field_method_get("top", |_, me| Ok(me.top)); + fields.add_field_method_get("bottom", |_, me| Ok(me.bottom)); } } diff --git a/yazi-plugin/src/elements/paragraph.rs b/yazi-plugin/src/elements/paragraph.rs index 9ace98926..884c691c6 100644 --- a/yazi-plugin/src/elements/paragraph.rs +++ b/yazi-plugin/src/elements/paragraph.rs @@ -2,7 +2,7 @@ use ansi_to_tui::IntoText; use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, Table, UserData}; use ratatui::widgets::Widget; -use super::{Line, RectRef, Renderable}; +use super::{Line, Rect, Renderable}; // Alignment const LEFT: u8 = 0; @@ -14,9 +14,9 @@ pub const WRAP_NO: u8 = 0; pub const WRAP: u8 = 1; pub const WRAP_TRIM: u8 = 2; -#[derive(Clone, Debug, Default)] +#[derive(Clone, Default)] pub struct Paragraph { - pub area: ratatui::layout::Rect, + pub area: Rect, pub text: ratatui::text::Text<'static>, pub style: ratatui::style::Style, @@ -26,16 +26,12 @@ pub struct Paragraph { impl Paragraph { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|_, (_, area, lines): (Table, RectRef, Vec)| { - Ok(Paragraph { - area: *area, - text: lines.into_iter().map(|s| s.0).collect(), - ..Default::default() - }) + let new = lua.create_function(|_, (_, area, lines): (Table, Rect, Vec)| { + Ok(Paragraph { area, text: lines.into_iter().map(|s| s.0).collect(), ..Default::default() }) })?; - let parse = lua.create_function(|_, (area, code): (RectRef, mlua::String)| { - Ok(Paragraph { area: *area, text: code.into_text().into_lua_err()?, ..Default::default() }) + let parse = lua.create_function(|_, (area, code): (Rect, mlua::String)| { + Ok(Paragraph { area, text: code.into_text().into_lua_err()?, ..Default::default() }) })?; let paragraph = lua.create_table_from([ @@ -84,7 +80,7 @@ impl UserData for Paragraph { } impl Renderable for Paragraph { - fn area(&self) -> ratatui::layout::Rect { self.area } + fn area(&self) -> ratatui::layout::Rect { *self.area } fn render(self: Box, buf: &mut ratatui::buffer::Buffer) { let mut p = ratatui::widgets::Paragraph::new(self.text).style(self.style); @@ -93,7 +89,7 @@ impl Renderable for Paragraph { p = p.wrap(ratatui::widgets::Wrap { trim: self.wrap == WRAP_TRIM }); } - p.alignment(self.alignment).render(self.area, buf); + p.alignment(self.alignment).render(*self.area, buf); } fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(self.clone()).render(buf) } diff --git a/yazi-plugin/src/elements/position.rs b/yazi-plugin/src/elements/position.rs index 41a5358b1..171fa8cba 100644 --- a/yazi-plugin/src/elements/position.rs +++ b/yazi-plugin/src/elements/position.rs @@ -1,39 +1,37 @@ -use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataRef}; +use std::ops::Deref; -use crate::bindings::Cast; +use mlua::{FromLua, Lua, Table, UserData, UserDataFields}; -pub type PositionRef<'lua> = UserDataRef<'lua, ratatui::layout::Position>; +#[derive(Clone, Copy, FromLua)] +pub struct Position(ratatui::layout::Position); -pub struct Position; +impl Deref for Position { + type Target = ratatui::layout::Position; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl From for Position { + fn from(rect: ratatui::layout::Rect) -> Self { Self(rect.as_position()) } +} impl Position { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|lua, (_, args): (Table, Table)| { - Position::cast(lua, ratatui::layout::Position { - x: args.raw_get("x")?, - y: args.raw_get("y")?, - }) + let new = lua.create_function(|_, (_, args): (Table, Table)| { + Ok(Self(ratatui::layout::Position { x: args.raw_get("x")?, y: args.raw_get("y")? })) })?; - let position = - lua.create_table_from([("default", Position::cast(lua, Default::default())?)])?; + let position = lua.create_table_from([("default", Self(Default::default()))])?; position.set_metatable(Some(lua.create_table_from([("__call", new)])?)); ui.raw_set("Position", position) } - - pub fn register(lua: &Lua) -> mlua::Result<()> { - // TODO: remove this - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("x", |_, me| Ok(me.x)); - reg.add_field_method_get("y", |_, me| Ok(me.y)); - }) - } } -impl Cast for Position { - fn cast(lua: &Lua, data: ratatui::layout::Position) -> mlua::Result { - lua.create_any_userdata(data) +impl UserData for Position { + fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("x", |_, me| Ok(me.x)); + fields.add_field_method_get("y", |_, me| Ok(me.y)); } } diff --git a/yazi-plugin/src/elements/rect.rs b/yazi-plugin/src/elements/rect.rs index b8bb479d6..1efddfc6d 100644 --- a/yazi-plugin/src/elements/rect.rs +++ b/yazi-plugin/src/elements/rect.rs @@ -1,72 +1,71 @@ -use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataMethods, UserDataRef}; +use std::ops::Deref; -use super::{PaddingRef, Position, PositionRef}; -use crate::bindings::Cast; +use mlua::{FromLua, Lua, Table, UserData}; -pub type RectRef<'lua> = UserDataRef<'lua, ratatui::layout::Rect>; +use super::{Padding, Position}; -pub struct Rect; +#[derive(Clone, Copy, Default, FromLua)] +pub struct Rect(ratatui::layout::Rect); + +impl Deref for Rect { + type Target = ratatui::layout::Rect; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl From for Rect { + fn from(rect: ratatui::layout::Rect) -> Self { Self(rect) } +} + +impl From for Rect { + fn from(size: ratatui::layout::Size) -> Self { + Self(ratatui::layout::Rect { x: 0, y: 0, width: size.width, height: size.height }) + } +} impl Rect { pub fn install(lua: &Lua, ui: &Table) -> mlua::Result<()> { - let new = lua.create_function(|lua, (_, args): (Table, Table)| { - Rect::cast(lua, ratatui::layout::Rect { + let new = lua.create_function(|_, (_, args): (Table, Table)| { + Ok(Self(ratatui::layout::Rect { x: args.raw_get("x")?, y: args.raw_get("y")?, width: args.raw_get("w")?, height: args.raw_get("h")?, - }) + })) })?; - let rect = - lua.create_table_from([("default", Rect::cast(lua, ratatui::layout::Rect::default())?)])?; + let rect = lua.create_table_from([("default", Self(ratatui::layout::Rect::default()))])?; rect.set_metatable(Some(lua.create_table_from([("__call", new)])?)); ui.raw_set("Rect", rect) } +} - pub fn register(lua: &Lua) -> mlua::Result<()> { - // TODO: remove this - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("x", |_, me| Ok(me.x)); - reg.add_field_method_get("y", |_, me| Ok(me.y)); - reg.add_field_method_get("w", |_, me| Ok(me.width)); - reg.add_field_method_get("h", |_, me| Ok(me.height)); - - reg.add_field_method_get("left", |_, me| Ok(me.left())); - reg.add_field_method_get("right", |_, me| Ok(me.right())); - reg.add_field_method_get("top", |_, me| Ok(me.top())); - reg.add_field_method_get("bottom", |_, me| Ok(me.bottom())); - - reg.add_method("padding", |lua, me, padding: PaddingRef| { - let mut r = *me; - r.x = r.x.saturating_add(padding.left); - r.y = r.y.saturating_add(padding.top); +impl UserData for Rect { + fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("x", |_, me| Ok(me.x)); + fields.add_field_method_get("y", |_, me| Ok(me.y)); + fields.add_field_method_get("w", |_, me| Ok(me.width)); + fields.add_field_method_get("h", |_, me| Ok(me.height)); - r.width = r.width.saturating_sub(padding.left + padding.right); - r.height = r.height.saturating_sub(padding.top + padding.bottom); - Rect::cast(lua, r) - }); - reg.add_method("position", |lua, me, ()| Position::cast(lua, me.as_position())); - reg.add_method("contains", |_, me, position: PositionRef| Ok(me.contains(*position))); - }) + fields.add_field_method_get("left", |_, me| Ok(me.left())); + fields.add_field_method_get("right", |_, me| Ok(me.right())); + fields.add_field_method_get("top", |_, me| Ok(me.top())); + fields.add_field_method_get("bottom", |_, me| Ok(me.bottom())); } -} -impl Cast for Rect { - fn cast(lua: &Lua, data: ratatui::layout::Rect) -> mlua::Result { - lua.create_any_userdata(data) - } -} + fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_method("padding", |_, me, padding: Padding| { + let mut r = **me; + r.x = r.x.saturating_add(padding.left); + r.y = r.y.saturating_add(padding.top); -impl Cast for Rect { - fn cast(lua: &Lua, data: ratatui::layout::Size) -> mlua::Result { - lua.create_any_userdata(ratatui::layout::Rect { - x: 0, - y: 0, - width: data.width, - height: data.height, - }) + r.width = r.width.saturating_sub(padding.left + padding.right); + r.height = r.height.saturating_sub(padding.top + padding.bottom); + Ok(Self(r)) + }); + methods.add_method("position", |_, me, ()| Ok(Position::from(**me))); + methods.add_method("contains", |_, me, position: Position| Ok(me.contains(*position))); } } diff --git a/yazi-plugin/src/external/highlighter.rs b/yazi-plugin/src/external/highlighter.rs index 6ecf3ebda..09047e4c1 100644 --- a/yazi-plugin/src/external/highlighter.rs +++ b/yazi-plugin/src/external/highlighter.rs @@ -93,7 +93,7 @@ impl Highlighter { } Ok(if plain { - Text::from(replace_to_printable(&after.join(""), PREVIEW.tab_size)) + Text::from(replace_to_printable(&after, PREVIEW.tab_size)) } else { Self::highlight_with(before, after, syntax.unwrap()).await? }) diff --git a/yazi-plugin/src/isolate/fetch.rs b/yazi-plugin/src/isolate/fetch.rs index 07d2312b3..c0e6b9353 100644 --- a/yazi-plugin/src/isolate/fetch.rs +++ b/yazi-plugin/src/isolate/fetch.rs @@ -23,7 +23,7 @@ pub async fn fetch(name: &str, files: Vec) -> mlua::Resul } plugin.raw_set("skip", 0)?; - plugin.raw_set("area", Rect::cast(&lua, LAYOUT.load().preview)?)?; + plugin.raw_set("area", Rect::from(LAYOUT.load().preview))?; plugin.raw_set("files", files)?; Handle::current().block_on(plugin.call_async_method("fetch", ())) diff --git a/yazi-plugin/src/isolate/isolate.rs b/yazi-plugin/src/isolate/isolate.rs index 81179dcc9..c49aa341e 100644 --- a/yazi-plugin/src/isolate/isolate.rs +++ b/yazi-plugin/src/isolate/isolate.rs @@ -23,7 +23,6 @@ pub fn slim_lua(name: &str) -> mlua::Result { let ui = lua.create_table()?; elements::Line::install(&lua, &ui)?; elements::Paragraph::install(&lua, &ui)?; - elements::Rect::register(&lua)?; elements::Rect::install(&lua, &ui)?; elements::Span::install(&lua, &ui)?; diff --git a/yazi-plugin/src/isolate/peek.rs b/yazi-plugin/src/isolate/peek.rs index a4e7e5e50..d56be4a6d 100644 --- a/yazi-plugin/src/isolate/peek.rs +++ b/yazi-plugin/src/isolate/peek.rs @@ -40,7 +40,7 @@ pub fn peek( plugin.raw_set("file", File::cast(&lua, file)?)?; plugin.raw_set("_mime", mime)?; plugin.raw_set("skip", skip)?; - plugin.raw_set("area", Rect::cast(&lua, LAYOUT.load().preview)?)?; + plugin.raw_set("area", Rect::from(LAYOUT.load().preview))?; plugin.raw_set("window", Window::default())?; if ct2.is_cancelled() { Ok(()) } else { plugin.call_async_method("peek", ()).await } @@ -68,7 +68,7 @@ pub fn peek_sync(cmd: &Cmd, file: yazi_shared::fs::File, mime: Cow<'static, str> plugin.raw_set("file", File::cast(&LUA, file)?)?; plugin.raw_set("_mime", mime)?; plugin.raw_set("skip", skip)?; - plugin.raw_set("area", Rect::cast(&LUA, LAYOUT.load().preview)?)?; + plugin.raw_set("area", Rect::from(LAYOUT.load().preview))?; plugin.raw_set("window", Window::default())?; plugin.call_method("peek", ()) }); diff --git a/yazi-plugin/src/isolate/preload.rs b/yazi-plugin/src/isolate/preload.rs index 3635a7804..863a2b53e 100644 --- a/yazi-plugin/src/isolate/preload.rs +++ b/yazi-plugin/src/isolate/preload.rs @@ -18,7 +18,7 @@ pub async fn preload(name: &str, file: yazi_shared::fs::File) -> mlua::Result { - use $crate::{bindings::Cast, elements::{Rect, RectRef}}; + use mlua::IntoLua; + use $crate::elements::Rect; - $methods.add_function("area", |lua, (ud, area): (mlua::AnyUserData, Option)| { + $methods.add_function("area", |lua, (ud, area): (mlua::AnyUserData, Option)| { if let Some(r) = area { - ud.borrow_mut::()?.area = *r; - Ok(ud) + ud.borrow_mut::()?.area = r; + ud.into_lua(lua) } else { - Rect::cast(lua, ud.borrow::()?.area) + ud.borrow::()?.area.into_lua(lua) } }); }; diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index 4daacd158..a978a1e34 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -7,7 +7,6 @@ use yazi_dds::Sendable; use yazi_shared::{Layer, emit, event::{Cmd, Data}, render}; use super::Utils; -use crate::elements::RectRef; impl Utils { fn parse_args(t: Table) -> mlua::Result> { @@ -45,13 +44,13 @@ impl Utils { match id { "current" => { LAYOUT.store(Arc::new(yazi_config::Layout { - current: *c.raw_get::<_, RectRef>("_area")?, + current: *c.raw_get::<_, crate::elements::Rect>("_area")?, ..*LAYOUT.load_full() })); } "preview" => { LAYOUT.store(Arc::new(yazi_config::Layout { - preview: *c.raw_get::<_, RectRef>("_area")?, + preview: *c.raw_get::<_, crate::elements::Rect>("_area")?, ..*LAYOUT.load_full() })); } diff --git a/yazi-plugin/src/utils/image.rs b/yazi-plugin/src/utils/image.rs index 94edce3f4..9dfc388a4 100644 --- a/yazi-plugin/src/utils/image.rs +++ b/yazi-plugin/src/utils/image.rs @@ -1,18 +1,18 @@ -use mlua::{IntoLuaMulti, Lua, Table, Value}; +use mlua::{IntoLua, Lua, Table, Value}; use yazi_adapter::{ADAPTOR, Image}; use super::Utils; -use crate::{bindings::Cast, elements::{Rect, RectRef}, url::UrlRef}; +use crate::{elements::Rect, url::UrlRef}; impl Utils { pub(super) fn image(lua: &Lua, ya: &Table) -> mlua::Result<()> { ya.raw_set( "image_show", - lua.create_async_function(|lua, (url, rect): (UrlRef, RectRef)| async move { + lua.create_async_function(|lua, (url, rect): (UrlRef, Rect)| async move { if let Ok(area) = ADAPTOR.image_show(&url, *rect).await { - Rect::cast(lua, area)?.into_lua_multi(lua) + Rect::from(area).into_lua(lua) } else { - Value::Nil.into_lua_multi(lua) + Value::Nil.into_lua(lua) } })?, )?; diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index b409c5618..99d7e790e 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -3,7 +3,7 @@ use yazi_config::{PREVIEW, preview::PreviewWrap}; use yazi_shared::{Layer, PeekError, emit, event::Cmd}; use super::Utils; -use crate::{bindings::Window, cast_to_renderable, elements::{Paragraph, RectRef, Renderable, WRAP, WRAP_NO}, external::Highlighter, file::FileRef}; +use crate::{bindings::Window, cast_to_renderable, elements::{Paragraph, Rect, Renderable, WRAP, WRAP_NO}, external::Highlighter, file::FileRef}; pub struct PreviewLock { pub url: yazi_shared::fs::Url, @@ -37,7 +37,7 @@ impl Utils { ya.raw_set( "preview_code", lua.create_async_function(|lua, t: Table| async move { - let area: RectRef = t.raw_get("area")?; + let area: Rect = t.raw_get("area")?; let mut lock = PreviewLock::try_from(t)?; let text = match Highlighter::new(&lock.url).highlight(lock.skip, *area).await { @@ -49,7 +49,7 @@ impl Utils { }; lock.data = vec![Box::new(Paragraph { - area: *area, + area, text, wrap: if PREVIEW.wrap == PreviewWrap::Yes { WRAP } else { WRAP_NO }, ..Default::default() diff --git a/yazi-shared/src/chars.rs b/yazi-shared/src/chars.rs index 5d0035e27..08f34dcb0 100644 --- a/yazi-shared/src/chars.rs +++ b/yazi-shared/src/chars.rs @@ -28,11 +28,11 @@ pub fn strip_trailing_newline(mut s: String) -> String { s } -pub fn replace_to_printable(s: &str, tab_size: u8) -> String { +pub fn replace_to_printable(s: &[String], tab_size: u8) -> String { let mut buf = Vec::new(); - buf.try_reserve_exact(s.len() | 15).unwrap_or_else(|_| panic!()); + buf.try_reserve_exact(s.iter().map(|s| s.len()).sum::() | 15).unwrap_or_else(|_| panic!()); - for &b in s.as_bytes() { + for &b in s.iter().flat_map(|s| s.as_bytes()) { match b { b'\n' => buf.push(b'\n'), b'\t' => { diff --git a/yazi-shared/src/translit/traits.rs b/yazi-shared/src/translit/traits.rs index 3f862e489..094931c02 100644 --- a/yazi-shared/src/translit/traits.rs +++ b/yazi-shared/src/translit/traits.rs @@ -14,14 +14,13 @@ impl Transliterator for &[u8] { } let (ascii, rest) = self.split_at(ascii_len); - let ascii = unsafe { str::from_utf8_unchecked(ascii) }; // Reserve a bit more space to avoid reallocations on longer transliterations // but instead of `+ 16` uses `| 15` to stay in the smallest allocation bucket // for short strings let mut out = String::new(); out.try_reserve_exact(self.len() | 15).unwrap_or_else(|_| panic!()); - out.push_str(ascii); + out.push_str(unsafe { str::from_utf8_unchecked(ascii) }); for c in String::from_utf8_lossy(rest).chars() { if let Some(s) = super::lookup(c) {