diff --git a/yazi-plugin/preset/components/entity.lua b/yazi-plugin/preset/components/entity.lua
index b4285c28..62d783db 100644
--- a/yazi-plugin/preset/components/entity.lua
+++ b/yazi-plugin/preset/components/entity.lua
@@ -79,8 +79,8 @@ end
function Entity:redraw()
local lines = {}
for _, c in ipairs(self._children) do
- local line = ui.Line((type(c[1]) == "string" and self[c[1]] or c[1])(self))
- c.width, lines[#lines + 1] = line:width(), line
+ local line = (type(c[1]) == "string" and self[c[1]] or c[1])(self)
+ c.width, lines[#lines + 1] = ui.width(line), line
end
return ui.Line(lines):style(self:style())
end
@@ -101,12 +101,11 @@ function Entity:ellipsis(max)
for _, child in ipairs(self._children) do
adv = adv + child.width
if adv >= max then
- return not f.cha.is_dir and f.url.ext and "…." .. f.url.ext or "…"
+ return not f.cha.is_dir and f.url.ext and "…." .. f.url.ext or nil
elseif child.id == 4 then
break
end
end
- return "…"
end
-- Children
diff --git a/yazi-plugin/preset/plugins/archive.lua b/yazi-plugin/preset/plugins/archive.lua
index a32ca5e9..cd18c972 100644
--- a/yazi-plugin/preset/plugins/archive.lua
+++ b/yazi-plugin/preset/plugins/archive.lua
@@ -2,7 +2,6 @@ local M = {}
function M:peek(job)
local limit = job.area.h
- local paths, sizes = {}, {}
local files, bound, code = self.list_files({ "-p", tostring(job.file.url) }, job.skip, limit)
if code ~= 0 then
@@ -13,31 +12,40 @@ function M:peek(job)
)
end
+ local left, right = {}, {}
for _, f in ipairs(files) do
local icon = File({
url = Url(f.path),
cha = Cha { kind = f.attr:sub(1, 1) == "D" and 1 or 0 },
}):icon()
- if icon then
- paths[#paths + 1] = ui.Line { ui.Span(" " .. icon.text .. " "):style(icon.style), f.path }
+ if f.size > 0 then
+ right[#right + 1] = string.format(" %s ", ya.readable_size(f.size))
else
- paths[#paths + 1] = f.path
+ right[#right + 1] = " "
end
- if f.size > 0 then
- sizes[#sizes + 1] = string.format(" %s ", ya.readable_size(f.size))
+ if icon then
+ left[#left + 1] = ui.Span(" " .. icon.text .. " "):style(icon.style)
else
- sizes[#sizes + 1] = ""
+ left[#left + 1] = " "
end
+
+ left[#left] = ui.Line {
+ left[#left],
+ ya.truncate(f.path, {
+ rtl = true,
+ max = math.max(0, job.area.w - ui.width(left[#left]) - ui.width(right[#right])),
+ }),
+ }
end
if job.skip > 0 and bound < job.skip + limit then
ya.emit("peek", { math.max(0, bound - limit), only_if = job.file.url, upper_bound = true })
else
ya.preview_widget(job, {
- ui.Text(paths):area(job.area),
- ui.Text(sizes):area(job.area):align(ui.Text.RIGHT),
+ ui.Text(left):area(job.area),
+ ui.Text(right):area(job.area):align(ui.Text.RIGHT),
})
end
end
diff --git a/yazi-plugin/src/elements/bar.rs b/yazi-plugin/src/elements/bar.rs
index 98c927a5..8b30dc7a 100644
--- a/yazi-plugin/src/elements/bar.rs
+++ b/yazi-plugin/src/elements/bar.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, Lua, MetaMethod, Table, UserData};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use ratatui::widgets::Borders;
use super::Area;
@@ -13,7 +13,7 @@ pub struct Bar {
}
impl Bar {
- pub fn compose(lua: &Lua) -> mlua::Result
{
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, direction): (Table, u8)| {
Ok(Self { direction: Borders::from_bits_truncate(direction), ..Default::default() })
})?;
@@ -29,7 +29,7 @@ impl Bar {
])?;
bar.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(bar)
+ bar.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/border.rs b/yazi-plugin/src/elements/border.rs
index 1a114911..aa2e1f75 100644
--- a/yazi-plugin/src/elements/border.rs
+++ b/yazi-plugin/src/elements/border.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use ratatui::widgets::{Borders, Widget};
use super::Area;
@@ -24,7 +24,7 @@ pub struct Border {
}
impl Border {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, position): (Table, u8)| {
Ok(Border {
position: ratatui::widgets::Borders::from_bits_truncate(position),
@@ -50,7 +50,7 @@ impl Border {
])?;
border.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(border)
+ border.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/clear.rs b/yazi-plugin/src/elements/clear.rs
index 6a3feba1..1de82560 100644
--- a/yazi-plugin/src/elements/clear.rs
+++ b/yazi-plugin/src/elements/clear.rs
@@ -1,6 +1,6 @@
use std::sync::atomic::{AtomicBool, Ordering};
-use mlua::{Lua, MetaMethod, Table, UserData};
+use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value};
use yazi_adapter::ADAPTOR;
use super::Area;
@@ -13,13 +13,13 @@ pub struct Clear {
}
impl Clear {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, area): (Table, Area)| Ok(Clear { area }))?;
let clear = lua.create_table()?;
clear.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(clear)
+ clear.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/constraint.rs b/yazi-plugin/src/elements/constraint.rs
index 6526dd5b..c2ecad07 100644
--- a/yazi-plugin/src/elements/constraint.rs
+++ b/yazi-plugin/src/elements/constraint.rs
@@ -1,20 +1,22 @@
-use mlua::{FromLua, Lua, Table, UserData};
+use mlua::{FromLua, IntoLua, Lua, UserData, Value};
#[derive(Clone, Copy, Default, FromLua)]
pub struct Constraint(pub(super) ratatui::layout::Constraint);
impl Constraint {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
use ratatui::layout::Constraint as C;
- lua.create_table_from([
- ("Min", lua.create_function(|_, n: u16| Ok(Self(C::Min(n))))?),
- ("Max", lua.create_function(|_, n: u16| Ok(Self(C::Max(n))))?),
- ("Length", lua.create_function(|_, n: u16| Ok(Self(C::Length(n))))?),
- ("Percentage", lua.create_function(|_, n: u16| Ok(Self(C::Percentage(n))))?),
- ("Ratio", lua.create_function(|_, (a, b): (u32, u32)| Ok(Self(C::Ratio(a, b))))?),
- ("Fill", lua.create_function(|_, n: u16| Ok(Self(C::Fill(n))))?),
- ])
+ lua
+ .create_table_from([
+ ("Min", lua.create_function(|_, n: u16| Ok(Self(C::Min(n))))?),
+ ("Max", lua.create_function(|_, n: u16| Ok(Self(C::Max(n))))?),
+ ("Length", lua.create_function(|_, n: u16| Ok(Self(C::Length(n))))?),
+ ("Percentage", lua.create_function(|_, n: u16| Ok(Self(C::Percentage(n))))?),
+ ("Ratio", lua.create_function(|_, (a, b): (u32, u32)| Ok(Self(C::Ratio(a, b))))?),
+ ("Fill", lua.create_function(|_, n: u16| Ok(Self(C::Fill(n))))?),
+ ])?
+ .into_lua(lua)
}
}
diff --git a/yazi-plugin/src/elements/elements.rs b/yazi-plugin/src/elements/elements.rs
index 59714e12..9b3d0a55 100644
--- a/yazi-plugin/src/elements/elements.rs
+++ b/yazi-plugin/src/elements/elements.rs
@@ -23,6 +23,8 @@ pub fn compose(lua: &Lua) -> mlua::Result {
b"Style" => super::Style::compose(lua)?,
b"Table" => super::Table::compose(lua)?,
b"Text" => super::Text::compose(lua)?,
+
+ b"width" => super::Utils::width(lua)?,
_ => return Ok(Value::Nil),
}
.into_lua(lua)
diff --git a/yazi-plugin/src/elements/gauge.rs b/yazi-plugin/src/elements/gauge.rs
index f9235921..3cfe8f25 100644
--- a/yazi-plugin/src/elements/gauge.rs
+++ b/yazi-plugin/src/elements/gauge.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use ratatui::widgets::Widget;
use super::{Area, Span};
@@ -15,13 +15,13 @@ pub struct Gauge {
}
impl Gauge {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, _: Table| Ok(Gauge::default()))?;
let gauge = lua.create_table()?;
gauge.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(gauge)
+ gauge.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/layout.rs b/yazi-plugin/src/elements/layout.rs
index cc75ca8a..1e0ac00e 100644
--- a/yazi-plugin/src/elements/layout.rs
+++ b/yazi-plugin/src/elements/layout.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, Lua, MetaMethod, Table, UserData, UserDataMethods};
+use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use super::{Constraint, Rect};
@@ -13,13 +13,13 @@ pub struct Layout {
}
impl Layout {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, _: Table| Ok(Self::default()))?;
let layout = lua.create_table_from([("HORIZONTAL", HORIZONTAL), ("VERTICAL", VERTICAL)])?;
layout.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(layout)
+ layout.into_lua(lua)
}
}
diff --git a/yazi-plugin/src/elements/line.rs b/yazi-plugin/src/elements/line.rs
index d8083691..e5806bdb 100644
--- a/yazi-plugin/src/elements/line.rs
+++ b/yazi-plugin/src/elements/line.rs
@@ -21,7 +21,7 @@ pub struct Line {
}
impl Line {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, value): (Table, Value)| Line::try_from(value))?;
let parse = lua.create_function(|_, code: mlua::String| {
@@ -47,7 +47,7 @@ impl Line {
])?;
line.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(line)
+ line.into_lua(lua)
}
pub(super) fn render(
@@ -148,26 +148,70 @@ impl UserData for Line {
}
};
- let (mut width, mut last) = (0, None);
- 'outer: for (x, span) in me.inner.iter_mut().enumerate() {
- for (y, c) in span.content.char_indices() {
- width += c.width().unwrap_or(0);
- match last {
- None if width > max - ellipsis.0 => last = Some((false, x, y)),
- Some((false, x, y)) if width > max => {
- last = Some((true, x, y));
- break 'outer;
- }
- _ => {}
+ fn traverse(
+ max: usize,
+ threshold: usize,
+ it: impl Iterator- ,
+ ) -> (Option<(usize, usize, usize)>, bool) {
+ let (mut adv, mut cut) = (0, None);
+ for (x, y, c) in it {
+ adv += c.width().unwrap_or(0);
+ if adv <= threshold {
+ cut = Some((x, y, adv));
+ } else if adv > max {
+ break;
}
}
+ (cut, adv > max)
}
- if let Some((true, x, y)) = last {
- let spans = &mut me.inner.spans;
+ let rtl = t.raw_get("rtl")?;
+ let (cut, remain) = if rtl {
+ traverse(
+ max,
+ max - ellipsis.0,
+ me.inner
+ .iter()
+ .enumerate()
+ .rev()
+ .flat_map(|(x, s)| s.content.char_indices().rev().map(move |(y, c)| (x, y, c))),
+ )
+ } else {
+ traverse(
+ max,
+ max - ellipsis.0,
+ me.inner
+ .iter()
+ .enumerate()
+ .flat_map(|(x, s)| s.content.char_indices().map(move |(y, c)| (x, y, c))),
+ )
+ };
+
+ let Some((x, y, width)) = cut else {
+ me.inner.spans.clear();
+ me.inner.spans.push(ellipsis.1);
+ return Ok(ud);
+ };
+ if !remain {
+ return Ok(ud);
+ }
+
+ let spans = &mut me.inner.spans;
+ let len = match (rtl, width == max) {
+ (a, b) if a == b => spans[x].content[y..].chars().next().map_or(0, |c| c.len_utf8()),
+ _ => 0,
+ };
+
+ if rtl {
match &mut spans[x].content {
- Cow::Borrowed(s) => spans[x].content = Cow::Borrowed(&s[..y]),
- Cow::Owned(s) => s.truncate(y),
+ Cow::Borrowed(s) => spans[x].content = Cow::Borrowed(&s[y + len..]),
+ Cow::Owned(s) => _ = s.drain(..y + len),
+ }
+ spans.splice(..x, [ellipsis.1]);
+ } else {
+ match &mut spans[x].content {
+ Cow::Borrowed(s) => spans[x].content = Cow::Borrowed(&s[..y + len]),
+ Cow::Owned(s) => s.truncate(y + len),
}
spans.truncate(x + 1);
spans.push(ellipsis.1);
@@ -177,3 +221,80 @@ impl UserData for Line {
});
}
}
+
+#[cfg(test)]
+mod tests {
+ use mlua::{UserDataRef, chunk};
+
+ use super::*;
+
+ fn truncate(s: &str, max: usize, rtl: bool) -> String {
+ let lua = Lua::new();
+ let comp = Line::compose(&lua).unwrap();
+ let line: UserDataRef = lua
+ .load(chunk! {
+ return $comp($s):truncate { max = $max, rtl = $rtl }
+ })
+ .call(())
+ .unwrap();
+
+ line.inner.spans.iter().map(|s| s.content.as_ref()).collect()
+ }
+
+ #[test]
+ fn test_truncate() {
+ assert_eq!(truncate("你好,world", 0, false), "");
+ assert_eq!(truncate("你好,world", 1, false), "…");
+ assert_eq!(truncate("你好,world", 2, false), "…");
+
+ assert_eq!(truncate("你好,世界", 3, false), "你…");
+ assert_eq!(truncate("你好,世界", 4, false), "你…");
+ assert_eq!(truncate("你好,世界", 5, false), "你好…");
+
+ assert_eq!(truncate("Hello, world", 5, false), "Hell…");
+ assert_eq!(truncate("Ni好,世界", 3, false), "Ni…");
+ }
+
+ #[test]
+ fn test_truncate_rtl() {
+ assert_eq!(truncate("world,你好", 0, true), "");
+ assert_eq!(truncate("world,你好", 1, true), "…");
+ assert_eq!(truncate("world,你好", 2, true), "…");
+
+ assert_eq!(truncate("你好,世界", 3, true), "…界");
+ assert_eq!(truncate("你好,世界", 4, true), "…界");
+ assert_eq!(truncate("你好,世界", 5, true), "…世界");
+
+ assert_eq!(truncate("Hello, world", 5, true), "…orld");
+ assert_eq!(truncate("你好,Shi界", 3, true), "…界");
+ }
+
+ #[test]
+ fn test_truncate_oboe() {
+ assert_eq!(truncate("Hello, world", 11, false), "Hello, wor…");
+ assert_eq!(truncate("你好,世界", 9, false), "你好,世…");
+ assert_eq!(truncate("你好,世Jie", 9, false), "你好,世…");
+
+ assert_eq!(truncate("Hello, world", 11, true), "…llo, world");
+ assert_eq!(truncate("你好,世界", 9, true), "…好,世界");
+ assert_eq!(truncate("Ni好,世界", 9, true), "…好,世界");
+ }
+
+ #[test]
+ fn test_truncate_exact() {
+ assert_eq!(truncate("Hello, world", 12, false), "Hello, world");
+ assert_eq!(truncate("你好,世界", 10, false), "你好,世界");
+
+ assert_eq!(truncate("Hello, world", 12, true), "Hello, world");
+ assert_eq!(truncate("你好,世界", 10, true), "你好,世界");
+ }
+
+ #[test]
+ fn test_truncate_overflow() {
+ assert_eq!(truncate("Hello, world", 13, false), "Hello, world");
+ assert_eq!(truncate("你好,世界", 11, false), "你好,世界");
+
+ assert_eq!(truncate("Hello, world", 13, true), "Hello, world");
+ assert_eq!(truncate("你好,世界", 11, true), "你好,世界");
+ }
+}
diff --git a/yazi-plugin/src/elements/list.rs b/yazi-plugin/src/elements/list.rs
index 7607a282..5fa9612d 100644
--- a/yazi-plugin/src/elements/list.rs
+++ b/yazi-plugin/src/elements/list.rs
@@ -1,4 +1,4 @@
-use mlua::{ExternalError, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use ratatui::widgets::Widget;
use super::{Area, Text};
@@ -14,7 +14,7 @@ pub struct List {
}
impl List {
- pub fn compose(lua: &Lua) -> mlua::Result
{
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, seq): (Table, Table)| {
let mut items = Vec::with_capacity(seq.raw_len());
for v in seq.sequence_values::() {
@@ -27,7 +27,7 @@ impl List {
let list = lua.create_table()?;
list.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(list)
+ list.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/mod.rs b/yazi-plugin/src/elements/mod.rs
index 27caddee..5987df66 100644
--- a/yazi-plugin/src/elements/mod.rs
+++ b/yazi-plugin/src/elements/mod.rs
@@ -1,3 +1,3 @@
#![allow(clippy::module_inception)]
-yazi_macro::mod_flat!(area bar border cell clear constraint elements gauge layout line list pad pos rect renderable row span style table text);
+yazi_macro::mod_flat!(area bar border cell clear constraint elements gauge layout line list pad pos rect renderable row span style table text utils);
diff --git a/yazi-plugin/src/elements/pad.rs b/yazi-plugin/src/elements/pad.rs
index 36ee5044..3053797b 100644
--- a/yazi-plugin/src/elements/pad.rs
+++ b/yazi-plugin/src/elements/pad.rs
@@ -1,6 +1,6 @@
use std::ops::{Add, AddAssign, Deref};
-use mlua::{FromLua, Lua, MetaMethod, Table, UserData};
+use mlua::{FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
#[derive(Clone, Copy, Default, FromLua)]
pub struct Pad(ratatui::widgets::Padding);
@@ -16,7 +16,7 @@ impl From for Pad {
}
impl Pad {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new =
lua.create_function(|_, (_, top, right, bottom, left): (Table, u16, u16, u16, u16)| {
Ok(Self(ratatui::widgets::Padding::new(left, right, top, bottom)))
@@ -47,7 +47,7 @@ impl Pad {
])?;
pad.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(pad)
+ pad.into_lua(lua)
}
}
diff --git a/yazi-plugin/src/elements/pos.rs b/yazi-plugin/src/elements/pos.rs
index dc07cb51..e8b3fce0 100644
--- a/yazi-plugin/src/elements/pos.rs
+++ b/yazi-plugin/src/elements/pos.rs
@@ -1,6 +1,6 @@
use std::{ops::Deref, str::FromStr};
-use mlua::{AnyUserData, ExternalResult, Lua, MetaMethod, Table, UserData};
+use mlua::{AnyUserData, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use super::Pad;
@@ -46,13 +46,13 @@ impl TryFrom for Pos {
}
impl Pos {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, t): (Table, Table)| Self::try_from(t))?;
let position = lua.create_table()?;
position.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(position)
+ position.into_lua(lua)
}
pub fn new_input(t: mlua::Table) -> mlua::Result {
diff --git a/yazi-plugin/src/elements/rect.rs b/yazi-plugin/src/elements/rect.rs
index c678cb3d..e5b52d4e 100644
--- a/yazi-plugin/src/elements/rect.rs
+++ b/yazi-plugin/src/elements/rect.rs
@@ -1,6 +1,6 @@
use std::ops::Deref;
-use mlua::{FromLua, Lua, MetaMethod, Table, UserData};
+use mlua::{FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use super::Pad;
@@ -24,7 +24,7 @@ impl From for Rect {
}
impl Rect {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, args): (Table, Table)| {
Ok(Self(ratatui::layout::Rect {
x: args.raw_get("x").unwrap_or_default(),
@@ -37,7 +37,7 @@ impl Rect {
let rect = lua.create_table_from([("default", Self(ratatui::layout::Rect::default()))])?;
rect.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(rect)
+ rect.into_lua(lua)
}
pub(super) fn pad(self, pad: Pad) -> Self {
diff --git a/yazi-plugin/src/elements/row.rs b/yazi-plugin/src/elements/row.rs
index 5ac080e9..378c143d 100644
--- a/yazi-plugin/src/elements/row.rs
+++ b/yazi-plugin/src/elements/row.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, Table, UserData, Value};
+use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, Value};
use super::Cell;
@@ -14,7 +14,7 @@ pub struct Row {
}
impl Row {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, cells): (Table, Vec)| {
Ok(Self { cells, ..Default::default() })
})?;
@@ -22,7 +22,7 @@ impl Row {
let row = lua.create_table()?;
row.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(row)
+ row.into_lua(lua)
}
}
diff --git a/yazi-plugin/src/elements/span.rs b/yazi-plugin/src/elements/span.rs
index 98e2d756..e7a1ef74 100644
--- a/yazi-plugin/src/elements/span.rs
+++ b/yazi-plugin/src/elements/span.rs
@@ -1,6 +1,6 @@
use std::borrow::Cow;
-use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use unicode_width::UnicodeWidthChar;
const EXPECTED: &str = "expected a string or Span";
@@ -8,13 +8,13 @@ const EXPECTED: &str = "expected a string or Span";
pub struct Span(pub(super) ratatui::text::Span<'static>);
impl Span {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, value): (Table, Value)| Span::try_from(value))?;
let span = lua.create_table()?;
span.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(span)
+ span.into_lua(lua)
}
pub(super) fn truncate(&mut self, max: usize) -> usize {
diff --git a/yazi-plugin/src/elements/style.rs b/yazi-plugin/src/elements/style.rs
index 11411d23..d42590a4 100644
--- a/yazi-plugin/src/elements/style.rs
+++ b/yazi-plugin/src/elements/style.rs
@@ -1,19 +1,19 @@
use std::str::FromStr;
-use mlua::{AnyUserData, ExternalError, ExternalResult, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
+use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value};
use yazi_shared::theme::Color;
#[derive(Clone, Copy, Default)]
pub struct Style(pub(super) ratatui::style::Style);
impl Style {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, value): (Table, Value)| Self::try_from(value))?;
let style = lua.create_table()?;
style.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(style)
+ style.into_lua(lua)
}
}
diff --git a/yazi-plugin/src/elements/table.rs b/yazi-plugin/src/elements/table.rs
index 24f72851..cd591b15 100644
--- a/yazi-plugin/src/elements/table.rs
+++ b/yazi-plugin/src/elements/table.rs
@@ -1,4 +1,4 @@
-use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, UserData, Value};
+use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, UserData, Value};
use ratatui::widgets::StatefulWidget;
use super::{Area, Row};
@@ -32,7 +32,7 @@ pub struct Table {
}
impl Table {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, seq): (mlua::Table, mlua::Table)| {
let mut rows = Vec::with_capacity(seq.raw_len());
for v in seq.sequence_values::() {
@@ -45,7 +45,7 @@ impl Table {
let table = lua.create_table()?;
table.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(table)
+ table.into_lua(lua)
}
pub fn selected_cell(&self) -> Option<&ratatui::text::Text> {
diff --git a/yazi-plugin/src/elements/text.rs b/yazi-plugin/src/elements/text.rs
index 1b764478..4bff0438 100644
--- a/yazi-plugin/src/elements/text.rs
+++ b/yazi-plugin/src/elements/text.rs
@@ -29,7 +29,7 @@ pub struct Text {
}
impl Text {
- pub fn compose(lua: &Lua) -> mlua::Result {
+ pub fn compose(lua: &Lua) -> mlua::Result {
let new = lua.create_function(|_, (_, value): (Table, Value)| Text::try_from(value))?;
let parse = lua.create_function(|_, code: mlua::String| {
@@ -49,7 +49,7 @@ impl Text {
])?;
text.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?));
- Ok(text)
+ text.into_lua(lua)
}
pub(super) fn render(
diff --git a/yazi-plugin/src/elements/utils.rs b/yazi-plugin/src/elements/utils.rs
new file mode 100644
index 00000000..27dc5beb
--- /dev/null
+++ b/yazi-plugin/src/elements/utils.rs
@@ -0,0 +1,35 @@
+use mlua::{ExternalError, IntoLua, Lua, Value};
+use unicode_width::UnicodeWidthStr;
+
+use super::{Line, Span};
+
+pub(super) struct Utils;
+
+impl Utils {
+ pub(super) fn width(lua: &Lua) -> mlua::Result {
+ let f = lua.create_function(|_, v: Value| match v {
+ Value::String(s) => {
+ let (mut acc, b) = (0, s.as_bytes());
+ for c in b.utf8_chunks() {
+ acc += c.valid().width();
+ if !c.invalid().is_empty() {
+ acc += 1;
+ }
+ }
+ Ok(acc)
+ }
+ Value::UserData(ud) => {
+ if let Ok(line) = ud.borrow::() {
+ Ok(line.inner.width())
+ } else if let Ok(span) = ud.borrow::() {
+ Ok(span.0.width())
+ } else {
+ Err("expected a string, Line, or Span".into_lua_err())?
+ }
+ }
+ _ => Err("expected a string, Line, or Span".into_lua_err())?,
+ })?;
+
+ f.into_lua(lua)
+ }
+}
diff --git a/yazi-plugin/src/utils/text.rs b/yazi-plugin/src/utils/text.rs
index 8edd26e2..e50a46ca 100644
--- a/yazi-plugin/src/utils/text.rs
+++ b/yazi-plugin/src/utils/text.rs
@@ -96,17 +96,20 @@ impl Utils {
#[cfg(test)]
mod tests {
- use mlua::Value;
+ use mlua::chunk;
use super::*;
fn truncate(s: &str, max: usize, rtl: bool) -> String {
let lua = Lua::new();
- let t = lua
- .create_table_from([("max", Value::Integer(max as i64)), ("rtl", Value::Boolean(rtl))])
- .unwrap();
+ let f = Utils::truncate(&lua).unwrap();
- Utils::truncate(&lua).unwrap().call((s, t)).unwrap()
+ lua
+ .load(chunk! {
+ return $f($s, { max = $max, rtl = $rtl })
+ })
+ .call(())
+ .unwrap()
}
#[test]
|