mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: allows access to complete app data for all tabs (#644)
This commit is contained in:
parent
c12a735f68
commit
25c96557ed
15 changed files with 287 additions and 219 deletions
|
|
@ -1,3 +1,5 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use yazi_config::BOOT;
|
||||
use yazi_shared::fs::Url;
|
||||
|
||||
|
|
@ -46,18 +48,19 @@ impl Tabs {
|
|||
}
|
||||
|
||||
impl Tabs {
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize { self.items.len() }
|
||||
|
||||
#[inline]
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Tab> { self.items.iter() }
|
||||
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Tab> { self.items.iter_mut() }
|
||||
|
||||
#[inline]
|
||||
pub fn active(&self) -> &Tab { &self.items[self.idx] }
|
||||
|
||||
#[inline]
|
||||
pub(super) fn active_mut(&mut self) -> &mut Tab { &mut self.items[self.idx] }
|
||||
}
|
||||
|
||||
impl Deref for Tabs {
|
||||
type Target = Vec<Tab>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.items }
|
||||
}
|
||||
|
||||
impl DerefMut for Tabs {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,15 +43,16 @@ impl App {
|
|||
return;
|
||||
};
|
||||
|
||||
Lives::partial_scope(&self.cx, |_| {
|
||||
_ = Lives::scope(&self.cx, |_| {
|
||||
for patch in Progress::partial_render(term.current_buffer_mut()) {
|
||||
term.backend_mut().draw(patch.iter().map(|(x, y, cell)| (*x, *y, cell))).ok();
|
||||
term.backend_mut().draw(patch.iter().map(|(x, y, cell)| (*x, *y, cell)))?;
|
||||
if let Some((x, y)) = self.cx.cursor() {
|
||||
term.show_cursor().ok();
|
||||
term.set_cursor(x, y).ok();
|
||||
term.show_cursor()?;
|
||||
term.set_cursor(x, y)?;
|
||||
}
|
||||
term.backend_mut().flush().ok();
|
||||
term.backend_mut().flush()?;
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods, Value};
|
||||
|
||||
use super::Folder;
|
||||
|
||||
pub(super) struct Active<'a, 'b> {
|
||||
scope: &'b mlua::Scope<'a, 'a>,
|
||||
|
||||
inner: &'a yazi_core::tab::Tab,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Active<'a, 'b> {
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_core::tab::Mode>(|reg| {
|
||||
reg.add_field_method_get("is_select", |_, me| Ok(me.is_select()));
|
||||
reg.add_field_method_get("is_unset", |_, me| Ok(me.is_unset()));
|
||||
reg.add_field_method_get("is_visual", |_, me| Ok(me.is_visual()));
|
||||
reg.add_method("pending", |_, me, (idx, state): (usize, bool)| Ok(me.pending(idx, state)));
|
||||
|
||||
reg.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string()));
|
||||
})?;
|
||||
|
||||
lua.register_userdata_type::<yazi_core::tab::Config>(|reg| {
|
||||
reg.add_field_method_get("sort_by", |_, me| Ok(me.sort_by.to_string()));
|
||||
reg.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive));
|
||||
reg.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse));
|
||||
reg.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first));
|
||||
|
||||
reg.add_field_method_get("linemode", |_, me| Ok(me.linemode.to_owned()));
|
||||
reg.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden));
|
||||
})?;
|
||||
|
||||
lua.register_userdata_type::<yazi_core::tab::Preview>(|reg| {
|
||||
reg.add_field_method_get("skip", |_, me| Ok(me.skip));
|
||||
reg.add_field_function_get("folder", |_, me| me.named_user_value::<Value>("folder"));
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Active<'a, 'b> {
|
||||
pub(crate) fn new(scope: &'b mlua::Scope<'a, 'a>, inner: &'a yazi_core::tab::Tab) -> 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("mode", self.scope.create_any_userdata_ref(&self.inner.mode)?)?;
|
||||
ud.set_named_user_value("conf", self.scope.create_any_userdata_ref(&self.inner.conf)?)?;
|
||||
ud.set_named_user_value(
|
||||
"parent",
|
||||
self.inner.parent.as_ref().and_then(|p| Folder::make(self.scope, p).ok()),
|
||||
)?;
|
||||
ud.set_named_user_value("current", Folder::make(self.scope, &self.inner.current)?)?;
|
||||
ud.set_named_user_value("preview", self.preview(self.inner)?)?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
|
||||
fn preview(&self, tab: &'a yazi_core::tab::Tab) -> mlua::Result<AnyUserData<'a>> {
|
||||
let inner = &tab.preview;
|
||||
|
||||
let ud = self.scope.create_any_userdata_ref(inner)?;
|
||||
ud.set_named_user_value(
|
||||
"folder",
|
||||
tab
|
||||
.current
|
||||
.hovered()
|
||||
.filter(|&f| f.is_dir())
|
||||
.and_then(|f| tab.history(&f.url))
|
||||
.and_then(|f| Folder::make(self.scope, f).ok()),
|
||||
)?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
}
|
||||
34
yazi-fm/src/lives/config.rs
Normal file
34
yazi-fm/src/lives/config.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserDataFields};
|
||||
|
||||
use super::SCOPE;
|
||||
|
||||
pub(super) struct Config {
|
||||
inner: *const yazi_core::tab::Config,
|
||||
}
|
||||
|
||||
impl Deref for Config {
|
||||
type Target = yazi_core::tab::Config;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Config {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Config) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("sort_by", |_, me| Ok(me.sort_by.to_string()));
|
||||
reg.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive));
|
||||
reg.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse));
|
||||
reg.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first));
|
||||
|
||||
reg.add_field_method_get("linemode", |_, me| Ok(me.linemode.to_owned()));
|
||||
reg.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{IntoLua, Lua, UserDataFields, UserDataMethods};
|
||||
use mlua::{AnyUserData, IntoLua, Lua, UserDataFields, UserDataMethods};
|
||||
use yazi_config::THEME;
|
||||
use yazi_plugin::{bindings::{Cast, Cha, Icon, Range}, elements::Style, url::Url};
|
||||
use yazi_shared::MIME_DIR;
|
||||
|
||||
use super::CtxRef;
|
||||
use super::{CtxRef, SCOPE};
|
||||
|
||||
pub(super) struct File {
|
||||
idx: usize,
|
||||
|
|
@ -20,7 +20,12 @@ impl Deref for File {
|
|||
|
||||
impl File {
|
||||
#[inline]
|
||||
pub(super) fn new(idx: usize, folder: &yazi_core::folder::Folder) -> Self { Self { idx, folder } }
|
||||
pub(super) fn make(
|
||||
idx: usize,
|
||||
folder: &yazi_core::folder::Folder,
|
||||
) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { idx, folder })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::ops::{Deref, Range};
|
||||
|
||||
use mlua::{Lua, MetaMethod, UserDataMethods};
|
||||
use mlua::{AnyUserData, Lua, MetaMethod, UserDataMethods};
|
||||
|
||||
use super::File;
|
||||
use super::{File, SCOPE};
|
||||
|
||||
pub(super) struct Files {
|
||||
folder: *const yazi_core::folder::Folder,
|
||||
|
|
@ -17,20 +17,23 @@ impl Deref for Files {
|
|||
|
||||
impl Files {
|
||||
#[inline]
|
||||
pub(super) fn new(folder: &yazi_core::folder::Folder, window: Range<usize>) -> Self {
|
||||
Self { folder, window }
|
||||
pub(super) fn make(
|
||||
folder: &yazi_core::folder::Folder,
|
||||
window: Range<usize>,
|
||||
) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { folder, window })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.window.end - me.window.start));
|
||||
|
||||
reg.add_meta_method(MetaMethod::Index, |lua, me, mut key: usize| {
|
||||
key += me.window.start;
|
||||
if key > me.window.end || key == 0 {
|
||||
reg.add_meta_method(MetaMethod::Index, |_, me, mut idx: usize| {
|
||||
idx += me.window.start;
|
||||
if idx > me.window.end || idx == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Some(lua.create_any_userdata(File::new(key - 1, me.folder()))).transpose()
|
||||
Some(File::make(idx - 1, me.folder())).transpose()
|
||||
}
|
||||
});
|
||||
})?;
|
||||
|
|
|
|||
|
|
@ -1,42 +1,45 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserDataFields};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_plugin::{bindings::Cast, url::Url};
|
||||
|
||||
use super::{File, Files};
|
||||
use super::{File, Files, SCOPE};
|
||||
|
||||
pub(super) struct Folder;
|
||||
pub(super) struct Folder {
|
||||
inner: *const yazi_core::folder::Folder,
|
||||
}
|
||||
|
||||
impl Deref for Folder {
|
||||
type Target = yazi_core::folder::Folder;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Folder {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::folder::Folder) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_core::folder::Folder>(|reg| {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.cwd.clone()));
|
||||
reg.add_field_method_get("files", |lua, me| {
|
||||
lua.create_any_userdata(Files::new(me, 0..me.files.len()))
|
||||
});
|
||||
reg.add_field_method_get("window", |lua, me| {
|
||||
lua.create_any_userdata(Files::new(
|
||||
reg.add_field_method_get("files", |_, me| Files::make(me, 0..me.files.len()));
|
||||
reg.add_field_method_get("window", |_, me| {
|
||||
Files::make(
|
||||
me,
|
||||
me.offset..me.files.len().min(me.offset + LAYOUT.load().preview.height as usize),
|
||||
))
|
||||
)
|
||||
});
|
||||
|
||||
reg.add_field_method_get("offset", |_, me| Ok(me.offset));
|
||||
reg.add_field_method_get("cursor", |_, me| Ok(me.cursor));
|
||||
reg.add_field_method_get("hovered", |lua, me| {
|
||||
me.hovered().map(|_| lua.create_any_userdata(File::new(me.cursor, me))).transpose()
|
||||
reg.add_field_method_get("hovered", |_, me| {
|
||||
me.hovered().map(|_| File::make(me.cursor, me)).transpose()
|
||||
});
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Folder {
|
||||
#[inline]
|
||||
pub(crate) fn make<'a>(
|
||||
scope: &mlua::Scope<'a, 'a>,
|
||||
inner: &'a yazi_core::folder::Folder,
|
||||
) -> mlua::Result<AnyUserData<'a>> {
|
||||
scope.create_any_userdata_ref(inner)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,26 @@
|
|||
use std::sync::Arc;
|
||||
use std::{mem, sync::Arc};
|
||||
|
||||
use mlua::{Scope, Table};
|
||||
use tracing::error;
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_plugin::{elements::RectRef, LUA};
|
||||
use yazi_shared::RoCell;
|
||||
|
||||
use crate::Ctx;
|
||||
|
||||
pub(super) static SCOPE: RoCell<&mlua::Scope> = RoCell::new();
|
||||
|
||||
pub(crate) struct Lives;
|
||||
|
||||
impl Lives {
|
||||
pub(crate) fn register() -> mlua::Result<()> {
|
||||
super::Active::register(&LUA)?;
|
||||
super::Config::register(&LUA)?;
|
||||
super::File::register(&LUA)?;
|
||||
super::Files::register(&LUA)?;
|
||||
super::Folder::register(&LUA)?;
|
||||
super::Mode::register(&LUA)?;
|
||||
super::Preview::register(&LUA)?;
|
||||
super::Tab::register(&LUA)?;
|
||||
super::Tabs::register(&LUA)?;
|
||||
super::Tasks::register(&LUA)?;
|
||||
|
||||
|
|
@ -26,15 +32,16 @@ impl Lives {
|
|||
f: impl FnOnce(&Scope<'a, 'a>) -> mlua::Result<T>,
|
||||
) -> mlua::Result<T> {
|
||||
let result = LUA.scope(|scope| {
|
||||
SCOPE.init(unsafe { mem::transmute(scope) });
|
||||
LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?;
|
||||
|
||||
let global = LUA.globals();
|
||||
global.set(
|
||||
"cx",
|
||||
LUA.create_table_from([
|
||||
("active", super::Active::new(scope, cx.manager.active()).make()?),
|
||||
("tabs", super::Tabs::new(scope, &cx.manager.tabs).make()?),
|
||||
("tasks", super::Tasks::new(scope, &cx.tasks).make()?),
|
||||
("active", super::Tab::make(cx.manager.active())?),
|
||||
("tabs", super::Tabs::make(&cx.manager.tabs)?),
|
||||
("tasks", super::Tasks::make(&cx.tasks)?),
|
||||
])?,
|
||||
)?;
|
||||
|
||||
|
|
@ -48,6 +55,7 @@ impl Lives {
|
|||
status: *global.get::<_, Table>("Status")?.get::<_, RectRef>("area")?,
|
||||
}));
|
||||
|
||||
SCOPE.drop();
|
||||
Ok(ret)
|
||||
});
|
||||
|
||||
|
|
@ -56,20 +64,4 @@ impl Lives {
|
|||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn partial_scope<'a>(cx: &'a Ctx, f: impl FnOnce(&Scope<'a, 'a>)) {
|
||||
let result = LUA.scope(|scope| {
|
||||
LUA.globals().set(
|
||||
"cx",
|
||||
LUA.create_table_from([("tasks", super::Tasks::new(scope, &cx.tasks).make()?)])?,
|
||||
)?;
|
||||
|
||||
f(scope);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
if let Err(e) = result {
|
||||
error!("{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
mod active;
|
||||
mod config;
|
||||
mod file;
|
||||
mod files;
|
||||
mod folder;
|
||||
mod lives;
|
||||
mod mode;
|
||||
mod preview;
|
||||
mod tab;
|
||||
mod tabs;
|
||||
mod tasks;
|
||||
|
||||
use active::*;
|
||||
use config::*;
|
||||
use file::*;
|
||||
use files::*;
|
||||
use folder::*;
|
||||
pub(super) use lives::*;
|
||||
use mode::*;
|
||||
use preview::*;
|
||||
use tab::*;
|
||||
use tabs::*;
|
||||
use tasks::*;
|
||||
|
||||
|
|
|
|||
33
yazi-fm/src/lives/mode.rs
Normal file
33
yazi-fm/src/lives/mode.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::SCOPE;
|
||||
|
||||
pub(super) struct Mode {
|
||||
inner: *const yazi_core::tab::Mode,
|
||||
}
|
||||
|
||||
impl Deref for Mode {
|
||||
type Target = yazi_core::tab::Mode;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("is_select", |_, me| Ok(me.is_select()));
|
||||
reg.add_field_method_get("is_unset", |_, me| Ok(me.is_unset()));
|
||||
reg.add_field_method_get("is_visual", |_, me| Ok(me.is_visual()));
|
||||
reg.add_method("pending", |_, me, (idx, state): (usize, bool)| Ok(me.pending(idx, state)));
|
||||
|
||||
reg.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string()));
|
||||
})
|
||||
}
|
||||
}
|
||||
40
yazi-fm/src/lives/preview.rs
Normal file
40
yazi-fm/src/lives/preview.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserDataFields};
|
||||
|
||||
use super::{Folder, SCOPE};
|
||||
|
||||
pub(super) struct Preview {
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
}
|
||||
|
||||
impl Deref for Preview {
|
||||
type Target = yazi_core::tab::Preview;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.tab().preview }
|
||||
}
|
||||
|
||||
impl Preview {
|
||||
#[inline]
|
||||
pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { tab })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("skip", |_, me| Ok(me.skip));
|
||||
reg.add_field_method_get("folder", |_, me| {
|
||||
me.tab()
|
||||
.current
|
||||
.hovered()
|
||||
.filter(|&f| f.is_dir())
|
||||
.and_then(|f| me.tab().history(&f.url))
|
||||
.map(Folder::make)
|
||||
.transpose()
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } }
|
||||
}
|
||||
46
yazi-fm/src/lives/tab.rs
Normal file
46
yazi-fm/src/lives/tab.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::{Config, Folder, Mode, Preview, SCOPE};
|
||||
|
||||
pub(super) struct Tab {
|
||||
inner: *const yazi_core::tab::Tab,
|
||||
}
|
||||
|
||||
impl Deref for Tab {
|
||||
type Target = yazi_core::tab::Tab;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_method("name", |lua, me, ()| {
|
||||
Some(
|
||||
lua.create_string(
|
||||
me.current
|
||||
.cwd
|
||||
.file_name()
|
||||
.map_or(me.current.cwd.as_os_str().as_encoded_bytes(), |n| n.as_encoded_bytes()),
|
||||
),
|
||||
)
|
||||
.transpose()
|
||||
});
|
||||
|
||||
reg.add_field_method_get("mode", |_, me| Mode::make(&me.mode));
|
||||
reg.add_field_method_get("conf", |_, me| Config::make(&me.conf));
|
||||
reg.add_field_method_get("parent", |_, me| me.parent.as_ref().map(Folder::make).transpose());
|
||||
reg.add_field_method_get("current", |_, me| Folder::make(&me.current));
|
||||
reg.add_field_method_get("preview", |_, me| Preview::make(me));
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +1,42 @@
|
|||
// TODO: unsafe
|
||||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods, Value};
|
||||
use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::Folder;
|
||||
use super::{Tab, SCOPE};
|
||||
|
||||
pub(super) struct Tabs<'a, 'b> {
|
||||
scope: &'b mlua::Scope<'a, 'a>,
|
||||
|
||||
inner: &'a yazi_core::manager::Tabs,
|
||||
pub(super) struct Tabs {
|
||||
inner: *const yazi_core::manager::Tabs,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Tabs<'a, 'b> {
|
||||
impl Deref for Tabs {
|
||||
type Target = yazi_core::manager::Tabs;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Tabs {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::manager::Tabs) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_core::manager::Tabs>(|reg| {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("idx", |_, me| Ok(me.idx));
|
||||
|
||||
reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len()));
|
||||
reg.add_meta_function(MetaMethod::Index, |_, (me, index): (AnyUserData, usize)| {
|
||||
let items = me.named_user_value::<Vec<AnyUserData>>("items")?;
|
||||
Ok(items.get(index - 1).cloned())
|
||||
});
|
||||
})?;
|
||||
|
||||
lua.register_userdata_type::<yazi_core::tab::Tab>(|reg| {
|
||||
reg.add_method("name", |lua, me, ()| {
|
||||
Some(
|
||||
lua.create_string(
|
||||
me.current
|
||||
.cwd
|
||||
.file_name()
|
||||
.map_or(me.current.cwd.as_os_str().as_encoded_bytes(), |n| n.as_encoded_bytes()),
|
||||
),
|
||||
)
|
||||
.transpose()
|
||||
reg.add_meta_method(MetaMethod::Index, |_, me, idx: usize| {
|
||||
if idx > me.len() || idx == 0 {
|
||||
Ok(None)
|
||||
} else if idx - 1 == me.idx {
|
||||
Err("Use `active` instead of `tabs` to access the current tab".into_lua_err())
|
||||
} else {
|
||||
Some(Tab::make(&me[idx - 1])).transpose()
|
||||
}
|
||||
});
|
||||
|
||||
reg.add_field_function_get("mode", |_, me| me.named_user_value::<AnyUserData>("mode"));
|
||||
reg.add_field_function_get("conf", |_, me| me.named_user_value::<AnyUserData>("conf"));
|
||||
reg.add_field_function_get("parent", |_, me| me.named_user_value::<Value>("parent"));
|
||||
reg.add_field_function_get("current", |_, me| me.named_user_value::<AnyUserData>("current"));
|
||||
reg.add_field_function_get("preview", |_, me| me.named_user_value::<AnyUserData>("preview"));
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Tabs<'a, 'b> {
|
||||
pub(crate) fn new(scope: &'b mlua::Scope<'a, 'a>, inner: &'a yazi_core::manager::Tabs) -> 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(
|
||||
"items",
|
||||
self.inner.iter().filter_map(|t| self.tab(t).ok()).collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
|
||||
fn tab(&self, inner: &'a yazi_core::tab::Tab) -> mlua::Result<AnyUserData<'a>> {
|
||||
let ud = self.scope.create_any_userdata_ref(inner)?;
|
||||
|
||||
ud.set_named_user_value(
|
||||
"parent",
|
||||
inner.parent.as_ref().and_then(|p| Folder::make(self.scope, p).ok()),
|
||||
)?;
|
||||
|
||||
ud.set_named_user_value("current", Folder::make(self.scope, &inner.current)?)?;
|
||||
|
||||
Ok(ud)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,30 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, LuaSerdeExt, UserDataFields};
|
||||
|
||||
pub(super) struct Tasks<'a, 'b> {
|
||||
scope: &'b mlua::Scope<'a, 'a>,
|
||||
use super::SCOPE;
|
||||
|
||||
inner: &'a yazi_core::tasks::Tasks,
|
||||
pub(super) struct Tasks {
|
||||
inner: *const yazi_core::tasks::Tasks,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Tasks<'a, 'b> {
|
||||
impl Deref for Tasks {
|
||||
type Target = yazi_core::tasks::Tasks;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl Tasks {
|
||||
#[inline]
|
||||
pub(crate) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result<AnyUserData<'static>> {
|
||||
SCOPE.create_any_userdata(Self { inner })
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_core::tasks::Tasks>(|reg| {
|
||||
lua.register_userdata_type::<Self>(|reg| {
|
||||
reg.add_field_method_get("progress", |lua, me| lua.to_value(&me.progress))
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn new(scope: &'b mlua::Scope<'a, 'a>, inner: &'a yazi_core::tasks::Tasks) -> Self {
|
||||
Self { scope, inner }
|
||||
}
|
||||
|
||||
pub(crate) fn make(&self) -> mlua::Result<AnyUserData<'a>> {
|
||||
self.scope.create_any_userdata_ref(self.inner)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ impl<T> RoCell<T> {
|
|||
{
|
||||
self.init(f());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn drop(&self) {
|
||||
unsafe {
|
||||
*self.0.get() = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for RoCell<T> {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue