mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-25 13:27:33 +00:00
Add options for -n or --numeric-gid-uid.
This option is only avaialable in -l. There's test for rendering, but no test for option parsing. (I don't understand that section of code.)
This commit is contained in:
parent
13b91cced4
commit
4ea79ee11d
@ -65,6 +65,7 @@ complete -c exa -s 't' -l 'time' -x -d "Which timestamp field to list" -a "
|
|||||||
created\t'Display created time'
|
created\t'Display created time'
|
||||||
"
|
"
|
||||||
complete -c exa -s 'm' -l 'modified' -d "Use the modified timestamp field"
|
complete -c exa -s 'm' -l 'modified' -d "Use the modified timestamp field"
|
||||||
|
complete -c -exa -s 'n' -l 'numeric-uid-gid' -d "List numeric user and group IDs."
|
||||||
complete -c exa -l 'changed' -d "Use the changed timestamp field"
|
complete -c exa -l 'changed' -d "Use the changed timestamp field"
|
||||||
complete -c exa -s 'u' -l 'accessed' -d "Use the accessed timestamp field"
|
complete -c exa -s 'u' -l 'accessed' -d "Use the accessed timestamp field"
|
||||||
complete -c exa -s 'U' -l 'created' -d "Use the created timestamp field"
|
complete -c exa -s 'U' -l 'created' -d "Use the created timestamp field"
|
||||||
|
@ -39,6 +39,7 @@ __exa() {
|
|||||||
{-H,--links}"[List each file's number of hard links]" \
|
{-H,--links}"[List each file's number of hard links]" \
|
||||||
{-i,--inode}"[List each file's inode number]" \
|
{-i,--inode}"[List each file's inode number]" \
|
||||||
{-m,--modified}"[Use the modified timestamp field]" \
|
{-m,--modified}"[Use the modified timestamp field]" \
|
||||||
|
{-n, --numeric-uid-gid}"[List numeric user and group IDs.]" \
|
||||||
{-S,--blocks}"[List each file's number of filesystem blocks]" \
|
{-S,--blocks}"[List each file's number of filesystem blocks]" \
|
||||||
{-t,--time}="[Which time field to show]:(time field):(accessed changed created modified)" \
|
{-t,--time}="[Which time field to show]:(time field):(accessed changed created modified)" \
|
||||||
--time-style="[How to format timestamps]:(time style):(default iso long-iso full-iso)" \
|
--time-style="[How to format timestamps]:(time style):(default iso long-iso full-iso)" \
|
||||||
|
@ -140,6 +140,9 @@ These options are available when running with `--long` (`-l`):
|
|||||||
`-m`, `--modified`
|
`-m`, `--modified`
|
||||||
: Use the modified timestamp field.
|
: Use the modified timestamp field.
|
||||||
|
|
||||||
|
`-n`, `--numeric-uid-gid`
|
||||||
|
: List numeric user and group IDs.
|
||||||
|
|
||||||
`-S`, `--blocks`
|
`-S`, `--blocks`
|
||||||
: List each file’s number of file system blocks.
|
: List each file’s number of file system blocks.
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ const SORTS: Values = &[ "name", "Name", "size", "extension",
|
|||||||
pub static BINARY: Arg = Arg { short: Some(b'b'), long: "binary", takes_value: TakesValue::Forbidden };
|
pub static BINARY: Arg = Arg { short: Some(b'b'), long: "binary", takes_value: TakesValue::Forbidden };
|
||||||
pub static BYTES: Arg = Arg { short: Some(b'B'), long: "bytes", takes_value: TakesValue::Forbidden };
|
pub static BYTES: Arg = Arg { short: Some(b'B'), long: "bytes", takes_value: TakesValue::Forbidden };
|
||||||
pub static GROUP: Arg = Arg { short: Some(b'g'), long: "group", takes_value: TakesValue::Forbidden };
|
pub static GROUP: Arg = Arg { short: Some(b'g'), long: "group", takes_value: TakesValue::Forbidden };
|
||||||
|
pub static NUM_UGID: Arg = Arg { short: Some(b'n'), long: "numeric-uid-gid", takes_value: TakesValue::Forbidden };
|
||||||
pub static HEADER: Arg = Arg { short: Some(b'h'), long: "header", takes_value: TakesValue::Forbidden };
|
pub static HEADER: Arg = Arg { short: Some(b'h'), long: "header", takes_value: TakesValue::Forbidden };
|
||||||
pub static ICONS: Arg = Arg { short: None, long: "icons", takes_value: TakesValue::Forbidden };
|
pub static ICONS: Arg = Arg { short: None, long: "icons", takes_value: TakesValue::Forbidden };
|
||||||
pub static INODE: Arg = Arg { short: Some(b'i'), long: "inode", takes_value: TakesValue::Forbidden };
|
pub static INODE: Arg = Arg { short: Some(b'i'), long: "inode", takes_value: TakesValue::Forbidden };
|
||||||
@ -74,7 +75,7 @@ pub static ALL_ARGS: Args = Args(&[
|
|||||||
&ALL, &LIST_DIRS, &LEVEL, &REVERSE, &SORT, &DIRS_FIRST,
|
&ALL, &LIST_DIRS, &LEVEL, &REVERSE, &SORT, &DIRS_FIRST,
|
||||||
&IGNORE_GLOB, &GIT_IGNORE, &ONLY_DIRS,
|
&IGNORE_GLOB, &GIT_IGNORE, &ONLY_DIRS,
|
||||||
|
|
||||||
&BINARY, &BYTES, &GROUP, &HEADER, &ICONS, &INODE, &LINKS, &MODIFIED, &CHANGED,
|
&BINARY, &BYTES, &GROUP, &NUM_UGID, &HEADER, &ICONS, &INODE, &LINKS, &MODIFIED, &CHANGED,
|
||||||
&BLOCKS, &TIME, &ACCESSED, &CREATED, &TIME_STYLE,
|
&BLOCKS, &TIME, &ACCESSED, &CREATED, &TIME_STYLE,
|
||||||
&NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME,
|
&NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME,
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ LONG VIEW OPTIONS
|
|||||||
-H, --links list each file's number of hard links
|
-H, --links list each file's number of hard links
|
||||||
-i, --inode list each file's inode number
|
-i, --inode list each file's inode number
|
||||||
-m, --modified use the modified timestamp field
|
-m, --modified use the modified timestamp field
|
||||||
|
-n, --numeric-uid-gid list numeric user and group IDs
|
||||||
-S, --blocks show number of file system blocks
|
-S, --blocks show number of file system blocks
|
||||||
-t, --time FIELD which timestamp field to list (modified, accessed, created)
|
-t, --time FIELD which timestamp field to list (modified, accessed, created)
|
||||||
-u, --accessed use the accessed timestamp field
|
-u, --accessed use the accessed timestamp field
|
||||||
|
@ -4,7 +4,7 @@ use crate::options::parser::MatchedFlags;
|
|||||||
use crate::output::{View, Mode, TerminalWidth, grid, details};
|
use crate::output::{View, Mode, TerminalWidth, grid, details};
|
||||||
use crate::output::grid_details::{self, RowThreshold};
|
use crate::output::grid_details::{self, RowThreshold};
|
||||||
use crate::output::file_name::Options as FileStyle;
|
use crate::output::file_name::Options as FileStyle;
|
||||||
use crate::output::table::{TimeTypes, SizeFormat, Columns, Options as TableOptions};
|
use crate::output::table::{TimeTypes, SizeFormat, UserFormat, Columns, Options as TableOptions};
|
||||||
use crate::output::time::TimeFormat;
|
use crate::output::time::TimeFormat;
|
||||||
|
|
||||||
|
|
||||||
@ -183,8 +183,9 @@ impl TableOptions {
|
|||||||
fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
|
fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
|
||||||
let time_format = TimeFormat::deduce(matches, vars)?;
|
let time_format = TimeFormat::deduce(matches, vars)?;
|
||||||
let size_format = SizeFormat::deduce(matches)?;
|
let size_format = SizeFormat::deduce(matches)?;
|
||||||
|
let user_format = UserFormat::deduce(matches)?;
|
||||||
let columns = Columns::deduce(matches)?;
|
let columns = Columns::deduce(matches)?;
|
||||||
Ok(Self { time_format, size_format, columns })
|
Ok(Self { time_format, size_format, columns , user_format})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,6 +266,14 @@ impl TimeFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UserFormat {
|
||||||
|
fn deduce(matches: &MatchedFlags<'_>) -> Result<Self, OptionsError> {
|
||||||
|
let flag = matches.has(&flags::NUM_UGID)?;
|
||||||
|
Ok(if flag { Self::Numeric } else { Self::Name })
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl TimeTypes {
|
impl TimeTypes {
|
||||||
|
|
||||||
|
@ -3,10 +3,11 @@ use users::{Users, Groups};
|
|||||||
|
|
||||||
use crate::fs::fields as f;
|
use crate::fs::fields as f;
|
||||||
use crate::output::cell::TextCell;
|
use crate::output::cell::TextCell;
|
||||||
|
use crate::output::table::UserFormat;
|
||||||
|
|
||||||
|
|
||||||
impl f::Group {
|
impl f::Group {
|
||||||
pub fn render<C: Colours, U: Users+Groups>(self, colours: &C, users: &U) -> TextCell {
|
pub fn render<C: Colours, U: Users+Groups>(self, colours: &C, users: &U, format: UserFormat) -> TextCell {
|
||||||
use users::os::unix::GroupExt;
|
use users::os::unix::GroupExt;
|
||||||
|
|
||||||
let mut style = colours.not_yours();
|
let mut style = colours.not_yours();
|
||||||
@ -26,7 +27,12 @@ impl f::Group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextCell::paint(style, group.name().to_string_lossy().into())
|
let group_name = match format {
|
||||||
|
UserFormat::Name => group.name().to_string_lossy().into(),
|
||||||
|
UserFormat::Numeric => group.gid().to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
TextCell::paint(style, group_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +49,7 @@ pub mod test {
|
|||||||
use super::Colours;
|
use super::Colours;
|
||||||
use crate::fs::fields as f;
|
use crate::fs::fields as f;
|
||||||
use crate::output::cell::TextCell;
|
use crate::output::cell::TextCell;
|
||||||
|
use crate::output::table::UserFormat;
|
||||||
|
|
||||||
use users::{User, Group};
|
use users::{User, Group};
|
||||||
use users::mock::MockUsers;
|
use users::mock::MockUsers;
|
||||||
@ -66,16 +73,21 @@ pub mod test {
|
|||||||
|
|
||||||
let group = f::Group(100);
|
let group = f::Group(100);
|
||||||
let expected = TextCell::paint_str(Fixed(81).normal(), "folk");
|
let expected = TextCell::paint_str(Fixed(81).normal(), "folk");
|
||||||
assert_eq!(expected, group.render(&TestColours, &users))
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name));
|
||||||
|
|
||||||
|
let expected = TextCell::paint_str(Fixed(81).normal(), "100");
|
||||||
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unnamed() {
|
fn unnamed() {
|
||||||
let users = MockUsers::with_current_uid(1000);
|
let users = MockUsers::with_current_uid(1000);
|
||||||
|
|
||||||
let group = f::Group(100);
|
let group = f::Group(100);
|
||||||
let expected = TextCell::paint_str(Fixed(81).normal(), "100");
|
let expected = TextCell::paint_str(Fixed(81).normal(), "100");
|
||||||
assert_eq!(expected, group.render(&TestColours, &users));
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name));
|
||||||
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -86,7 +98,7 @@ pub mod test {
|
|||||||
|
|
||||||
let group = f::Group(100);
|
let group = f::Group(100);
|
||||||
let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
|
let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
|
||||||
assert_eq!(expected, group.render(&TestColours, &users))
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -99,13 +111,13 @@ pub mod test {
|
|||||||
|
|
||||||
let group = f::Group(100);
|
let group = f::Group(100);
|
||||||
let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
|
let expected = TextCell::paint_str(Fixed(80).normal(), "folk");
|
||||||
assert_eq!(expected, group.render(&TestColours, &users))
|
assert_eq!(expected, group.render(&TestColours, &users, UserFormat::Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn overflow() {
|
fn overflow() {
|
||||||
let group = f::Group(2_147_483_648);
|
let group = f::Group(2_147_483_648);
|
||||||
let expected = TextCell::paint_str(Fixed(81).normal(), "2147483648");
|
let expected = TextCell::paint_str(Fixed(81).normal(), "2147483648");
|
||||||
assert_eq!(expected, group.render(&TestColours, &MockUsers::with_current_uid(0)));
|
assert_eq!(expected, group.render(&TestColours, &MockUsers::with_current_uid(0), UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ use users::Users;
|
|||||||
|
|
||||||
use crate::fs::fields as f;
|
use crate::fs::fields as f;
|
||||||
use crate::output::cell::TextCell;
|
use crate::output::cell::TextCell;
|
||||||
|
use crate::output::table::UserFormat;
|
||||||
|
|
||||||
|
|
||||||
impl f::User {
|
impl f::User {
|
||||||
pub fn render<C: Colours, U: Users>(self, colours: &C, users: &U) -> TextCell {
|
pub fn render<C: Colours, U: Users>(self, colours: &C, users: &U, format: UserFormat) -> TextCell {
|
||||||
let user_name = match users.get_user_by_uid(self.0) {
|
let user_name = match (format, users.get_user_by_uid(self.0)) {
|
||||||
Some(user) => user.name().to_string_lossy().into(),
|
(_, None) => self.0.to_string(),
|
||||||
None => self.0.to_string(),
|
(UserFormat::Numeric, _) => self.0.to_string(),
|
||||||
|
(UserFormat::Name, Some(user)) => user.name().to_string_lossy().into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let style = if users.get_current_uid() == self.0 { colours.you() }
|
let style = if users.get_current_uid() == self.0 { colours.you() }
|
||||||
@ -31,6 +33,7 @@ pub mod test {
|
|||||||
use super::Colours;
|
use super::Colours;
|
||||||
use crate::fs::fields as f;
|
use crate::fs::fields as f;
|
||||||
use crate::output::cell::TextCell;
|
use crate::output::cell::TextCell;
|
||||||
|
use crate::output::table::UserFormat;
|
||||||
|
|
||||||
use users::User;
|
use users::User;
|
||||||
use users::mock::MockUsers;
|
use users::mock::MockUsers;
|
||||||
@ -53,7 +56,10 @@ pub mod test {
|
|||||||
|
|
||||||
let user = f::User(1000);
|
let user = f::User(1000);
|
||||||
let expected = TextCell::paint_str(Red.bold(), "enoch");
|
let expected = TextCell::paint_str(Red.bold(), "enoch");
|
||||||
assert_eq!(expected, user.render(&TestColours, &users))
|
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Name));
|
||||||
|
|
||||||
|
let expected = TextCell::paint_str(Red.bold(), "1000");
|
||||||
|
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -62,7 +68,8 @@ pub mod test {
|
|||||||
|
|
||||||
let user = f::User(1000);
|
let user = f::User(1000);
|
||||||
let expected = TextCell::paint_str(Red.bold(), "1000");
|
let expected = TextCell::paint_str(Red.bold(), "1000");
|
||||||
assert_eq!(expected, user.render(&TestColours, &users));
|
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Name));
|
||||||
|
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -72,20 +79,20 @@ pub mod test {
|
|||||||
|
|
||||||
let user = f::User(1000);
|
let user = f::User(1000);
|
||||||
let expected = TextCell::paint_str(Blue.underline(), "enoch");
|
let expected = TextCell::paint_str(Blue.underline(), "enoch");
|
||||||
assert_eq!(expected, user.render(&TestColours, &users));
|
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn different_unnamed() {
|
fn different_unnamed() {
|
||||||
let user = f::User(1000);
|
let user = f::User(1000);
|
||||||
let expected = TextCell::paint_str(Blue.underline(), "1000");
|
let expected = TextCell::paint_str(Blue.underline(), "1000");
|
||||||
assert_eq!(expected, user.render(&TestColours, &MockUsers::with_current_uid(0)));
|
assert_eq!(expected, user.render(&TestColours, &MockUsers::with_current_uid(0), UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn overflow() {
|
fn overflow() {
|
||||||
let user = f::User(2_147_483_648);
|
let user = f::User(2_147_483_648);
|
||||||
let expected = TextCell::paint_str(Blue.underline(), "2147483648");
|
let expected = TextCell::paint_str(Blue.underline(), "2147483648");
|
||||||
assert_eq!(expected, user.render(&TestColours, &MockUsers::with_current_uid(0)));
|
assert_eq!(expected, user.render(&TestColours, &MockUsers::with_current_uid(0), UserFormat::Numeric));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ use crate::theme::Theme;
|
|||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub size_format: SizeFormat,
|
pub size_format: SizeFormat,
|
||||||
pub time_format: TimeFormat,
|
pub time_format: TimeFormat,
|
||||||
|
pub user_format: UserFormat,
|
||||||
pub columns: Columns,
|
pub columns: Columns,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +181,15 @@ pub enum SizeFormat {
|
|||||||
JustBytes,
|
JustBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formatting options for user and group.
|
||||||
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
|
pub enum UserFormat {
|
||||||
|
/// The UID / GID
|
||||||
|
Numeric,
|
||||||
|
/// Show the name
|
||||||
|
Name,
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for SizeFormat {
|
impl Default for SizeFormat {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::DecimalBytes
|
Self::DecimalBytes
|
||||||
@ -311,6 +321,7 @@ pub struct Table<'a> {
|
|||||||
widths: TableWidths,
|
widths: TableWidths,
|
||||||
time_format: TimeFormat,
|
time_format: TimeFormat,
|
||||||
size_format: SizeFormat,
|
size_format: SizeFormat,
|
||||||
|
user_format: UserFormat,
|
||||||
git: Option<&'a GitCache>,
|
git: Option<&'a GitCache>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,6 +344,7 @@ impl<'a, 'f> Table<'a> {
|
|||||||
env,
|
env,
|
||||||
time_format: options.time_format,
|
time_format: options.time_format,
|
||||||
size_format: options.size_format,
|
size_format: options.size_format,
|
||||||
|
user_format: options.user_format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,10 +404,10 @@ impl<'a, 'f> Table<'a> {
|
|||||||
file.blocks().render(self.theme)
|
file.blocks().render(self.theme)
|
||||||
}
|
}
|
||||||
Column::User => {
|
Column::User => {
|
||||||
file.user().render(self.theme, &*self.env.lock_users())
|
file.user().render(self.theme, &*self.env.lock_users(), self.user_format)
|
||||||
}
|
}
|
||||||
Column::Group => {
|
Column::Group => {
|
||||||
file.group().render(self.theme, &*self.env.lock_users())
|
file.group().render(self.theme, &*self.env.lock_users(), self.user_format)
|
||||||
}
|
}
|
||||||
Column::GitStatus => {
|
Column::GitStatus => {
|
||||||
self.git_status(file).render(self.theme)
|
self.git_status(file).render(self.theme)
|
||||||
|
Loading…
Reference in New Issue
Block a user