diff options
Diffstat (limited to 'src')
-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 |
7 files changed, 101 insertions, 35 deletions
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, + } +} |