From b0800bbe73b4f6de59169758b77e2962be7a8903 Mon Sep 17 00:00:00 2001 From: AidanV Date: Sat, 20 Apr 2024 01:21:24 -0700 Subject: [PATCH] working file ownership --- Cargo.lock | 30 ++++++++++ yazi-config/preset/keymap.toml | 1 + yazi-fm/Cargo.toml | 1 + yazi-fm/src/lives/file.rs | 2 +- yazi-plugin/preset/components/folder.lua | 2 + yazi-plugin/src/bindings/cha.rs | 5 +- yazi-plugin/src/bindings/file.rs | 6 +- yazi-plugin/src/utils/preview.rs | 19 ++++--- yazi-shared/Cargo.toml | 1 + yazi-shared/src/fs/cha.rs | 70 ++++++++++++++++-------- 10 files changed, 104 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1608b935..0d1153c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,6 +279,12 @@ 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" @@ -1261,6 +1267,18 @@ 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" @@ -2272,6 +2290,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" @@ -2815,6 +2843,7 @@ dependencies = [ "futures", "libc", "mlua", + "nix", "ratatui", "scopeguard", "signal-hook-tokio", @@ -2920,6 +2949,7 @@ dependencies = [ "serde", "tokio", "tracing", + "users", ] [[package]] diff --git a/yazi-config/preset/keymap.toml b/yazi-config/preset/keymap.toml index 0ab02b91..73de0b62 100644 --- a/yazi-config/preset/keymap.toml +++ b/yazi-config/preset/keymap.toml @@ -88,6 +88,7 @@ keymap = [ { on = [ "m", "s" ], run = "linemode size", desc = "Set linemode to size" }, { on = [ "m", "p" ], run = "linemode permissions", desc = "Set linemode to permissions" }, { on = [ "m", "m" ], run = "linemode mtime", desc = "Set linemode to mtime" }, + { on = [ "m", "o" ], run = "linemode owner", desc = "Set linemode to owner" }, { on = [ "m", "n" ], run = "linemode none", desc = "Set linemode to none" }, # Copy diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index 938159fd..df88240e 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -35,6 +35,7 @@ tokio-util = "0.7.10" tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } tracing-appender = "0.2.3" tracing-subscriber = "0.3.18" +nix = "0.28.0" [target."cfg(unix)".dependencies] libc = "0.2.153" diff --git a/yazi-fm/src/lives/file.rs b/yazi-fm/src/lives/file.rs index a257d3a7..ffa78318 100644 --- a/yazi-fm/src/lives/file.rs +++ b/yazi-fm/src/lives/file.rs @@ -33,7 +33,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)); + reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.cha.clone())); 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/preset/components/folder.lua b/yazi-plugin/preset/components/folder.lua index aaaa7df5..e0db69e5 100644 --- a/yazi-plugin/preset/components/folder.lua +++ b/yazi-plugin/preset/components/folder.lua @@ -21,6 +21,8 @@ function Folder:linemode(area, files) spans[#spans + 1] = ui.Span(time and os.date("%y-%m-%d %H:%M", time // 1) or "") 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 "it failed") end spans[#spans + 1] = ui.Span(" ") diff --git a/yazi-plugin/src/bindings/cha.rs b/yazi-plugin/src/bindings/cha.rs index 68b81c05..bc9b092d 100644 --- a/yazi-plugin/src/bindings/cha.rs +++ b/yazi-plugin/src/bindings/cha.rs @@ -24,6 +24,7 @@ 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)); @@ -51,5 +52,7 @@ impl Cha { } impl> Cast for Cha { - fn cast(lua: &Lua, data: T) -> mlua::Result { lua.create_any_userdata(data.into()) } + fn cast(lua: &Lua, data: T) -> mlua::Result { + lua.create_any_userdata(data.into()) + } } diff --git a/yazi-plugin/src/bindings/file.rs b/yazi-plugin/src/bindings/file.rs index 9f714658..3c7c8df8 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)); + reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.cha.clone())); reg.add_field_method_get("link_to", |lua, me| { me.link_to.as_ref().cloned().map(|u| Url::cast(lua, u)).transpose() }); @@ -25,5 +25,7 @@ impl File { } impl> Cast for File { - fn cast(lua: &Lua, data: T) -> mlua::Result { lua.create_any_userdata(data.into()) } + fn cast(lua: &Lua, data: T) -> mlua::Result { + lua.create_any_userdata(data.into()) + } } diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index 73a6aed9..0864e7f6 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -2,15 +2,20 @@ 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 { @@ -19,11 +24,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, - skip: t.raw_get("skip")?, + url: file.url(), + cha: file.cha.clone(), + skip: t.raw_get("skip")?, window: t.raw_get("window")?, - data: Default::default(), + data: Default::default(), }) } } diff --git a/yazi-shared/Cargo.toml b/yazi-shared/Cargo.toml index f1fdf534..e03664c0 100644 --- a/yazi-shared/Cargo.toml +++ b/yazi-shared/Cargo.toml @@ -27,3 +27,4 @@ tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_lev [target."cfg(unix)".dependencies] libc = "0.2.153" +users = "0.11.0" diff --git a/yazi-shared/src/fs/cha.rs b/yazi-shared/src/fs/cha.rs index a1b116ba..278fc4a6 100644 --- a/yazi-shared/src/fs/cha.rs +++ b/yazi-shared/src/fs/cha.rs @@ -18,19 +18,21 @@ bitflags! { } } -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Debug, Default)] pub struct Cha { - pub kind: ChaKind, - pub len: u64, - pub accessed: Option, - pub created: Option, - pub modified: Option, + pub kind: ChaKind, + pub len: u64, + pub accessed: Option, + pub created: Option, + pub modified: Option, #[cfg(unix)] pub permissions: libc::mode_t, #[cfg(unix)] - pub uid: u32, + pub uid: u32, #[cfg(unix)] - pub gid: u32, + pub gid: u32, + #[cfg(unix)] + pub owner: String, } impl From for Cha { @@ -58,28 +60,36 @@ impl From for Cha { } Self { - kind: ck, - len: m.len(), + kind: ck, + len: m.len(), accessed: m.accessed().ok(), // TODO: remove this once https://github.com/rust-lang/rust/issues/108277 is fixed. - created: None, + created: None, modified: m.modified().ok(), #[cfg(unix)] - permissions: { + permissions: { use std::os::unix::prelude::PermissionsExt; m.permissions().mode() as libc::mode_t }, #[cfg(unix)] - uid: { + uid: { use std::os::unix::fs::MetadataExt; m.uid() }, #[cfg(unix)] - gid: { + gid: { use std::os::unix::fs::MetadataExt; m.gid() }, + #[cfg(unix)] + owner: { + //use nix::unistd::User; + use std::os::unix::fs::MetadataExt; + //from_uid(m.uid()). + 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() + }, } } } @@ -94,28 +104,44 @@ impl Cha { impl Cha { #[inline] - pub fn is_dir(&self) -> bool { self.kind.contains(ChaKind::DIR) } + pub fn is_dir(&self) -> bool { + self.kind.contains(ChaKind::DIR) + } #[inline] - pub fn is_hidden(&self) -> bool { self.kind.contains(ChaKind::HIDDEN) } + pub fn is_hidden(&self) -> bool { + self.kind.contains(ChaKind::HIDDEN) + } #[inline] - pub fn is_link(&self) -> bool { self.kind.contains(ChaKind::LINK) } + pub fn is_link(&self) -> bool { + self.kind.contains(ChaKind::LINK) + } #[inline] - pub fn is_orphan(&self) -> bool { self.kind.contains(ChaKind::ORPHAN) } + pub fn is_orphan(&self) -> bool { + self.kind.contains(ChaKind::ORPHAN) + } #[inline] - pub fn is_block_device(&self) -> bool { self.kind.contains(ChaKind::BLOCK_DEVICE) } + pub fn is_block_device(&self) -> bool { + self.kind.contains(ChaKind::BLOCK_DEVICE) + } #[inline] - pub fn is_char_device(&self) -> bool { self.kind.contains(ChaKind::CHAR_DEVICE) } + pub fn is_char_device(&self) -> bool { + self.kind.contains(ChaKind::CHAR_DEVICE) + } #[inline] - pub fn is_fifo(&self) -> bool { self.kind.contains(ChaKind::FIFO) } + pub fn is_fifo(&self) -> bool { + self.kind.contains(ChaKind::FIFO) + } #[inline] - pub fn is_socket(&self) -> bool { self.kind.contains(ChaKind::SOCKET) } + pub fn is_socket(&self) -> bool { + self.kind.contains(ChaKind::SOCKET) + } #[inline] pub fn is_exec(&self) -> bool {