mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: copy-on-write support for field caching (#2629)
This commit is contained in:
parent
56d6e4a71e
commit
510cb14ab6
12 changed files with 53 additions and 57 deletions
|
|
@ -2,16 +2,16 @@
|
|||
macro_rules! cached_field {
|
||||
($fields:ident, $key:ident, $value:expr) => {
|
||||
$fields.add_field_function_get(stringify!($key), |lua, ud| {
|
||||
use mlua::IntoLua;
|
||||
ud.borrow_mut_scoped::<Self, mlua::Result<mlua::Value>>(|me| {
|
||||
match paste::paste! { &me.[<v_ $key>] } {
|
||||
Some(v) => Ok(v.clone()),
|
||||
None => {
|
||||
let v: mlua::Result<_> = $value(lua, me);
|
||||
let v = v?.into_lua(lua)?;
|
||||
paste::paste! { me.[<v_ $key>] = Some(v.clone()) };
|
||||
Ok(v)
|
||||
}
|
||||
use mlua::{Error::UserDataDestructed, IntoLua, Lua, Result, Value, Value::UserData};
|
||||
ud.borrow_mut_scoped::<Self, Result<Value>>(|me| match paste::paste! { &me.[<v_ $key>] } {
|
||||
Some(v) if !v.is_userdata() => Ok(v.clone()),
|
||||
Some(v @ UserData(ud)) if !matches!(ud.borrow::<()>(), Err(UserDataDestructed)) => {
|
||||
Ok(v.clone())
|
||||
}
|
||||
_ => {
|
||||
let v = ($value as fn(&Lua, &Self) -> Result<_>)(lua, me)?.into_lua(lua)?;
|
||||
paste::paste! { me.[<v_ $key>] = Some(v.clone()) };
|
||||
Ok(v)
|
||||
}
|
||||
})?
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ impl Url {
|
|||
impl FromLua for Url {
|
||||
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||
Ok(match value {
|
||||
Value::UserData(ud) => Self::new(ud.take::<Self>()?.inner),
|
||||
Value::UserData(ud) => ud.take()?,
|
||||
_ => Err("Expected a Url".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
|
|
@ -70,23 +70,23 @@ impl FromLua for Url {
|
|||
|
||||
impl UserData for Url {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, name, |lua: &Lua, me: &Self| {
|
||||
cached_field!(fields, name, |lua, me| {
|
||||
Some(me.name())
|
||||
.filter(|&s| !s.is_empty())
|
||||
.map(|s| lua.create_string(s.as_encoded_bytes()))
|
||||
.transpose()
|
||||
});
|
||||
cached_field!(fields, stem, |lua: &Lua, me: &Self| {
|
||||
cached_field!(fields, stem, |lua, me| {
|
||||
me.file_stem().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
cached_field!(fields, ext, |lua: &Lua, me: &Self| {
|
||||
cached_field!(fields, ext, |lua, me| {
|
||||
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
cached_field!(fields, parent, |_, me: &Self| Ok(me.parent_url().map(Self::new)));
|
||||
cached_field!(fields, base, |_, me: &Self| {
|
||||
cached_field!(fields, parent, |_, me| Ok(me.parent_url().map(Self::new)));
|
||||
cached_field!(fields, base, |_, me| {
|
||||
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::new(me.base())) })
|
||||
});
|
||||
cached_field!(fields, frag, |lua: &Lua, me: &Self| lua.create_string(me.frag()));
|
||||
cached_field!(fields, frag, |lua, me| lua.create_string(me.frag()));
|
||||
|
||||
fields.add_field_method_get("is_regular", |_, me| Ok(me.is_regular()));
|
||||
fields.add_field_method_get("is_search", |_, me| Ok(me.is_search()));
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ impl Files {
|
|||
|
||||
impl UserData for Files {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, filter, |_, me: &Self| me.filter().map(Filter::make).transpose());
|
||||
cached_field!(fields, filter, |_, me| me.filter().map(Filter::make).transpose());
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::{Deref, Range};
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserData, UserDataFields, Value};
|
||||
use mlua::{AnyUserData, UserData, UserDataFields, Value};
|
||||
use yazi_binding::{FolderStage, Url, cached_field};
|
||||
use yazi_config::LAYOUT;
|
||||
|
||||
|
|
@ -55,14 +55,14 @@ impl Folder {
|
|||
|
||||
impl UserData for Folder {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, cwd, |_, me: &Self| Ok(Url::new(me.url.to_owned())));
|
||||
cached_field!(fields, files, |_, me: &Self| Files::make(0..me.files.len(), me, &me.tab));
|
||||
cached_field!(fields, stage, |_: &Lua, me: &Self| Ok(FolderStage::new(me.stage)));
|
||||
cached_field!(fields, window, |_, me: &Self| Files::make(me.window.clone(), me, &me.tab));
|
||||
cached_field!(fields, cwd, |_, me| Ok(Url::new(me.url.to_owned())));
|
||||
cached_field!(fields, files, |_, me| Files::make(0..me.files.len(), me, &me.tab));
|
||||
cached_field!(fields, stage, |_, me| Ok(FolderStage::new(me.stage)));
|
||||
cached_field!(fields, window, |_, me| Files::make(me.window.clone(), me, &me.tab));
|
||||
|
||||
fields.add_field_method_get("offset", |_, me| Ok(me.offset));
|
||||
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
|
||||
cached_field!(fields, hovered, |_, me: &Self| {
|
||||
cached_field!(fields, hovered, |_, me| {
|
||||
me.hovered().map(|_| File::make(me.cursor, me, &me.tab)).transpose()
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ impl Preference {
|
|||
|
||||
impl UserData for Preference {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, sort_by, |_, me: &Self| Ok(me.sort_by.to_string()));
|
||||
cached_field!(fields, sort_by, |_, me| Ok(me.sort_by.to_string()));
|
||||
fields.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive));
|
||||
fields.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse));
|
||||
fields.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first));
|
||||
fields.add_field_method_get("sort_translit", |_, me| Ok(me.sort_translit));
|
||||
|
||||
cached_field!(fields, linemode, |_, me: &Self| Ok(me.linemode.to_string()));
|
||||
cached_field!(fields, linemode, |_, me| Ok(me.linemode.to_string()));
|
||||
fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ impl Preview {
|
|||
impl UserData for Preview {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("skip", |_, me| Ok(me.skip));
|
||||
cached_field!(fields, folder, |_, me: &Self| {
|
||||
cached_field!(fields, folder, |_, me| {
|
||||
me.tab
|
||||
.hovered_folder()
|
||||
.map(|f| {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use yazi_binding::{UrlRef, cached_field};
|
||||
use yazi_plugin::Id;
|
||||
|
||||
|
|
@ -46,21 +46,21 @@ impl Tab {
|
|||
impl UserData for Tab {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
|
||||
cached_field!(fields, name, |lua: &Lua, me: &Self| {
|
||||
cached_field!(fields, name, |lua, me| {
|
||||
lua.create_string(me.current.url.name().as_encoded_bytes())
|
||||
});
|
||||
|
||||
cached_field!(fields, mode, |_, me: &Self| Mode::make(&me.mode));
|
||||
cached_field!(fields, pref, |_, me: &Self| Preference::make(&me.pref));
|
||||
cached_field!(fields, current, |_, me: &Self| Folder::make(None, &me.current, me));
|
||||
cached_field!(fields, parent, |_, me: &Self| {
|
||||
cached_field!(fields, mode, |_, me| Mode::make(&me.mode));
|
||||
cached_field!(fields, pref, |_, me| Preference::make(&me.pref));
|
||||
cached_field!(fields, current, |_, me| Folder::make(None, &me.current, me));
|
||||
cached_field!(fields, parent, |_, me| {
|
||||
me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose()
|
||||
});
|
||||
|
||||
cached_field!(fields, selected, |_, me: &Self| Selected::make(&me.selected));
|
||||
cached_field!(fields, selected, |_, me| Selected::make(&me.selected));
|
||||
|
||||
cached_field!(fields, preview, |_, me: &Self| Preview::make(me));
|
||||
cached_field!(fields, finder, |_, me: &Self| me.finder.as_ref().map(Finder::make).transpose());
|
||||
cached_field!(fields, preview, |_, me| Preview::make(me));
|
||||
cached_field!(fields, finder, |_, me| me.finder.as_ref().map(Finder::make).transpose());
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, Lua, LuaSerdeExt, UserData, UserDataFields, Value};
|
||||
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::{Lives, PtrCell};
|
||||
|
|
@ -26,6 +26,6 @@ impl Tasks {
|
|||
|
||||
impl UserData for Tasks {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, progress, |lua: &Lua, me: &Self| lua.to_value(&me.progress));
|
||||
cached_field!(fields, progress, |lua, me| lua.to_value(&me.progress));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{Lua, UserData, UserDataFields, Value};
|
||||
use mlua::{UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use crate::elements::Style;
|
||||
|
|
@ -26,7 +26,7 @@ impl From<&'static yazi_shared::theme::Icon> for Icon {
|
|||
|
||||
impl UserData for Icon {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, text, |lua: &Lua, me: &Self| lua.create_string(&me.text));
|
||||
cached_field!(fields, style, |_, me: &Self| Ok(Style::from(me.style)));
|
||||
cached_field!(fields, text, |lua, me| lua.create_string(&me.text));
|
||||
cached_field!(fields, style, |_, me| Ok(Style::from(me.style)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl Fetcher {
|
|||
|
||||
impl UserData for Fetcher {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ impl Spotter {
|
|||
|
||||
impl UserData for Spotter {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ impl Preloader {
|
|||
|
||||
impl UserData for Preloader {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +109,6 @@ impl Previewer {
|
|||
|
||||
impl UserData for Previewer {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,17 +81,13 @@ macro_rules! impl_style_shorthands {
|
|||
#[macro_export]
|
||||
macro_rules! impl_file_fields {
|
||||
($fields:ident) => {
|
||||
yazi_binding::cached_field!($fields, cha, |_, me: &Self| Ok($crate::bindings::Cha::from(
|
||||
me.cha
|
||||
)));
|
||||
yazi_binding::cached_field!($fields, url, |_, me: &Self| Ok(yazi_binding::Url::new(
|
||||
me.url_owned()
|
||||
)));
|
||||
yazi_binding::cached_field!($fields, link_to, |_, me: &Self| Ok(
|
||||
yazi_binding::cached_field!($fields, cha, |_, me| Ok($crate::bindings::Cha::from(me.cha)));
|
||||
yazi_binding::cached_field!($fields, url, |_, me| Ok(yazi_binding::Url::new(me.url_owned())));
|
||||
yazi_binding::cached_field!($fields, link_to, |_, me| Ok(
|
||||
me.link_to.clone().map(yazi_binding::Url::new)
|
||||
));
|
||||
|
||||
yazi_binding::cached_field!($fields, name, |lua: &mlua::Lua, me: &Self| {
|
||||
yazi_binding::cached_field!($fields, name, |lua, me| {
|
||||
Some(me.name())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| lua.create_string(s.as_encoded_bytes()))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::{Lua, UserData, Value};
|
||||
use mlua::{UserData, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::Status;
|
||||
|
|
@ -19,8 +19,8 @@ impl Output {
|
|||
|
||||
impl UserData for Output {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, status, |_, me: &Self| Ok(Status::new(me.inner.status)));
|
||||
cached_field!(fields, stdout, |lua: &Lua, me: &Self| lua.create_string(&me.inner.stdout));
|
||||
cached_field!(fields, stderr, |lua: &Lua, me: &Self| lua.create_string(&me.inner.stderr));
|
||||
cached_field!(fields, status, |_, me| Ok(Status::new(me.inner.status)));
|
||||
cached_field!(fields, stdout, |lua, me| lua.create_string(&me.inner.stdout));
|
||||
cached_field!(fields, stderr, |lua, me| lua.create_string(&me.inner.stderr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue