From 4e2a06f2219c777154b482d22457028636578db9 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Fri, 20 Oct 2023 14:12:04 +0800 Subject: [PATCH] .. --- core/src/files/file.rs | 4 +-- core/src/files/sorter.rs | 3 +- plugin/preset/components/folder.lua | 4 +-- plugin/preset/components/status.lua | 11 +++++-- plugin/src/bindings/files.rs | 49 +++++++++++++++++++---------- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/core/src/files/file.rs b/core/src/files/file.rs index d2b8a405..1c7cad5e 100644 --- a/core/src/files/file.rs +++ b/core/src/files/file.rs @@ -8,7 +8,6 @@ use tokio::fs; pub struct File { pub url: Url, pub meta: Metadata, - pub length: u64, pub(super) link_to: Option, pub is_link: bool, pub is_hidden: bool, @@ -30,9 +29,8 @@ impl File { link_to = fs::read_link(&url).await.map(Url::from).ok(); } - let length = meta.len(); let is_hidden = url.file_name().map(|s| s.to_string_lossy().starts_with('.')).unwrap_or(false); - Self { url, meta, length, link_to, is_link, is_hidden } + Self { url, meta, link_to, is_link, is_hidden } } #[inline] diff --git a/core/src/files/sorter.rs b/core/src/files/sorter.rs index c336a3bf..21c1dea6 100644 --- a/core/src/files/sorter.rs +++ b/core/src/files/sorter.rs @@ -48,7 +48,7 @@ impl FilesSorter { SortBy::Size => items.sort_unstable_by(|a, b| { let aa = if a.is_dir() { sizes.get(&a.url).copied() } else { None }; let bb = if b.is_dir() { sizes.get(&b.url).copied() } else { None }; - self.cmp(aa.unwrap_or(a.length), bb.unwrap_or(b.length), self.promote(a, b)) + self.cmp(aa.unwrap_or(a.meta.len()), bb.unwrap_or(b.meta.len()), self.promote(a, b)) }), } true @@ -75,7 +75,6 @@ impl FilesSorter { let dummy = File { url: Default::default(), meta: items[0].meta.clone(), - length: 0, link_to: None, is_link: false, is_hidden: false, diff --git a/plugin/preset/components/folder.lua b/plugin/preset/components/folder.lua index 31da1cbe..189807ba 100644 --- a/plugin/preset/components/folder.lua +++ b/plugin/preset/components/folder.lua @@ -53,9 +53,9 @@ function Folder:labels(area) if linemode == "size" then lines[#lines + 1] = ui.Line { ui.Span(utils.readable_size(f:size())) } elseif linemode == "mtime" then - lines[#lines + 1] = ui.Line { ui.Span("mtime") } + lines[#lines + 1] = ui.Line { ui.Span(os.date("%y-%m-%d %H:%M", f.modified)) } elseif linemode == "permissions" then - lines[#lines + 1] = ui.Line { ui.Span("permissions") } + lines[#lines + 1] = ui.Line { ui.Span(f:permissions() or "") } end end return ui.Paragraph(area, lines):align(ui.Alignment.RIGHT) diff --git a/plugin/preset/components/status.lua b/plugin/preset/components/status.lua index 5db823b4..4f45937a 100644 --- a/plugin/preset/components/status.lua +++ b/plugin/preset/components/status.lua @@ -47,13 +47,18 @@ end function Status:permissions() local h = cx.active.current.hovered - if h == nil or h.permissions == nil then + if h == nil then + return ui.Span("") + end + + local perm = h:permissions() + if perm == nil then return ui.Span("") end local spans = {} - for i = 1, #h.permissions do - local c = h.permissions:sub(i, i) + for i = 1, #perm do + local c = perm:sub(i, i) local style = THEME.status.permissions_t if c == "-" then style = THEME.status.permissions_s diff --git a/plugin/src/bindings/files.rs b/plugin/src/bindings/files.rs index de78b562..b0ee0304 100644 --- a/plugin/src/bindings/files.rs +++ b/plugin/src/bindings/files.rs @@ -1,3 +1,5 @@ +use std::time::UNIX_EPOCH; + use config::THEME; use mlua::{AnyUserData, IntoLua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef}; @@ -13,7 +15,6 @@ impl From<&core::files::File> for File { 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)); @@ -48,34 +49,55 @@ impl Files { LUA.register_userdata_type::(|reg| { reg.add_field_method_get("url", |_, me| Ok(Url::from(&me.url))); - reg.add_field_method_get("length", |_, me| Ok(me.length)); reg.add_field_method_get("link_to", |_, me| Ok(me.link_to().map(Url::from))); reg.add_field_method_get("is_link", |_, me| Ok(me.is_link)); reg.add_field_method_get("is_hidden", |_, me| Ok(me.is_hidden)); + // Metadata + reg.add_field_method_get("is_file", |_, me| Ok(me.is_file())); + reg.add_field_method_get("is_dir", |_, me| Ok(me.is_dir())); + reg.add_field_method_get("is_symlink", |_, me| Ok(me.meta.is_symlink())); + #[cfg(unix)] + { + use std::os::unix::prelude::FileTypeExt; + reg.add_field_method_get("is_block_device", |_, me| { + Ok(me.meta.file_type().is_block_device()) + }); + reg + .add_field_method_get("is_char_device", |_, me| Ok(me.meta.file_type().is_char_device())); + reg.add_field_method_get("is_fifo", |_, me| Ok(me.meta.file_type().is_fifo())); + reg.add_field_method_get("is_socket", |_, me| Ok(me.meta.file_type().is_socket())); + } + reg.add_field_method_get("length", |_, me| Ok(me.meta.len())); + reg.add_field_method_get("created", |_, me| { + Ok(me.meta.created()?.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok()) + }); + reg.add_field_method_get("modified", |_, me| { + Ok(me.meta.modified()?.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok()) + }); + reg.add_field_method_get("accessed", |_, me| { + Ok(me.meta.accessed()?.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok()) + }); + reg.add_method("permissions", |_, me, ()| Ok(shared::permissions(me.meta.permissions()))); + + // Extension reg.add_field_method_get("name", |_, me| { Ok(me.url.file_name().map(|n| n.to_string_lossy().to_string())) }); - reg.add_field_method_get("permissions", |_, me| { - Ok(shared::permissions(me.meta.permissions())) - }); - reg.add_function("size", |_, me: AnyUserData| { let file = me.borrow::()?; if !file.is_dir() { - return Ok(file.length); + return Ok(file.meta.len()); } let folder = me.named_user_value::>("folder")?; - Ok(folder.files.sizes.get(&file.url).copied().unwrap_or(file.length)) + Ok(folder.files.sizes.get(&file.url).copied().unwrap_or(file.meta.len())) }); - reg.add_function("mime", |_, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let file = me.borrow::()?; Ok(manager.mimetype.get(&file.url).cloned()) }); - reg.add_function("prefix", |_, me: AnyUserData| { let folder = me.named_user_value::>("folder")?; if !folder.cwd.is_search() { @@ -87,7 +109,6 @@ impl Files { p.next_back(); Ok(Some(p.as_path().to_string_lossy().to_string())) }); - reg.add_method("icon", |_, me, ()| { Ok( THEME @@ -97,7 +118,6 @@ impl Files { .map(|x| x.display.to_string()), ) }); - reg.add_function("style", |_, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let file = me.borrow::()?; @@ -110,13 +130,11 @@ impl Files { .map(|x| Style::from(x.style)), ) }); - reg.add_function("is_hovered", |_, me: AnyUserData| { let folder = me.named_user_value::>("folder")?; let file = me.borrow::()?; Ok(matches!(folder.hovered(), Some(f) if f.url == file.url)) }); - reg.add_function("is_yanked", |_, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let file = me.borrow::()?; @@ -128,7 +146,6 @@ impl Files { 1u8 }) }); - reg.add_function("is_selected", |_, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let folder = me.named_user_value::>("folder")?; @@ -142,7 +159,6 @@ impl Files { manager.active().mode.pending(folder.offset + idx, selected) }) }); - reg.add_function("found", |lua, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let Some(finder) = &manager.active().finder else { @@ -158,7 +174,6 @@ impl Files { } Ok(None) }); - reg.add_function("highlights", |_, me: AnyUserData| { let manager = me.named_user_value::>("manager")?; let Some(finder) = &manager.active().finder else {