mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
2c2e1668fc
commit
e6a4c0e7ab
9 changed files with 97 additions and 93 deletions
|
|
@ -76,7 +76,9 @@ impl App {
|
|||
fn dispatch_render(&mut self) {
|
||||
if let Some(term) = &mut self.term {
|
||||
let _ = term.draw(|f| {
|
||||
plugin::scope(&self.cx, || {
|
||||
f.render_widget(Root::new(&self.cx), f.size());
|
||||
});
|
||||
|
||||
if let Some((x, y)) = self.cx.cursor() {
|
||||
f.set_cursor(x, y);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'a> Folder<'a> {
|
|||
|
||||
impl<'a> Widget for Folder<'a> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let x = plugin::Folder { kind: self.kind as u8 }.render(self.cx, area);
|
||||
let x = plugin::Folder { kind: self.kind as u8 }.render(area);
|
||||
if x.is_err() {
|
||||
info!("{:?}", x);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ impl<'a> Layout<'a> {
|
|||
|
||||
impl<'a> Widget for Layout<'a> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let x = plugin::Status::render(self.cx, area);
|
||||
let x = plugin::Status::render(area);
|
||||
if x.is_err() {
|
||||
info!("{:?}", x);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable"],"version":"0.2"}
|
||||
{"language":"en","version":"0.2","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort"]}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,9 @@ function Folder:by_kind(kind)
|
|||
end
|
||||
end
|
||||
|
||||
function Folder:window(kind)
|
||||
local folder = self:by_kind(kind)
|
||||
if folder ~= nil then
|
||||
return folder.files:slice(folder.offset, MANAGER.layout.folder_height())
|
||||
end
|
||||
end
|
||||
function Folder:window(kind) return (self:by_kind(kind) or {}).window end
|
||||
|
||||
function Folder:hovered(kind)
|
||||
local folder = self:by_kind(kind)
|
||||
return folder and folder.hovered
|
||||
end
|
||||
function Folder:hovered(kind) return (self:by_kind(kind) or {}).hovered end
|
||||
|
||||
function Folder:parent(area)
|
||||
local window = self:window(self.Kind.Parent)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,31 @@
|
|||
use config::THEME;
|
||||
use mlua::{AnyUserData, Function, IntoLua, MetaMethod, UserDataFields, UserDataMethods, Value};
|
||||
use config::{MANAGER, THEME};
|
||||
use mlua::{AnyUserData, Function, IntoLua, MetaMethod, UserData, UserDataFields, UserDataMethods, Value};
|
||||
|
||||
use super::Url;
|
||||
use crate::{layout::Style, LUA};
|
||||
|
||||
pub struct Manager;
|
||||
struct File(core::files::File);
|
||||
|
||||
impl Manager {
|
||||
impl From<&core::files::File> for File {
|
||||
fn from(value: &core::files::File) -> Self { Self(value.clone()) }
|
||||
}
|
||||
|
||||
impl UserData for File {
|
||||
fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("url", |_, me| Ok(Url::from(me.0.url())));
|
||||
fields.add_field_method_get("length", |_, me| Ok(me.0.length()));
|
||||
fields.add_field_method_get("link_to", |_, me| Ok(me.0.link_to().map(Url::from)));
|
||||
fields.add_field_method_get("is_link", |_, me| Ok(me.0.is_link()));
|
||||
fields.add_field_method_get("is_hidden", |_, me| Ok(me.0.is_hidden()));
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Manager<'a, 'b> {
|
||||
scope: &'b mlua::Scope<'a, 'a>,
|
||||
inner: &'a core::manager::Manager,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Manager<'a, 'b> {
|
||||
pub(crate) fn init() -> mlua::Result<()> {
|
||||
LUA.register_userdata_type::<core::manager::Manager>(|reg| {
|
||||
reg.add_field_function_get("mode", |_, me| me.named_user_value::<AnyUserData>("mode"));
|
||||
|
|
@ -29,6 +48,7 @@ impl Manager {
|
|||
reg.add_field_method_get("offset", |_, me| Ok(me.offset()));
|
||||
reg.add_field_method_get("cursor", |_, me| Ok(me.cursor()));
|
||||
|
||||
reg.add_field_function_get("window", |_, me| me.named_user_value::<Value>("window"));
|
||||
reg.add_field_function_get("files", |_, me| me.named_user_value::<AnyUserData>("files"));
|
||||
reg.add_field_function_get("hovered", |_, me| me.named_user_value::<Value>("hovered"));
|
||||
})?;
|
||||
|
|
@ -38,22 +58,20 @@ impl Manager {
|
|||
|
||||
reg.add_meta_function(MetaMethod::Pairs, |lua, me: AnyUserData| {
|
||||
let iter = lua.create_function(|lua, (me, i): (AnyUserData, usize)| {
|
||||
let items: Vec<AnyUserData> = me.named_user_value("items")?;
|
||||
|
||||
let files = me.borrow::<core::files::Files>()?;
|
||||
let i = i + 1;
|
||||
Ok(if i > items.len() {
|
||||
Ok(if i > files.len() {
|
||||
mlua::Variadic::new()
|
||||
} else {
|
||||
let item = items[i - 1].clone().into_lua(lua)?;
|
||||
mlua::Variadic::from_iter([i.into_lua(lua)?, item])
|
||||
mlua::Variadic::from_iter([i.into_lua(lua)?, File::from(&files[i - 1]).into_lua(lua)?])
|
||||
})
|
||||
})?;
|
||||
Ok((iter, me, 0))
|
||||
});
|
||||
|
||||
reg.add_function("slice", |_, (me, skip, take): (AnyUserData, usize, usize)| {
|
||||
let items = me.named_user_value::<Vec<AnyUserData>>("items")?;
|
||||
Ok(items.iter().skip(skip).take(take).cloned().collect::<Vec<_>>())
|
||||
let files = me.borrow::<core::files::Files>()?;
|
||||
Ok(files.iter().skip(skip).take(take).map(File::from).collect::<Vec<_>>())
|
||||
});
|
||||
})?;
|
||||
|
||||
|
|
@ -87,61 +105,56 @@ impl Manager {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn make<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
inner: &'a core::manager::Manager,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value("mode", scope.create_any_userdata_ref(inner.active().mode())?)?;
|
||||
pub(crate) fn new(scope: &'b mlua::Scope<'a, 'a>, inner: &'a core::manager::Manager) -> Self {
|
||||
Self { scope, inner }
|
||||
}
|
||||
|
||||
pub(crate) fn make(&self) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = self.scope.create_any_userdata_ref(self.inner)?;
|
||||
ud.set_named_user_value(
|
||||
"parent",
|
||||
inner.parent().and_then(|p| Self::folder(scope, inner, p).ok()),
|
||||
"mode",
|
||||
self.scope.create_any_userdata_ref(self.inner.active().mode())?,
|
||||
)?;
|
||||
ud.set_named_user_value("current", Self::folder(scope, inner, inner.current())?)?;
|
||||
ud.set_named_user_value("preview", Self::preview(scope, inner, inner.active())?)?;
|
||||
ud.set_named_user_value("parent", self.inner.parent().and_then(|p| self.folder(p, None).ok()))?;
|
||||
ud.set_named_user_value("current", self.folder(self.inner.current(), None)?)?;
|
||||
ud.set_named_user_value("preview", self.preview(self.inner.active())?)?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
|
||||
pub(crate) fn folder<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
manager: &'a core::manager::Manager,
|
||||
pub(crate) fn folder(
|
||||
&self,
|
||||
inner: &'a core::manager::Folder,
|
||||
window: Option<(usize, usize)>,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value("files", Self::files(scope, manager, &inner.files)?)?;
|
||||
let window = window.unwrap_or_else(|| (inner.offset(), MANAGER.layout.folder_height()));
|
||||
|
||||
let ud = self.scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value(
|
||||
"hovered",
|
||||
inner.hovered.as_ref().and_then(|h| Self::file(scope, manager, h).ok()),
|
||||
"window",
|
||||
inner
|
||||
.files
|
||||
.iter()
|
||||
.skip(window.0)
|
||||
.take(window.1)
|
||||
.filter_map(|f| self.file(f).ok())
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
ud.set_named_user_value("files", self.files(&inner.files)?)?;
|
||||
ud.set_named_user_value("hovered", inner.hovered.as_ref().and_then(|h| self.file(h).ok()))?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
|
||||
fn files<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
manager: &'a core::manager::Manager,
|
||||
inner: &'a core::files::Files,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value(
|
||||
"items",
|
||||
inner.iter().filter_map(|f| Self::file(scope, manager, f).ok()).collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
Ok(ud)
|
||||
fn files(&self, inner: &'a core::files::Files) -> mlua::Result<AnyUserData<'a>> {
|
||||
self.scope.create_any_userdata_ref(inner)
|
||||
}
|
||||
|
||||
fn file<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
manager: &'a core::manager::Manager,
|
||||
inner: &'a core::files::File,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = scope.create_any_userdata_ref(inner)?;
|
||||
|
||||
fn file(&self, inner: &'a core::files::File) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = self.scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value(
|
||||
"icon",
|
||||
scope.create_function(|_, ()| {
|
||||
self.scope.create_function(|_, ()| {
|
||||
Ok(
|
||||
THEME
|
||||
.icons
|
||||
|
|
@ -154,8 +167,8 @@ impl Manager {
|
|||
|
||||
ud.set_named_user_value(
|
||||
"style",
|
||||
scope.create_function(|_, ()| {
|
||||
let mime = manager.mimetype.get(inner.url());
|
||||
self.scope.create_function(|_, ()| {
|
||||
let mime = self.inner.mimetype.get(inner.url());
|
||||
Ok(
|
||||
THEME
|
||||
.filetypes
|
||||
|
|
@ -169,14 +182,10 @@ impl Manager {
|
|||
Ok(ud)
|
||||
}
|
||||
|
||||
fn preview<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
manager: &'a core::manager::Manager,
|
||||
tab: &'a core::manager::Tab,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
fn preview(&self, tab: &'a core::manager::Tab) -> mlua::Result<AnyUserData<'a>> {
|
||||
let inner = tab.preview();
|
||||
|
||||
let ud = scope.create_any_userdata_ref(inner)?;
|
||||
let ud = self.scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value(
|
||||
"folder",
|
||||
inner
|
||||
|
|
@ -184,7 +193,7 @@ impl Manager {
|
|||
.as_ref()
|
||||
.filter(|l| l.is_folder())
|
||||
.and_then(|l| tab.history(&l.url))
|
||||
.and_then(|f| Self::folder(scope, manager, f).ok()),
|
||||
.and_then(|f| self.folder(f, Some((f.offset(), MANAGER.layout.preview_height()))).ok()),
|
||||
)?;
|
||||
|
||||
Ok(ud)
|
||||
|
|
|
|||
|
|
@ -1,23 +1,14 @@
|
|||
use core::Ctx;
|
||||
|
||||
use mlua::{Result, Table, TableExt};
|
||||
use ratatui::layout;
|
||||
|
||||
use crate::{bindings, layout::{Paragraph, Rect}, GLOBALS, LUA};
|
||||
use crate::{layout::{Paragraph, Rect}, GLOBALS, LUA};
|
||||
|
||||
pub struct Status;
|
||||
|
||||
impl Status {
|
||||
pub fn render(cx: &Ctx, area: layout::Rect) -> Result<Vec<Paragraph>> {
|
||||
LUA.scope(|scope| {
|
||||
let tbl = LUA.create_table()?;
|
||||
tbl.set("manager", bindings::Manager::make(scope, &cx.manager)?)?;
|
||||
tbl.set("tasks", bindings::Tasks::make(scope, &cx.tasks)?)?;
|
||||
GLOBALS.set("cx", tbl)?;
|
||||
|
||||
pub fn render(area: layout::Rect) -> Result<Vec<Paragraph>> {
|
||||
let comp: Table = GLOBALS.get("Status")?;
|
||||
comp.call_method::<_, _>("render", Rect(area))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,14 +23,8 @@ impl Folder {
|
|||
Ok(tbl)
|
||||
}
|
||||
|
||||
pub fn render(self, cx: &Ctx, area: layout::Rect) -> Result<Vec<Paragraph>> {
|
||||
LUA.scope(|scope| {
|
||||
let tbl = LUA.create_table()?;
|
||||
tbl.set("manager", bindings::Manager::make(scope, &cx.manager)?)?;
|
||||
GLOBALS.set("cx", tbl)?;
|
||||
|
||||
pub fn render(self, area: layout::Rect) -> Result<Vec<Paragraph>> {
|
||||
let comp: Table = GLOBALS.get("Folder")?;
|
||||
comp.call_method::<_, _>("render", (Rect(area), self.args()?))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ mod components;
|
|||
mod config;
|
||||
mod layout;
|
||||
mod plugin;
|
||||
mod scope;
|
||||
|
||||
pub use components::*;
|
||||
use config::*;
|
||||
pub use plugin::*;
|
||||
pub use scope::*;
|
||||
|
|
|
|||
14
plugin/src/scope.rs
Normal file
14
plugin/src/scope.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use core::Ctx;
|
||||
|
||||
use crate::{bindings, GLOBALS, LUA};
|
||||
|
||||
pub fn scope<F: FnOnce()>(cx: &Ctx, f: F) {
|
||||
let _ = LUA.scope(|scope| {
|
||||
let tbl = LUA.create_table()?;
|
||||
tbl.set("manager", bindings::Manager::new(scope, &cx.manager).make()?)?;
|
||||
tbl.set("tasks", bindings::Tasks::make(scope, &cx.tasks)?)?;
|
||||
GLOBALS.set("cx", tbl)?;
|
||||
|
||||
Ok(f())
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue