Skip to content

Commit

Permalink
perf: cheaper sync context initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Feb 8, 2024
1 parent 0d7e977 commit e355c6d
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 210 deletions.
10 changes: 4 additions & 6 deletions yazi-fm/src/lives/active.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods, Value};
use yazi_config::LAYOUT;

use super::Folder;

pub struct Active<'a, 'b> {
pub(super) struct Active<'a, 'b> {
scope: &'b mlua::Scope<'a, 'a>,

inner: &'a yazi_core::tab::Tab,
Expand Down Expand Up @@ -50,17 +49,16 @@ impl<'a, 'b> Active<'a, 'b> {
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::new(self.scope, p).make(None).ok()),
self.inner.parent.as_ref().and_then(|p| Folder::make(self.scope, p).ok()),
)?;
ud.set_named_user_value("current", Folder::new(self.scope, &self.inner.current).make(None)?)?;
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 window = Some((inner.skip, LAYOUT.load().preview.height as usize));

let ud = self.scope.create_any_userdata_ref(inner)?;
ud.set_named_user_value(
Expand All @@ -70,7 +68,7 @@ impl<'a, 'b> Active<'a, 'b> {
.hovered()
.filter(|&f| f.is_dir())
.and_then(|f| tab.history(&f.url))
.and_then(|f| Folder::new(self.scope, f).make(window).ok()),
.and_then(|f| Folder::make(self.scope, f).ok()),
)?;

Ok(ud)
Expand Down
122 changes: 122 additions & 0 deletions yazi-fm/src/lives/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use std::ops::Deref;

use mlua::{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;

pub(super) struct File {
idx: usize,
folder: *const yazi_core::folder::Folder,
}

impl Deref for File {
type Target = yazi_shared::fs::File;

fn deref(&self) -> &Self::Target { &self.folder().files[self.idx] }
}

impl File {
#[inline]
pub(super) fn new(idx: usize, folder: &yazi_core::folder::Folder) -> Self { Self { idx, folder } }

pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
lua.register_userdata_type::<Self>(|reg| {
reg.add_field_method_get("url", |lua, me| Url::cast(lua, me.url.clone()));
reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.cha));
reg.add_field_method_get("link_to", |lua, me| {
me.link_to.as_ref().cloned().map(|u| Url::cast(lua, u)).transpose()
});

reg.add_field_method_get("name", |lua, me| {
me.url.file_name().map(|n| lua.create_string(n.as_encoded_bytes())).transpose()
});
reg.add_method("size", |_, me, ()| {
Ok(if me.is_dir() { me.folder().files.sizes.get(&me.url).copied() } else { Some(me.len) })
});
reg.add_method("mime", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
Ok(cx.manager.mimetype.get(&me.url).cloned())
});
reg.add_method("prefix", |lua, me, ()| {
if !me.folder().cwd.is_search() {
return Ok(None);
}

let mut p = me.url.strip_prefix(&me.folder().cwd).unwrap_or(&me.url).components();
p.next_back();
Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose()
});
reg.add_method("icon", |lua, me, ()| {
THEME
.icons
.iter()
.find(|&x| x.name.match_path(&me.url, me.is_dir()))
.map(|x| Icon::cast(lua, x))
.transpose()
});
reg.add_method("style", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
let mime =
if me.is_dir() { Some(MIME_DIR) } else { cx.manager.mimetype.get(&me.url).map(|x| &**x) };

Ok(THEME.filetypes.iter().find(|&x| x.matches(me, mime)).map(|x| Style::from(x.style)))
});
reg.add_method("is_hovered", |_, me, ()| {
Ok(matches!(me.folder().hovered(), Some(f) if f.url == me.url))
});
reg.add_method("is_yanked", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
Ok(if !cx.manager.yanked.1.contains(&me.url) {
0u8
} else if cx.manager.yanked.0 {
2u8
} else {
1u8
})
});
reg.add_method("is_selected", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
let selected = me.folder().files.is_selected(&me.url);

Ok(if !cx.manager.active().mode.is_visual() {
selected
} else {
cx.manager.active().mode.pending(me.idx, selected)
})
});
reg.add_method("found", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
let Some(finder) = &cx.manager.active().finder else {
return Ok(None);
};

let Some(idx) = finder.matched_idx(&me.url) else {
return Ok(None);
};

Some(lua.create_sequence_from([idx.into_lua(lua)?, finder.matched().len().into_lua(lua)?]))
.transpose()
});
reg.add_method("highlights", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?;
let Some(finder) = &cx.manager.active().finder else {
return Ok(None);
};

let Some(h) = me.name().and_then(|n| finder.filter.highlighted(n)) else {
return Ok(None);
};

Ok(Some(h.into_iter().map(Range::from).collect::<Vec<_>>()))
});
})?;

Ok(())
}

#[inline]
fn folder(&self) -> &yazi_core::folder::Folder { unsafe { &*self.folder } }
}
43 changes: 43 additions & 0 deletions yazi-fm/src/lives/files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::ops::{Deref, Range};

use mlua::{Lua, MetaMethod, UserDataMethods};

use super::File;

pub(super) struct Files {
folder: *const yazi_core::folder::Folder,
window: Range<usize>,
}

impl Deref for Files {
type Target = yazi_core::folder::Files;

fn deref(&self) -> &Self::Target { &self.folder().files }
}

impl Files {
#[inline]
pub(super) fn new(folder: &yazi_core::folder::Folder, window: Range<usize>) -> Self {
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 {
Ok(None)
} else {
Some(lua.create_any_userdata(File::new(key - 1, me.folder()))).transpose()
}
});
})?;

Ok(())
}

#[inline]
fn folder(&self) -> &yazi_core::folder::Folder { unsafe { &*self.folder } }
}
Loading

0 comments on commit e355c6d

Please sign in to comment.