mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: add the area() API for renderable elements (#1667)
This commit is contained in:
parent
ac196f211e
commit
1a1820cf77
9 changed files with 54 additions and 15 deletions
|
|
@ -4,7 +4,7 @@ function M:peek()
|
||||||
local limit = self.area.h
|
local limit = self.area.h
|
||||||
local paths, sizes = {}, {}
|
local paths, sizes = {}, {}
|
||||||
|
|
||||||
local files, bound, code = self:list_files({ "-p", tostring(self.file.url) }, self.skip, limit)
|
local files, bound, code = self.list_files({ "-p", tostring(self.file.url) }, self.skip, limit)
|
||||||
if code ~= 0 then
|
if code ~= 0 then
|
||||||
return ya.preview_widgets(self, {
|
return ya.preview_widgets(self, {
|
||||||
ui.Paragraph(self.area, {
|
ui.Paragraph(self.area, {
|
||||||
|
|
@ -53,7 +53,7 @@ function M:seek(units)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spawn_7z(args)
|
function M.spawn_7z(args)
|
||||||
local last_error = nil
|
local last_error = nil
|
||||||
local try = function(name)
|
local try = function(name)
|
||||||
local stdout = args[1] == "l" and Command.PIPED or Command.NULL
|
local stdout = args[1] == "l" and Command.PIPED or Command.NULL
|
||||||
|
|
@ -88,8 +88,8 @@ end
|
||||||
--- 1: failed to spawn
|
--- 1: failed to spawn
|
||||||
--- 2: wrong password
|
--- 2: wrong password
|
||||||
--- 3: partial success
|
--- 3: partial success
|
||||||
function M:list_files(args, skip, limit)
|
function M.list_files(args, skip, limit)
|
||||||
local child = self:spawn_7z { "l", "-ba", "-slt", table.unpack(args) }
|
local child = M.spawn_7z { "l", "-ba", "-slt", table.unpack(args) }
|
||||||
if not child then
|
if not child then
|
||||||
return {}, 0, 1
|
return {}, 0, 1
|
||||||
end
|
end
|
||||||
|
|
@ -98,7 +98,7 @@ function M:list_files(args, skip, limit)
|
||||||
local key, value = "", ""
|
local key, value = "", ""
|
||||||
repeat
|
repeat
|
||||||
local next, event = child:read_line()
|
local next, event = child:read_line()
|
||||||
if event == 1 and self:is_encrypted(next) then
|
if event == 1 and M.is_encrypted(next) then
|
||||||
code = 2
|
code = 2
|
||||||
break
|
break
|
||||||
elseif event == 1 then
|
elseif event == 1 then
|
||||||
|
|
@ -145,8 +145,8 @@ end
|
||||||
--- 1: failed to spawn
|
--- 1: failed to spawn
|
||||||
--- 2: wrong password
|
--- 2: wrong password
|
||||||
--- 3: partial success
|
--- 3: partial success
|
||||||
function M:list_meta(args)
|
function M.list_meta(args)
|
||||||
local child = self:spawn_7z { "l", "-slt", table.unpack(args) }
|
local child = M.spawn_7z { "l", "-slt", table.unpack(args) }
|
||||||
if not child then
|
if not child then
|
||||||
return nil, 1
|
return nil, 1
|
||||||
end
|
end
|
||||||
|
|
@ -157,7 +157,7 @@ function M:list_meta(args)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
local next, event = child:read_line()
|
local next, event = child:read_line()
|
||||||
if event == 1 and self:is_encrypted(next) then
|
if event == 1 and M.is_encrypted(next) then
|
||||||
code = 2
|
code = 2
|
||||||
break
|
break
|
||||||
elseif event == 1 then
|
elseif event == 1 then
|
||||||
|
|
@ -178,8 +178,8 @@ function M:list_meta(args)
|
||||||
return typ ~= "" and typ or nil, code
|
return typ ~= "" and typ or nil, code
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:is_encrypted(s) return s:find(" Wrong password", 1, true) end
|
function M.is_encrypted(s) return s:find(" Wrong password", 1, true) end
|
||||||
|
|
||||||
function M:is_tar(url) return require("archive"):list_meta { "-p", tostring(url) } == "tar" end
|
function M.is_tar(url) return M.list_meta { "-p", tostring(url) } == "tar" end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -48,13 +48,13 @@ function M:try_with(from, pwd, to)
|
||||||
end
|
end
|
||||||
|
|
||||||
local archive = require("archive")
|
local archive = require("archive")
|
||||||
local child, code = archive:spawn_7z { "x", "-aou", "-p" .. pwd, "-o" .. tostring(tmp), tostring(from) }
|
local child, code = archive.spawn_7z { "x", "-aou", "-p" .. pwd, "-o" .. tostring(tmp), tostring(from) }
|
||||||
if not child then
|
if not child then
|
||||||
fail("Spawn `7z` and `7zz` both commands failed, error code %s", code)
|
fail("Spawn `7z` and `7zz` both commands failed, error code %s", code)
|
||||||
end
|
end
|
||||||
|
|
||||||
local output, err = child:wait_with_output()
|
local output, err = child:wait_with_output()
|
||||||
if output and output.status.code == 2 and archive:is_encrypted(output.stderr) then
|
if output and output.status.code == 2 and archive.is_encrypted(output.stderr) then
|
||||||
fs.remove("dir_clean", tmp)
|
fs.remove("dir_clean", tmp)
|
||||||
return true -- Need to retry
|
return true -- Need to retry
|
||||||
end
|
end
|
||||||
|
|
@ -77,7 +77,7 @@ function M:tidy(from, to, tmp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local only = #outs == 1
|
local only = #outs == 1
|
||||||
if only and not outs[1].cha.is_dir and require("archive"):is_tar(outs[1].url) then
|
if only and not outs[1].cha.is_dir and require("archive").is_tar(outs[1].url) then
|
||||||
self:entry { tostring(outs[1].url), tostring(to) }
|
self:entry { tostring(outs[1].url), tostring(to) }
|
||||||
fs.remove("file", outs[1].url)
|
fs.remove("file", outs[1].url)
|
||||||
fs.remove("dir", tmp)
|
fs.remove("dir", tmp)
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,13 @@ impl Bar {
|
||||||
|
|
||||||
impl UserData for Bar {
|
impl UserData for Bar {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
crate::impl_style_method!(methods, style);
|
crate::impl_style_method!(methods, style);
|
||||||
|
|
||||||
|
methods.add_function("direction", |_, (ud, symbol): (AnyUserData, u8)| {
|
||||||
|
ud.borrow_mut::<Self>()?.direction = Borders::from_bits_truncate(symbol);
|
||||||
|
Ok(ud)
|
||||||
|
});
|
||||||
methods.add_function("symbol", |_, (ud, symbol): (AnyUserData, String)| {
|
methods.add_function("symbol", |_, (ud, symbol): (AnyUserData, String)| {
|
||||||
ud.borrow_mut::<Self>()?.symbol = symbol;
|
ud.borrow_mut::<Self>()?.symbol = symbol;
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,13 @@ impl Border {
|
||||||
|
|
||||||
impl UserData for Border {
|
impl UserData for Border {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
crate::impl_style_method!(methods, style);
|
crate::impl_style_method!(methods, style);
|
||||||
|
|
||||||
|
methods.add_function("position", |_, (ud, position): (AnyUserData, u8)| {
|
||||||
|
ud.borrow_mut::<Self>()?.position = ratatui::widgets::Borders::from_bits_truncate(position);
|
||||||
|
Ok(ud)
|
||||||
|
});
|
||||||
methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| {
|
methods.add_function("type", |_, (ud, value): (AnyUserData, u8)| {
|
||||||
ud.borrow_mut::<Self>()?.type_ = match value {
|
ud.borrow_mut::<Self>()?.type_ = match value {
|
||||||
ROUNDED => ratatui::widgets::BorderType::Rounded,
|
ROUNDED => ratatui::widgets::BorderType::Rounded,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,11 @@ impl Renderable for Clear {
|
||||||
fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(*self).render(buf); }
|
fn clone_render(&self, buf: &mut ratatui::buffer::Buffer) { Box::new(*self).render(buf); }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserData for Clear {}
|
impl UserData for Clear {
|
||||||
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
const fn is_overlapping(a: &Rect, b: &Rect) -> bool {
|
const fn is_overlapping(a: &Rect, b: &Rect) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ impl Gauge {
|
||||||
|
|
||||||
impl UserData for Gauge {
|
impl UserData for Gauge {
|
||||||
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
crate::impl_style_method!(methods, style);
|
crate::impl_style_method!(methods, style);
|
||||||
|
|
||||||
methods.add_function("percent", |_, (ud, percent): (AnyUserData, u8)| {
|
methods.add_function("percent", |_, (ud, percent): (AnyUserData, u8)| {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,11 @@ impl List {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserData for List {}
|
impl UserData for List {
|
||||||
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Renderable for List {
|
impl Renderable for List {
|
||||||
fn area(&self) -> ratatui::layout::Rect { self.area }
|
fn area(&self) -> ratatui::layout::Rect { self.area }
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ impl Paragraph {
|
||||||
|
|
||||||
impl UserData for Paragraph {
|
impl UserData for Paragraph {
|
||||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
|
crate::impl_area_method!(methods);
|
||||||
crate::impl_style_method!(methods, style);
|
crate::impl_style_method!(methods, style);
|
||||||
crate::impl_style_shorthands!(methods, style);
|
crate::impl_style_shorthands!(methods, style);
|
||||||
|
|
||||||
|
|
@ -76,6 +77,9 @@ impl UserData for Paragraph {
|
||||||
};
|
};
|
||||||
Ok(ud)
|
Ok(ud)
|
||||||
});
|
});
|
||||||
|
methods.add_method("max_width", |_, me, ()| {
|
||||||
|
Ok(me.text.lines.iter().take(me.area.height as usize).map(|l| l.width()).max())
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,22 @@ macro_rules! impl_style_method {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_area_method {
|
||||||
|
($methods:ident) => {
|
||||||
|
use $crate::{bindings::Cast, elements::{Rect, RectRef}};
|
||||||
|
|
||||||
|
$methods.add_function("area", |lua, (ud, area): (mlua::AnyUserData, Option<RectRef>)| {
|
||||||
|
if let Some(r) = area {
|
||||||
|
ud.borrow_mut::<Self>()?.area = *r;
|
||||||
|
Ok(ud)
|
||||||
|
} else {
|
||||||
|
Rect::cast(lua, ud.borrow::<Self>()?.area)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_style_shorthands {
|
macro_rules! impl_style_shorthands {
|
||||||
($methods:ident, $($field:tt).+) => {
|
($methods:ident, $($field:tt).+) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue