summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config/general/display_raw.rs6
-rw-r--r--src/config/option/linemodes.rs69
-rw-r--r--src/key_command/impl_comment.rs11
-rw-r--r--src/key_command/impl_display.rs2
-rw-r--r--src/ui/widgets/tui_dirlist_detailed.rs23
-rw-r--r--src/ui/widgets/tui_footer.rs7
-rw-r--r--src/util/unix.rs18
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,
+ }
+}