diff options
author | Lzzzzzt <101313294+Lzzzzzt@users.noreply.github.com> | 2023-08-05 06:36:38 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-04 18:36:38 -0400 |
commit | a97ca3027bf66dbf16db7737ad5288fa9aaa89f2 (patch) | |
tree | 0dbf25b3c658d109d195ca753e9b941c36e332f4 | |
parent | 48e42e21dd0c0774cdee649b2134a12ea9c5960e (diff) |
feat: add user & group on foot and make linemode configturable and more options (#385)
* add user & group on footer
* linemode have more options
* linemode have more options
* linemode have more options
-rw-r--r-- | Cargo.lock | 16 | ||||
-rw-r--r-- | Cargo.toml | 9 | ||||
-rw-r--r-- | config/joshuto.toml | 5 | ||||
-rw-r--r-- | config/keymap.toml | 5 | ||||
-rw-r--r-- | docs/configuration/joshuto.toml.md | 10 | ||||
-rw-r--r-- | src/config/general/display_raw.rs | 6 | ||||
-rw-r--r-- | src/config/option/linemodes.rs | 69 | ||||
-rw-r--r-- | src/key_command/impl_comment.rs | 11 | ||||
-rw-r--r-- | src/key_command/impl_display.rs | 2 | ||||
-rw-r--r-- | src/ui/widgets/tui_dirlist_detailed.rs | 23 | ||||
-rw-r--r-- | src/ui/widgets/tui_footer.rs | 7 | ||||
-rw-r--r-- | src/util/unix.rs | 18 |
12 files changed, 132 insertions, 49 deletions
@@ -80,6 +80,9 @@ name = "bitflags" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +dependencies = [ + "serde", +] [[package]] name = "bstr" @@ -471,6 +474,7 @@ version = "0.9.5" dependencies = [ "alphanumeric-sort", "ansi-to-tui", + "bitflags 2.3.3", "chrono", "colors-transform", "dirs-next", @@ -478,6 +482,7 @@ dependencies = [ "globset", "lazy_static", "libc", + "nix", "notify", "open", "phf", @@ -495,7 +500,6 @@ dependencies = [ "trash", "unicode-segmentation", "unicode-width", - "users", "uuid", "walkdir", "whoami", @@ -1265,16 +1269,6 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -27,7 +27,7 @@ rustyline = "^12" serde = "^1" serde_derive = "^1" shell-words = "^1" -shellexpand = { version = "^3", features = ["full"]} +shellexpand = { version = "^3", features = ["full"] } signal-hook = "^0" structopt = "^0" termion = "^2" @@ -35,10 +35,15 @@ toml = "^0" trash = { version = "^3", optional = true } unicode-segmentation = "^1" unicode-width = "^0" -users = "^0" whoami = "^1" xdg = "^2" walkdir = "^2" +bitflags = { version = "^2", features = ["serde"] } + +[dependencies.nix] +version = "^0" +default_features = false +features = ["user"] [dependencies.ratatui] version = "^0" diff --git a/config/joshuto.toml b/config/joshuto.toml index c106057..3986e35 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -22,6 +22,11 @@ tilde_in_titlebar = true # none, absolute, relative line_number_style = "none" +# size, mtime, user, gourp, perm. can be combined with |. +# `none` to disable, `all` to enable all +# all and none can't be combined with other options +linemode = "size" + [display.sort] # lexical, mtime, natural, size, ext sort_method = "natural" diff --git a/config/keymap.toml b/config/keymap.toml index 5e9e6d6..8a9f371 100644 --- a/config/keymap.toml +++ b/config/keymap.toml @@ -119,7 +119,10 @@ keymap = [ { keys = ["m", "s"], command = "linemode size" }, { keys = ["m", "m"], command = "linemode mtime" }, - { keys = ["m", "M"], command = "linemode sizemtime" }, + { keys = ["m", "M"], command = "linemode size | mtime" }, + { keys = ["m", "u"], command = "linemode user" }, + { keys = ["m", "U"], command = "linemode user | group" }, + { keys = ["m", "p"], command = "linemode perm" }, { keys = ["g", "r"], command = "cd /" }, { keys = ["g", "c"], command = "cd ~/.config" }, diff --git a/docs/configuration/joshuto.toml.md b/docs/configuration/joshuto.toml.md index 4a19692..1e0ed5c 100644 --- a/docs/configuration/joshuto.toml.md +++ b/docs/configuration/joshuto.toml.md @@ -56,6 +56,16 @@ tilde_in_titlebar = true # - relative line_number_style = "none" +# Options include +# - size +# - mtime +# - user +# - group +# - perm +# - none (can't be combined with other options) +# - all (can't be combined with other options) +linemode = "size" + # Configurations related to file sorting [display.sort] # Options include diff --git a/src/config/general/display_raw.rs b/src/config/general/display_raw.rs index a340305..baaa101 100644 --- a/src/config/general/display_raw.rs +++ b/src/config/general/display_raw.rs @@ -59,6 +59,9 @@ pub struct DisplayOptionRaw { #[serde(default)] pub line_number_style: String, + + #[serde(default)] + pub linemode: LineMode, } impl std::default::Default for DisplayOptionRaw { @@ -75,6 +78,7 @@ impl std::default::Default for DisplayOptionRaw { sort_options: SortOptionRaw::default(), tilde_in_titlebar: true, line_number_style: "none".to_string(), + linemode: LineMode::default(), } } } @@ -125,7 +129,7 @@ impl From<DisplayOptionRaw> for DisplayOption { default_tab_display_option: TabDisplayOption { sort_options: raw.sort_options.into(), // todo: make default line mode configurable - linemode: LineMode::Size, + linemode: raw.linemode, ..Default::default() }, } diff --git a/src/config/option/linemodes.rs b/src/config/option/linemodes.rs index 372a3ad..591862f 100644 --- a/src/config/option/linemodes.rs +++ b/src/config/option/linemodes.rs @@ -1,31 +1,62 @@ +use serde_derive::Deserialize; + use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult}; -#[derive(Clone, Debug, Copy, Default)] -pub enum LineMode { - #[default] - Size, - MTime, - SizeMTime, +bitflags::bitflags! { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)] + #[serde(transparent)] + pub struct LineMode: u8 { + const size = 1 << 0; + const mtime = 1 << 1; + const user = 1 << 2; + const group = 1 << 3; + const perm = 1 << 4; + } +} + +impl Default for LineMode { + fn default() -> Self { + Self::size + } } impl LineMode { pub fn from_string(name: &str) -> JoshutoResult<LineMode> { match name { - "size" => Ok(LineMode::Size), - "mtime" => Ok(LineMode::MTime), - "sizemtime" => Ok(LineMode::SizeMTime), - _ => Err(JoshutoError::new( - JoshutoErrorKind::InvalidParameters, - format!("Linemode '{}' unknown.", name), - )), + "all" => Ok(LineMode::all()), + "none" => Ok(LineMode::empty()), + _ => { + let mut flags = name.split('|'); + + let mut linemode = LineMode::empty(); + + flags.try_for_each(|flag| { + match flag.trim() { + "size" => linemode |= LineMode::size, + "mtime" => linemode |= LineMode::mtime, + "user" => linemode |= LineMode::user, + "group" => linemode |= LineMode::group, + "perm" => linemode |= LineMode::perm, + flag => { + return Err(JoshutoError::new( + JoshutoErrorKind::InvalidParameters, + format!("Linemode '{}' unknown.", flag), + )) + } + } + + Ok(()) + })?; + + Ok(linemode) + } } } - pub fn as_str(&self) -> &'static str { - match self { - Self::Size => "size", - Self::MTime => "mtime", - Self::SizeMTime => "sizemtime", - } + pub fn as_string(&self) -> String { + self.iter_names() + .map(|f| f.0) + .collect::<Vec<_>>() + .join(" | ") } } diff --git a/src/key_command/impl_comment.rs b/src/key_command/impl_comment.rs index 82806f7..a7f373f 100644 --- a/src/key_command/impl_comment.rs +++ b/src/key_command/impl_comment.rs @@ -7,10 +7,13 @@ impl CommandComment for Command { // These comments are displayed at the help page fn comment(&self) -> &'static str { match self { - Self::SetLineMode(linemode) => match linemode { - LineMode::Size => "Show files with size", - LineMode::MTime => "Show files with modified time", - LineMode::SizeMTime => "Show files with size and modified time", + Self::SetLineMode(linemode) => match *linemode { + LineMode::size => "Show files with size", + LineMode::mtime => "Show files with modified time", + LineMode::user => "Show files with user", + LineMode::group => "Show files with group", + LineMode::perm => "Show files with permission", + _ => "Show files with multi-attribution", }, Self::Escape => "Escape from visual mode (cancel)", Self::BulkRename => "Bulk rename", diff --git a/src/key_command/impl_display.rs b/src/key_command/impl_display.rs index a20031e..6049467 100644 --- a/src/key_command/impl_display.rs +++ b/src/key_command/impl_display.rs @@ -10,7 +10,7 @@ impl std::fmt::Display for Command { Self::CursorMoveUp { offset } => write!(f, "{} {}", self.command(), offset), Self::CursorMoveDown { offset } => write!(f, "{} {}", self.command(), offset), - Self::SetLineMode(mode) => write!(f, "{} {}", self.command(), mode.as_str()), + Self::SetLineMode(mode) => write!(f, "{} {}", self.command(), mode.as_string()), Self::ParentCursorMoveUp { offset } => write!(f, "{} {}", self.command(), offset), Self::ParentCursorMoveDown { offset } => write!(f, "{} {}", self.command(), offset), diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs index 3373134..6e2a2a8 100644 --- a/src/ui/widgets/tui_dirlist_detailed.rs +++ b/src/ui/widgets/tui_dirlist_detailed.rs @@ -7,9 +7,9 @@ use ratatui::widgets::Widget; use crate::config::option::{DisplayOption, LineMode, LineNumberStyle, TabDisplayOption}; use crate::fs::{FileType, JoshutoDirEntry, JoshutoDirList, LinkType}; -use crate::util::format; use crate::util::string::UnicodeTruncate; use crate::util::style; +use crate::util::{format, unix}; use unicode_width::UnicodeWidthStr; const MIN_LEFT_LABEL_WIDTH: i32 = 15; @@ -144,15 +144,18 @@ fn print_entry( let right_label_original = format!( " {}{} ", symlink_string, - match linemode { - LineMode::Size => get_entry_size_string(entry), - LineMode::MTime => format::mtime_to_string(entry.metadata.modified()), - LineMode::SizeMTime => format!( - "{} {}", - get_entry_size_string(entry), - format::mtime_to_string(entry.metadata.modified()) - ), - } + linemode + .iter_names() + .map(|f| match f.0 { + "size" => get_entry_size_string(entry), + "mtime" => format::mtime_to_string(entry.metadata.modified()), + "user" => unix::uid_to_string(entry.metadata.uid).unwrap_or("unknown".into()), + "group" => unix::gid_to_string(entry.metadata.gid).unwrap_or("unknown".into()), + "perm" => unix::mode_to_string(entry.metadata.mode), + _ => unreachable!(), + }) + .collect::<Vec<_>>() + .join(" ") ); // draw prefix first diff --git a/src/ui/widgets/tui_footer.rs b/src/ui/widgets/tui_footer.rs index dc42ee6..16c4ac4 100644 --- a/src/ui/widgets/tui_footer.rs +++ b/src/ui/widgets/tui_footer.rs @@ -49,6 +49,9 @@ impl<'a> Widget for TuiFooter<'a> { let mode_str = unix::mode_to_string(entry.metadata.permissions_ref().mode()); + let user_str = unix::uid_to_string(entry.metadata.uid).unwrap_or("unknown".into()); + let group_str = unix::gid_to_string(entry.metadata.gid).unwrap_or("unknown".into()); + let mtime_str = format::mtime_to_string(entry.metadata.modified()); let size_str = format::file_size_to_string(entry.metadata.len()); @@ -70,6 +73,10 @@ impl<'a> Widget for TuiFooter<'a> { }), Span::styled(mode_str, mode_style), Span::raw(" "), + Span::raw(user_str), + Span::raw(" "), + Span::raw(group_str), + Span::raw(" "), Span::raw(format!("{}/{}", i + 1, self.dirlist.len())), Span::raw(" "), Span::raw(mtime_str), diff --git a/src/util/unix.rs b/src/util/unix.rs index ac66e2b..61d41fb 100644 --- a/src/util/unix.rs +++ b/src/util/unix.rs @@ -67,3 +67,21 @@ pub fn expand_shell_string(s: &str) -> path::PathBuf { let tilde_path = path::PathBuf::from(tilde_cow.as_ref()); tilde_path } + +pub fn uid_to_string(uid: u32) -> Option<String> { + use nix::unistd::{Uid, User}; + + match User::from_uid(Uid::from(uid)) { + Ok(Some(user)) => Some(user.name), + _ => None, + } +} + +pub fn gid_to_string(gid: u32) -> Option<String> { + use nix::unistd::{Gid, Group}; + + match Group::from_gid(Gid::from(gid)) { + Ok(Some(group)) => Some(group.name), + _ => None, + } +} |