diff --git a/Cargo.lock b/Cargo.lock index 0243451a..4e77318f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2191,6 +2191,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", + "log", +] + [[package]] name = "utf8parse" version = "0.2.1" @@ -2726,6 +2736,7 @@ dependencies = [ "tokio-util", "tracing", "unicode-width", + "users", "yazi-adaptor", "yazi-config", "yazi-prebuild", diff --git a/yazi-plugin/Cargo.toml b/yazi-plugin/Cargo.toml index e777ba3e..f25c8c2c 100644 --- a/yazi-plugin/Cargo.toml +++ b/yazi-plugin/Cargo.toml @@ -31,3 +31,4 @@ tokio-util = "^0" tracing = { version = "^0", features = [ "max_level_debug", "release_max_level_warn" ] } unicode-width = "^0" yazi-prebuild = "0.1.2" +users = "0.11" \ No newline at end of file diff --git a/yazi-plugin/preset/components/status.lua b/yazi-plugin/preset/components/status.lua index 96bcc22e..a91a69dc 100644 --- a/yazi-plugin/preset/components/status.lua +++ b/yazi-plugin/preset/components/status.lua @@ -140,11 +140,35 @@ function Status:progress(area, offset) } end +function Status:owner(area) + local h = cx.active.current.hovered + if ya.target_family() ~= "unix" or h == nil then + return ui.Span("") + end + + local spans = {} + + local uid = h.cha.uid + if uid then + spans[#spans + 1] = ui.Span(ya.get_user_name_by_uid(uid) or tostring(uid)) + spans[#spans + 1] = ui.Span(" ") + end + + local gid = h.cha.gid + if gid then + spans[#spans + 1] = ui.Span(ya.get_group_name_by_gid(gid) or tostring(gid)) + spans[#spans + 1] = ui.Span(" ") + end + + return ui.Line(spans) +end + function Status:render(area) self.area = area local left = ui.Line { self:mode(), self:size(), self:name() } local right = ui.Line { self:permissions(), self:percentage(), self:position() } + -- local right = ui.Line({ self:owner(), self:permissions(), self:percentage(), self:position() }) local progress = self:progress(area, right:width()) return { ui.Paragraph(area, { left }), diff --git a/yazi-plugin/src/bindings/cha.rs b/yazi-plugin/src/bindings/cha.rs index 6589466d..630fe2a2 100644 --- a/yazi-plugin/src/bindings/cha.rs +++ b/yazi-plugin/src/bindings/cha.rs @@ -21,6 +21,8 @@ impl Cha { reg.add_field_method_get("is_char_device", |_, me| Ok(me.is_char_device())); reg.add_field_method_get("is_fifo", |_, me| Ok(me.is_fifo())); reg.add_field_method_get("is_socket", |_, me| Ok(me.is_socket())); + 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("length", |_, me| Ok(me.len)); reg.add_field_method_get("created", |_, me| { diff --git a/yazi-plugin/src/utils/mod.rs b/yazi-plugin/src/utils/mod.rs index 9f5baa10..faa02f0b 100644 --- a/yazi-plugin/src/utils/mod.rs +++ b/yazi-plugin/src/utils/mod.rs @@ -9,6 +9,8 @@ mod preview; mod target; mod text; mod time; +#[cfg(unix)] +mod unix_user; mod utils; pub use preview::*; diff --git a/yazi-plugin/src/utils/unix_user.rs b/yazi-plugin/src/utils/unix_user.rs new file mode 100644 index 00000000..83f0a179 --- /dev/null +++ b/yazi-plugin/src/utils/unix_user.rs @@ -0,0 +1,52 @@ +use std::sync::Arc; + +use mlua::{Lua, Table}; +use users::{Groups, Users, UsersCache}; + +use super::Utils; + +impl Utils { + pub(super) fn unix_user(lua: &Lua, ya: &Table) -> mlua::Result<()> { + let arc_cache = Arc::new(UsersCache::new()); + + { + let cache = Arc::clone(&arc_cache); + ya.set("get_current_uid", lua.create_function(move |_, ()| Ok(cache.get_current_uid()))?)?; + } + + { + let cache = Arc::clone(&arc_cache); + ya.set("get_current_gid", lua.create_function(move |_, ()| Ok(cache.get_current_gid()))?)?; + } + + { + let cache = Arc::clone(&arc_cache); + ya.set( + "get_user_name_by_uid", + lua.create_function(move |_, uid: u32| { + Ok( + cache + .get_user_by_uid(uid) + .and_then(|u| u.name().to_str().and_then(|n| Some(n.to_owned()))), + ) + })?, + )?; + } + + { + let cache = Arc::clone(&arc_cache); + ya.set( + "get_group_name_by_gid", + lua.create_function(move |_, gid: u32| { + Ok( + cache + .get_group_by_gid(gid) + .and_then(|g| g.name().to_str().and_then(|n| Some(n.to_owned()))), + ) + })?, + )?; + } + + Ok(()) + } +} diff --git a/yazi-plugin/src/utils/utils.rs b/yazi-plugin/src/utils/utils.rs index 44bda2c3..c2d56639 100644 --- a/yazi-plugin/src/utils/utils.rs +++ b/yazi-plugin/src/utils/utils.rs @@ -14,6 +14,8 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { Utils::target(lua, &ya)?; Utils::time(lua, &ya)?; Utils::text(lua, &ya)?; + #[cfg(unix)] + Utils::unix_user(lua, &ya)?; lua.globals().set("ya", ya) } diff --git a/yazi-shared/src/fs/cha.rs b/yazi-shared/src/fs/cha.rs index 87f4d7c5..a28f2425 100644 --- a/yazi-shared/src/fs/cha.rs +++ b/yazi-shared/src/fs/cha.rs @@ -27,6 +27,10 @@ pub struct Cha { pub modified: Option, #[cfg(unix)] pub permissions: u32, + #[cfg(unix)] + pub uid: u32, + #[cfg(unix)] + pub gid: u32, } impl From for Cha { @@ -68,6 +72,16 @@ impl From for Cha { use std::os::unix::prelude::PermissionsExt; m.permissions().mode() }, + #[cfg(unix)] + uid: { + use std::os::unix::fs::MetadataExt; + m.uid() + }, + #[cfg(unix)] + gid: { + use std::os::unix::fs::MetadataExt; + m.gid() + }, } } }