This commit is contained in:
sxyazi 2023-09-23 09:51:54 +08:00
parent 03b1e8728b
commit 528e4a6130
No known key found for this signature in database
11 changed files with 110 additions and 118 deletions

View file

@ -18,7 +18,6 @@ mod which;
use app::*;
use executor::*;
use logs::*;
use parser::*;
use root::*;
use signals::*;

View file

@ -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::<Vec<_>>())
}
fn area(args: Vec<&str>) -> Result<Rect> {
fn area(args: &[&str]) -> Result<Rect> {
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::<u8>() {
paragraph = paragraph.alignment(match align {
1 => Alignment::Center,
2 => Alignment::Right,
_ => Alignment::Left,
});
}
paragraph.render(area, buf);
}
}
}

View file

@ -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;

View file

@ -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

View file

@ -13,9 +13,16 @@ function Line:from(spans) return self:new(table.unpack(spans)) end
function Line:to_string()
local s = ""
for _, span in ipairs(self.spans) do
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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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());

View file

@ -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<Lua> = RoCell::new();
pub(crate) static GLOBALS: RoCell<Table> = 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(())
}

View file

@ -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<String> {
pub fn render(cx: &Ctx, area: layout::Rect) -> Result<String> {
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))
})
}
}