mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: truncate long paths in archive preview file list (#2778)
This commit is contained in:
parent
70e459a011
commit
b6ae5d3ca9
22 changed files with 257 additions and 87 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub struct Line {
|
|||
}
|
||||
|
||||
impl Line {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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<Item = (usize, usize, char)>,
|
||||
) -> (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<Line> = 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), "你好,世界");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
let new = lua.create_function(|_, (_, seq): (Table, Table)| {
|
||||
let mut items = Vec::with_capacity(seq.raw_len());
|
||||
for v in seq.sequence_values::<Value>() {
|
||||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<ratatui::widgets::Padding> for Pad {
|
|||
}
|
||||
|
||||
impl Pad {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<mlua::Table> for Pos {
|
|||
}
|
||||
|
||||
impl Pos {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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<Self> {
|
||||
|
|
|
|||
|
|
@ -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<ratatui::layout::Size> for Rect {
|
|||
}
|
||||
|
||||
impl Rect {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
let new = lua.create_function(|_, (_, cells): (Table, Vec<Cell>)| {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<mlua::Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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::<Value>() {
|
||||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub struct Text {
|
|||
}
|
||||
|
||||
impl Text {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
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(
|
||||
|
|
|
|||
35
yazi-plugin/src/elements/utils.rs
Normal file
35
yazi-plugin/src/elements/utils.rs
Normal file
|
|
@ -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<Value> {
|
||||
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::<Line>() {
|
||||
Ok(line.inner.width())
|
||||
} else if let Ok(span) = ud.borrow::<Span>() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue