From 528e4a61308370de73dea3eddebbcd57216c498a Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sat, 23 Sep 2023 09:51:54 +0800 Subject: [PATCH] .. --- app/src/main.rs | 1 - app/src/parser.rs | 21 ++++++-- app/src/status/layout.rs | 9 +--- plugin/preset/components/status.lua | 73 +++++++++++++++------------- plugin/preset/elements/line.lua | 15 ++++-- plugin/preset/elements/paragraph.lua | 20 ++++++-- plugin/preset/elements/span.lua | 4 +- plugin/preset/layout.lua | 43 ---------------- plugin/src/layout.rs | 20 ++++---- plugin/src/plugin.rs | 10 +++- plugin/src/status.rs | 12 ++--- 11 files changed, 110 insertions(+), 118 deletions(-) delete mode 100644 plugin/preset/layout.lua diff --git a/app/src/main.rs b/app/src/main.rs index 69b3b9f9..63e22eb6 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -18,7 +18,6 @@ mod which; use app::*; use executor::*; use logs::*; -use parser::*; use root::*; use signals::*; diff --git a/app/src/parser.rs b/app/src/parser.rs index 5bce2cd4..ea1b04f9 100644 --- a/app/src/parser.rs +++ b/app/src/parser.rs @@ -1,6 +1,6 @@ use anyhow::Result; use config::theme::Color; -use ratatui::{prelude::{Buffer, Rect}, style::{Modifier, Style}, text::{Line, Span}, widgets::{Paragraph, Widget}}; +use ratatui::{prelude::{Alignment, Buffer, Rect}, style::{Modifier, Style}, text::{Line, Span}, widgets::{Paragraph, Widget}}; pub struct Parser; @@ -69,7 +69,7 @@ impl Parser { Paragraph::new(lines.into_iter().map(|s| Self::line(&s)).collect::>()) } - fn area(args: Vec<&str>) -> Result { + fn area(args: &[&str]) -> Result { Ok(Rect { x: args[0].parse()?, y: args[1].parse()?, @@ -105,13 +105,24 @@ impl Parser { }; let args: Vec<_> = args.split(',').collect(); - if args.len() != 4 { + if args.len() != 5 { continue; } - if let Ok(area) = Self::area(args) { - Self::paragraph(content).render(area, buf); + let Ok(area) = Self::area(&args) else { + continue; + }; + + let mut paragraph = Self::paragraph(content); + if let Ok(align) = args[4].parse::() { + paragraph = paragraph.alignment(match align { + 1 => Alignment::Center, + 2 => Alignment::Right, + _ => Alignment::Left, + }); } + + paragraph.render(area, buf); } } } diff --git a/app/src/status/layout.rs b/app/src/status/layout.rs index 4b2becb4..5737ad1c 100644 --- a/app/src/status/layout.rs +++ b/app/src/status/layout.rs @@ -1,6 +1,6 @@ use core::Ctx; -use ratatui::{buffer::Buffer, layout::{self, Constraint, Direction, Rect}, widgets::Widget}; +use ratatui::{buffer::Buffer, prelude::Rect, widgets::Widget}; use tracing::info; use crate::parser::Parser; @@ -15,12 +15,7 @@ impl<'a> Layout<'a> { impl<'a> Widget for Layout<'a> { fn render(self, area: Rect, buf: &mut Buffer) { - let chunks = layout::Layout::new() - .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) - .split(area); - - let x = plugin::Status::layout(self.cx, area); + let x = plugin::Status::render(self.cx, area); if x.is_err() { info!("{:?}", x); return; diff --git a/plugin/preset/components/status.lua b/plugin/preset/components/status.lua index b3ec2943..77ddee71 100644 --- a/plugin/preset/components/status.lua +++ b/plugin/preset/components/status.lua @@ -1,57 +1,46 @@ -function layout(area) - local chunks = yazi - .Layout() - :direction(false) - :constraints({ yazi.Constraint.Percentage(50), yazi.Constraint.Percentage(50) }) - :split(area) +Status = {} - return yazi.Paragraph.render( - yazi.Paragraph(mode(), size(), name()):area(chunks[1]), - yazi.Paragraph(permissions(), percentage(), position()):area(chunks[2]) - ) -end - -function mode() +function Status.mode() local mode = cx.manager.mode:upper() if mode == "UNSET" then mode = "UN-SET" end - return yazi.Line( - yazi.Span(THEME.status.separator.opening):fg(THEME.status.mode_normal.bg), - yazi.Span(" " .. mode .. " "):style(THEME.status.mode_normal) + return ui.Line( + ui.Span(THEME.status.separator.opening):fg(THEME.status.mode_normal.bg), + ui.Span(" " .. mode .. " "):style(THEME.status.mode_normal) ) end -function size() +function Status.size() local hovered = cx.manager.current_hovered if hovered == nil then - return yazi.Span("") + return ui.Span("") end - return yazi.Line( - yazi.Span(" " .. hovered.length .. " "):fg(THEME.status.mode_normal.bg):bg(THEME.status.fancy.bg), - yazi.Span(THEME.status.separator.closing):fg(THEME.status.fancy.bg) + return ui.Line( + ui.Span(" " .. hovered.length .. " "):fg(THEME.status.mode_normal.bg):bg(THEME.status.fancy.bg), + ui.Span(THEME.status.separator.closing):fg(THEME.status.fancy.bg) ) end -function name() +function Status.name() local hovered = cx.manager.current_hovered if hovered == nil then - return yazi.Span("") + return ui.Span("") end - return yazi.Span(" " .. utils.basename(hovered.url)) + return ui.Span(" " .. utils.basename(hovered.url)) end -function permissions() +function Status.permissions() local hovered = cx.manager.current_hovered if hovered == nil then - return yazi.Span("") + return ui.Span("") end if hovered.permissions == nil then - return yazi.Span("") + return ui.Span("") end local spans = {} @@ -65,12 +54,12 @@ function permissions() elseif c == "x" or c == "s" or c == "S" or c == "t" or c == "T" then style = THEME.status.permissions_x end - spans[i] = yazi.Span(c):style(style) + spans[i] = ui.Span(c):style(style) end - return yazi.Line:from(spans) + return ui.Line:from(spans) end -function percentage() +function Status.percentage() local percent = 0 local cursor = cx.manager.current_cursor local length = cx.manager.current_length @@ -84,14 +73,28 @@ function percentage() percent = string.format(" %3d%% ", percent) end - return yazi.Line( - yazi.Span(THEME.status.separator.opening):fg(THEME.status.fancy.bg), - yazi.Span(percent):fg(THEME.status.mode_normal.bg):bg(THEME.status.fancy.bg) + return ui.Line( + ui.Span(THEME.status.separator.opening):fg(THEME.status.fancy.bg), + ui.Span(percent):fg(THEME.status.mode_normal.bg):bg(THEME.status.fancy.bg) ) end -function position() +function Status.position() local cursor = cx.manager.current_cursor local length = cx.manager.current_length - return yazi.Span(string.format(" %d/%d ", cursor + 1, length)) + return ui.Span(string.format(" %d/%d ", cursor + 1, length)) +end + +function Status:render(area) + local chunks = ui.Layout() + :direction(ui.Direction.HORIZONTAL) + :constraints({ ui.Constraint.Percentage(50), ui.Constraint.Percentage(50) }) + :split(area) + + local left = ui.Line(self.mode(), self.size(), self.name()) + local right = ui.Line(self.permissions(), self.percentage(), self.position()) + return ui.Paragraph.render( + ui.Paragraph(left):area(chunks[1]), + ui.Paragraph(right):align(ui.Alignment.RIGHT):area(chunks[2]) + ) end diff --git a/plugin/preset/elements/line.lua b/plugin/preset/elements/line.lua index 8f04ffd0..633bf5f0 100644 --- a/plugin/preset/elements/line.lua +++ b/plugin/preset/elements/line.lua @@ -13,8 +13,15 @@ function Line:from(spans) return self:new(table.unpack(spans)) end function Line:to_string() local s = "" - for _, span in ipairs(self.spans) do - s = s .. span:to_string():gsub("\n", "\\\n") .. "\n" + for _, el in ipairs(self.spans) do + local mt = getmetatable(el) + if mt == ui.Line then + for _, span in ipairs(el.spans) do + s = s .. span:to_string():gsub("\n", "\\\n") .. "\n" + end + else + s = s .. el:to_string():gsub("\n", "\\\n") .. "\n" + end end return s.sub(s, 1, -2) end @@ -24,5 +31,5 @@ setmetatable(Line, { __tostring = function(self) return self:to_string() end, }) -yazi = yazi or {} -yazi.Line = Line +ui = ui or {} +ui.Line = Line diff --git a/plugin/preset/elements/paragraph.lua b/plugin/preset/elements/paragraph.lua index 5682b478..32ed7bdd 100644 --- a/plugin/preset/elements/paragraph.lua +++ b/plugin/preset/elements/paragraph.lua @@ -1,7 +1,13 @@ local Paragraph = {} +local Alignment = { + LEFT = 0, + CENTER = 1, + RIGHT = 2, +} function Paragraph:new(...) local o = { + alignment = 0, position = nil, lines = { ... }, } @@ -12,6 +18,11 @@ end function Paragraph:from(lines) return self:new(table.unpack(lines)) end +function Paragraph:align(align) + self.alignment = align + return self +end + function Paragraph:area(rect) self.position = rect return self @@ -25,8 +36,6 @@ function Paragraph:to_string() return s.sub(s, 1, -2) end -function Paragraph:aaa() return self:to_string() end - function Paragraph.render(...) local s = "R" for _, paragraph in ipairs { ... } do @@ -38,6 +47,8 @@ function Paragraph.render(...) .. paragraph.position.width .. "," .. paragraph.position.height + .. "," + .. paragraph.alignment .. ";" .. paragraph:to_string():gsub("\0", "\\\0") .. "\0" @@ -50,5 +61,6 @@ setmetatable(Paragraph, { __tostring = function(self) return self:to_string() end, }) -yazi = yazi or {} -yazi.Paragraph = Paragraph +ui = ui or {} +ui.Paragraph = Paragraph +ui.Alignment = Alignment diff --git a/plugin/preset/elements/span.lua b/plugin/preset/elements/span.lua index 0a253771..9cdb0902 100644 --- a/plugin/preset/elements/span.lua +++ b/plugin/preset/elements/span.lua @@ -120,5 +120,5 @@ setmetatable(Span, { __tostring = function(self) return self:to_string() end, }) -yazi = yazi or {} -yazi.Span = Span +ui = ui or {} +ui.Span = Span diff --git a/plugin/preset/layout.lua b/plugin/preset/layout.lua deleted file mode 100644 index 421f5f99..00000000 --- a/plugin/preset/layout.lua +++ /dev/null @@ -1,43 +0,0 @@ -local Layout = {} - -function Layout:new(...) - local o = { - direction = "R", - dimension = {}, - elements = { ... }, - } - setmetatable(o, self) - self.__index = self - return o -end - -function Layout:from(elements) return self:new(table.unpack(elements)) end - -function Layout:rows(rows) - self.direction = "R" - self.dimension = rows - return self:to_string() -end - -function Layout:cols(cols) - self.direction = "C" - self.dimension = cols - return self:to_string() -end - -function Layout:to_string() - local s = "" - for i, element in ipairs(self.elements) do - if i == 1 then - s = s .. self.direction - end - s = s .. self.dimension[i] .. "\0" .. element:to_string():gsub("\0", "\\\0") - end -end - -setmetatable(Layout, { - __call = function(self, ...) return self:new(...) end, -}) - -yazi = yazi or {} -yazi.Layout = Layout diff --git a/plugin/src/layout.rs b/plugin/src/layout.rs index c14a37bb..497fb7f1 100644 --- a/plugin/src/layout.rs +++ b/plugin/src/layout.rs @@ -1,7 +1,7 @@ use mlua::{AnyUserData, FromLua, Lua, Table, UserData, UserDataMethods, Value}; use ratatui::layout; -use crate::LUA; +use crate::{GLOBALS, LUA}; // --- Rect #[derive(Clone, Copy)] @@ -39,8 +39,7 @@ pub struct Constraint(layout::Constraint); impl Constraint { pub(super) fn install() -> mlua::Result<()> { - let globals = LUA.globals(); - let yazi = globals.get::<_, Table>("yazi")?; + let ui: Table = GLOBALS.get("ui")?; let constraint = LUA.create_table()?; constraint.set( @@ -61,7 +60,7 @@ impl Constraint { constraint .set("Min", LUA.create_function(|_, n: u16| Ok(Constraint(layout::Constraint::Min(n))))?)?; - yazi.set("Constraint", constraint) + ui.set("Constraint", constraint) } } @@ -90,10 +89,13 @@ pub struct Layout { impl Layout { pub(super) fn install() -> mlua::Result<()> { - let globals = LUA.globals(); + let ui: Table = GLOBALS.get("ui")?; + ui.set("Layout", LUA.create_function(|_, ()| Ok(Self::default()))?)?; - let yazi = globals.get::<_, Table>("yazi")?; - yazi.set("Layout", LUA.create_function(|_, ()| Ok(Self::default()))?) + let direction = LUA.create_table()?; + direction.set("HORIZONTAL", false)?; + direction.set("VERTICAL", true)?; + ui.set("Direction", direction) } } @@ -160,9 +162,9 @@ impl UserData for Layout { let mut layout = layout::Layout::new() .direction(if me.direction { - layout::Direction::Horizontal - } else { layout::Direction::Vertical + } else { + layout::Direction::Horizontal }) .constraints(me.constraints.as_slice()); diff --git a/plugin/src/plugin.rs b/plugin/src/plugin.rs index cb2bb95b..09f70777 100644 --- a/plugin/src/plugin.rs +++ b/plugin/src/plugin.rs @@ -1,11 +1,12 @@ use anyhow::Result; use config::THEME; -use mlua::{Lua, LuaSerdeExt}; +use mlua::{Lua, LuaSerdeExt, SerializeOptions, Table}; use shared::RoCell; use crate::layout; pub(crate) static LUA: RoCell = RoCell::new(); +pub(crate) static GLOBALS: RoCell = RoCell::new(); pub fn init() { fn inner() -> Result<()> { @@ -24,12 +25,17 @@ pub fn init() { lua.load(include_str!("../preset/components/status.lua")).exec()?; // Initialize - lua.globals().set("THEME", lua.to_value(&*THEME)?)?; LUA.init(lua); + GLOBALS.init(LUA.globals()); + // Install layout::Layout::install()?; layout::Constraint::install()?; + let options = + SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false); + GLOBALS.set("THEME", LUA.to_value_with(&*THEME, options)?)?; + Ok(()) } diff --git a/plugin/src/status.rs b/plugin/src/status.rs index 52965aa0..fa02d1bb 100644 --- a/plugin/src/status.rs +++ b/plugin/src/status.rs @@ -1,9 +1,9 @@ use core::Ctx; -use mlua::{Function, Result}; +use mlua::{Result, Table, TableExt}; use ratatui::layout; -use crate::{bindings, Rect, LUA}; +use crate::{bindings, Rect, GLOBALS, LUA}; pub struct Status; @@ -16,16 +16,16 @@ impl Status { let cx = LUA.create_table()?; cx.set("manager", manager)?; cx.set("tasks", tasks)?; - LUA.globals().set("cx", cx)?; + GLOBALS.set("cx", cx)?; f() }) } - pub fn layout(cx: &Ctx, area: layout::Rect) -> Result { + pub fn render(cx: &Ctx, area: layout::Rect) -> Result { Self::scope(cx, || { - let layout: Function = LUA.globals().get("layout")?; - layout.call::<_, String>(Rect::from(area)) + let status: Table = GLOBALS.get("Status")?; + status.call_method::<_, String>("render", Rect::from(area)) }) } }