diff --git a/Cargo.lock b/Cargo.lock index 0d1153c8..c5cca5b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,12 +279,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chrono" version = "0.4.38" @@ -1267,18 +1261,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" -[[package]] -name = "nix" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "cfg_aliases", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -2843,7 +2825,6 @@ dependencies = [ "futures", "libc", "mlua", - "nix", "ratatui", "scopeguard", "signal-hook-tokio", diff --git a/yazi-fm/src/lives/file.rs b/yazi-fm/src/lives/file.rs index ffa78318..96443822 100644 --- a/yazi-fm/src/lives/file.rs +++ b/yazi-fm/src/lives/file.rs @@ -2,21 +2,27 @@ use std::ops::Deref; 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_plugin::{ + bindings::{Cast, Cha, Icon, Range}, + elements::Style, + url::Url, +}; use yazi_shared::MIME_DIR; use super::{CtxRef, SCOPE}; pub(super) struct File { - idx: usize, + idx: usize, folder: *const yazi_core::folder::Folder, - tab: *const yazi_core::tab::Tab, + tab: *const yazi_core::tab::Tab, } impl Deref for File { type Target = yazi_shared::fs::File; - fn deref(&self) -> &Self::Target { &self.folder().files[self.idx] } + fn deref(&self) -> &Self::Target { + &self.folder().files[self.idx] + } } impl File { @@ -33,7 +39,7 @@ impl File { lua.register_userdata_type::(|reg| { reg.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); 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.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() }); @@ -131,8 +137,12 @@ impl File { } #[inline] - fn folder(&self) -> &yazi_core::folder::Folder { unsafe { &*self.folder } } + fn folder(&self) -> &yazi_core::folder::Folder { + unsafe { &*self.folder } + } #[inline] - fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } + fn tab(&self) -> &yazi_core::tab::Tab { + unsafe { &*self.tab } + } } diff --git a/yazi-plugin/preset/components/folder.lua b/yazi-plugin/preset/components/folder.lua index f5cbcf97..2ddd7197 100644 --- a/yazi-plugin/preset/components/folder.lua +++ b/yazi-plugin/preset/components/folder.lua @@ -22,7 +22,7 @@ function Folder:linemode(area, files) elseif mode == "permissions" then spans[#spans + 1] = ui.Span(f.cha:permissions() or "") elseif mode == "owner" then - spans[#spans + 1] = ui.Span(f.cha.owner or "") + spans[#spans + 1] = ui.Span(f.cha:owner() or "") end spans[#spans + 1] = ui.Span(" ") diff --git a/yazi-plugin/src/bindings/cha.rs b/yazi-plugin/src/bindings/cha.rs index bc9b092d..e418fcc3 100644 --- a/yazi-plugin/src/bindings/cha.rs +++ b/yazi-plugin/src/bindings/cha.rs @@ -24,7 +24,6 @@ impl Cha { { reg.add_field_method_get("uid", |_, me| Ok(me.uid)); reg.add_field_method_get("gid", |_, me| Ok(me.gid)); - reg.add_field_method_get("owner", |_, me| Ok(me.owner.clone())); } reg.add_field_method_get("length", |_, me| Ok(me.len)); @@ -45,6 +44,14 @@ impl Cha { None::, ) }); + reg.add_method("owner", |_, me, ()| { + Ok( + #[cfg(unix)] + Some(yazi_shared::fs::owner(me.uid, me.gid)), + #[cfg(windows)] + None::, + ) + }); })?; Ok(()) diff --git a/yazi-plugin/src/bindings/file.rs b/yazi-plugin/src/bindings/file.rs index 3c7c8df8..271d89af 100644 --- a/yazi-plugin/src/bindings/file.rs +++ b/yazi-plugin/src/bindings/file.rs @@ -11,7 +11,7 @@ impl File { pub fn register(lua: &Lua) -> mlua::Result<()> { lua.register_userdata_type::(|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.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() }); diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index 0864e7f6..73a6aed9 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -2,20 +2,15 @@ use mlua::{AnyUserData, IntoLuaMulti, Lua, Table, Value}; use yazi_shared::{emit, event::Cmd, Layer, PeekError}; use super::Utils; -use crate::{ - bindings::{FileRef, Window}, - cast_to_renderable, - elements::{Paragraph, RectRef, Renderable}, - external::{self, Highlighter}, -}; +use crate::{bindings::{FileRef, Window}, cast_to_renderable, elements::{Paragraph, RectRef, Renderable}, external::{self, Highlighter}}; pub struct PreviewLock { pub url: yazi_shared::fs::Url, pub cha: yazi_shared::fs::Cha, - pub skip: usize, + pub skip: usize, pub window: Window, - pub data: Vec>, + pub data: Vec>, } impl<'a> TryFrom> for PreviewLock { @@ -24,11 +19,11 @@ impl<'a> TryFrom> for PreviewLock { fn try_from(t: Table) -> Result { let file: FileRef = t.raw_get("file")?; Ok(Self { - url: file.url(), - cha: file.cha.clone(), - skip: t.raw_get("skip")?, + url: file.url(), + cha: file.cha, + skip: t.raw_get("skip")?, window: t.raw_get("window")?, - data: Default::default(), + data: Default::default(), }) } } diff --git a/yazi-shared/src/fs/cha.rs b/yazi-shared/src/fs/cha.rs index 098100cc..d6eb4696 100644 --- a/yazi-shared/src/fs/cha.rs +++ b/yazi-shared/src/fs/cha.rs @@ -18,7 +18,7 @@ bitflags! { } } -#[derive(Clone, Debug, Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct Cha { pub kind: ChaKind, pub len: u64, @@ -31,8 +31,6 @@ pub struct Cha { pub uid: u32, #[cfg(unix)] pub gid: u32, - #[cfg(unix)] - pub owner: String, } impl From for Cha { @@ -82,12 +80,6 @@ impl From for Cha { use std::os::unix::fs::MetadataExt; m.gid() }, - #[cfg(unix)] - owner: { - use std::os::unix::fs::MetadataExt; - users::get_user_by_uid(m.uid()).unwrap().name().to_str().unwrap_or_default().to_string() - + " " + users::get_group_by_gid(m.gid()).unwrap().name().to_str().unwrap_or_default() - }, } } } diff --git a/yazi-shared/src/fs/fns.rs b/yazi-shared/src/fs/fns.rs index 97934573..4a081739 100644 --- a/yazi-shared/src/fs/fns.rs +++ b/yazi-shared/src/fs/fns.rs @@ -1,8 +1,16 @@ -use std::{collections::VecDeque, fs::Metadata, path::{Path, PathBuf}}; +use std::{ + collections::VecDeque, + fs::Metadata, + path::{Path, PathBuf}, +}; use anyhow::Result; use filetime::{set_file_mtime, FileTime}; -use tokio::{fs, io, select, sync::{mpsc, oneshot}, time}; +use tokio::{ + fs, io, select, + sync::{mpsc, oneshot}, + time, +}; pub async fn accessible(path: &Path) -> bool { match fs::symlink_metadata(path).await { @@ -103,7 +111,10 @@ pub fn copy_with_progress( #[cfg(unix)] #[allow(clippy::collapsible_else_if)] pub fn permissions(m: libc::mode_t) -> String { - use libc::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; + use libc::{ + S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, + S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR, + }; let mut s = String::with_capacity(10); // File type @@ -121,32 +132,72 @@ pub fn permissions(m: libc::mode_t) -> String { s.push(if m & S_IRUSR != 0 { 'r' } else { '-' }); s.push(if m & S_IWUSR != 0 { 'w' } else { '-' }); s.push(if m & S_IXUSR != 0 { - if m & S_ISUID != 0 { 's' } else { 'x' } + if m & S_ISUID != 0 { + 's' + } else { + 'x' + } } else { - if m & S_ISUID != 0 { 'S' } else { '-' } + if m & S_ISUID != 0 { + 'S' + } else { + '-' + } }); // Group s.push(if m & S_IRGRP != 0 { 'r' } else { '-' }); s.push(if m & S_IWGRP != 0 { 'w' } else { '-' }); s.push(if m & S_IXGRP != 0 { - if m & S_ISGID != 0 { 's' } else { 'x' } + if m & S_ISGID != 0 { + 's' + } else { + 'x' + } } else { - if m & S_ISGID != 0 { 'S' } else { '-' } + if m & S_ISGID != 0 { + 'S' + } else { + '-' + } }); // Other s.push(if m & S_IROTH != 0 { 'r' } else { '-' }); s.push(if m & S_IWOTH != 0 { 'w' } else { '-' }); s.push(if m & S_IXOTH != 0 { - if m & S_ISVTX != 0 { 't' } else { 'x' } + if m & S_ISVTX != 0 { + 't' + } else { + 'x' + } } else { - if m & S_ISVTX != 0 { 'T' } else { '-' } + if m & S_ISVTX != 0 { + 'T' + } else { + '-' + } }); s } +#[cfg(unix)] +pub fn owner(uid: u32, gid: u32) -> String { + let username = match users::get_user_by_uid(uid) { + Some(u) => u.name().to_str().unwrap_or_default().to_string(), + None => String::default(), + }; + let groupname = match users::get_group_by_gid(gid) { + Some(g) => g.name().to_str().unwrap_or_default().to_string(), + None => String::default(), + }; + format!("{username} {groupname}") + //users::get_user_by_uid(uid).unwrap().name().to_str().unwrap_or_default().to_string() + //+ " " + //+ users::get_group_by_gid(gid).unwrap().name().to_str().unwrap_or_default() +} + // Find the max common root in a list of files // e.g. /a/b/c, /a/b/d -> /a/b // /aa/bb/cc, /aa/dd/ee -> /aa