diff --git a/Cargo.lock b/Cargo.lock index d4b549c..cd545a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,14 +44,12 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "datetime" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0fcb4df22ae812fa2f6d5e3b577247584cc67fce06ad0779168d1dd41cbcce3" +checksum = "44c3f7a77f3e57fedf80e09136f2d8777ebf621207306f6d96d610af048354bc" dependencies = [ - "iso8601", "libc", "locale", - "num-traits", "pad", "redox_syscall", "winapi", @@ -120,15 +118,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "iso8601" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e86914a73535f3f541a765adea0a9fafcf53fa6adb73662c4988fd9233766f" -dependencies = [ - "nom", -] - [[package]] name = "jobserver" version = "0.1.21" @@ -198,37 +187,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -[[package]] -name = "memchr" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" - [[package]] name = "natord" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c" -[[package]] -name = "nom" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -dependencies = [ - "memchr", - "version_check", -] - -[[package]] -name = "num-traits" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.13.0" @@ -377,12 +341,6 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" - [[package]] name = "winapi" version = "0.3.9" @@ -407,9 +365,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "zoneinfo_compiled" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7033eef97c288bfa49e3ebf958245a41016f1673a5317196efad03eb656a7648" +checksum = "64fbebe65e899530f43bd760b23fda8f141118f4db49952b02998cbd0907a5de" dependencies = [ "byteorder", "datetime", diff --git a/Cargo.toml b/Cargo.toml index 1817788..949fd84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,6 @@ name = "exa" [dependencies] ansi_term = "0.12" -datetime = "0.5" glob = "0.3" lazy_static = "1.3" libc = "0.2" @@ -36,29 +35,38 @@ scoped_threadpool = "0.1" term_grid = "0.1" term_size = "0.3" unicode-width = "0.1" -zoneinfo_compiled = "0.5" +zoneinfo_compiled = "0.5.1" [target.'cfg(unix)'.dependencies] users = "0.11" +[dependencies.datetime] +version = "0.5.2" +default-features = false +features = ["format"] + [dependencies.git2] version = "0.13" optional = true default-features = false -[build-dependencies] -datetime = "0.5" +[build-dependencies.datetime] +version = "0.5.2" +default-features = false [features] default = [ "git" ] git = [ "git2" ] vendored-openssl = ["git2/vendored-openssl"] -[profile.release] -opt-level = 3 + +# make dev builds faster by excluding debug symbols +[profile.dev] debug = false + +# use LTO for smaller binaries (that take longer to build) +[profile.release] lto = true -panic = "abort" [package.metadata.deb] diff --git a/Justfile b/Justfile index 32d4da5..3c62a73 100644 --- a/Justfile +++ b/Justfile @@ -1,74 +1,104 @@ -all: build test xtests -all-release: build-release test-release xtests-release +all: build test +all-release: build-release test-release -# compiles the exa binary +#----------# +# building # +#----------# + +# compile the exa binary @build: cargo build -# compiles the exa binary (in release mode) +# compile the exa binary (in release mode) @build-release: cargo build --release --verbose -# compiles the exa binary with every combination of feature flags -@build-features: - cargo hack build --feature-powerset +# produce an HTML chart of compilation timings +@build-time: + cargo +nightly clean + cargo +nightly build -Z timings + +# check that the exa binary can compile +@check: + cargo check -# runs unit tests +#---------------# +# running tests # +#---------------# + +# run unit tests @test: - cargo test --all -- --quiet + cargo test --workspace -- --quiet -# runs unit tests (in release mode) +# run unit tests (in release mode) @test-release: - cargo test --release --all --verbose - -# runs unit tests with every combination of feature flags -@test-features: - cargo hack test --feature-powerset -- --quiet + cargo test --workspace --release --verbose -# runs extended tests +#------------------------# +# running extended tests # +#------------------------# + +# run extended tests @xtests: xtests/run.sh -# runs extended tests (using the release mode exa) +# run extended tests (using the release mode exa) @xtests-release: xtests/run.sh --release +# display the number of extended tests that get run +@count-xtests: + grep -F '[[cmd]]' -R xtests | wc -l -# lints the code + +#-----------------------# +# code quality and misc # +#-----------------------# + +# lint the code @clippy: touch src/main.rs cargo clippy -# updates dependency versions, and checks for outdated ones +# update dependency versions, and checks for outdated ones @update-deps: cargo update command -v cargo-outdated >/dev/null || (echo "cargo-outdated not installed" && exit 1) cargo outdated -# lists unused dependencies +# list unused dependencies @unused-deps: command -v cargo-udeps >/dev/null || (echo "cargo-udeps not installed" && exit 1) cargo +nightly udeps -# prints versions of the necessary build tools +# check that every combination of feature flags is successful +@check-features: + command -v cargo-hack >/dev/null || (echo "cargo-hack not installed" && exit 1) + cargo hack check --feature-powerset + +# print versions of the necessary build tools @versions: rustc --version cargo --version -# builds the man pages +#---------------# +# documentation # +#---------------# + +# build the man pages @man: mkdir -p "${CARGO_TARGET_DIR:-target}/man" pandoc --standalone -f markdown -t man man/exa.1.md > "${CARGO_TARGET_DIR:-target}/man/exa.1" pandoc --standalone -f markdown -t man man/exa_colors.5.md > "${CARGO_TARGET_DIR:-target}/man/exa_colors.5" -# builds and previews the main man page (exa.1) +# build and preview the main man page (exa.1) @man-1-preview: man man "${CARGO_TARGET_DIR:-target}/man/exa.1" -# builds and previews the colour configuration man page (exa_colors.5) +# build and preview the colour configuration man page (exa_colors.5) @man-5-preview: man man "${CARGO_TARGET_DIR:-target}/man/exa_colors.5" diff --git a/README.md b/README.md index fac14ba..1939928 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,12 @@ On Arch, install the [`exa`](https://www.archlinux.org/packages/community/x86_64 $ pacman -S exa +### Android / Termux + +On Android / Termux, install the [`exa`](https://github.com/termux/termux-packages/tree/master/packages/exa) package. + + $ pkg install exa + ### Debian On Debian, install the [`exa`](https://packages.debian.org/unstable/exa) package. @@ -164,7 +170,7 @@ On openSUSE, install the [`exa`](https://software.opensuse.org/package/exa) pack On Ubuntu 20.10 (Groovy Gorilla) and later, install the [`exa`](https://packages.ubuntu.com/groovy/exa) package. - $ apt install exa + $ sudo apt install exa ### Void Linux diff --git a/completions/completions.fish b/completions/completions.fish index e868e8e..d261196 100755 --- a/completions/completions.fish +++ b/completions/completions.fish @@ -66,6 +66,7 @@ complete -c exa -s 't' -l 'time' -x -d "Which timestamp field to list" -a " created\t'Display created time' " complete -c exa -s 'm' -l 'modified' -d "Use the modified timestamp field" +complete -c exa -s 'n' -l 'numeric' -d "List numeric user and group IDs." 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 'created' -d "Use the created timestamp field" diff --git a/completions/completions.zsh b/completions/completions.zsh index d51332e..f339289 100644 --- a/completions/completions.zsh +++ b/completions/completions.zsh @@ -40,6 +40,7 @@ __exa() { {-H,--links}"[List each file's number of hard links]" \ {-i,--inode}"[List each file's inode number]" \ {-m,--modified}"[Use the modified timestamp field]" \ + {-n,--numeric}"[List numeric user and group IDs.]" \ {-S,--blocks}"[List each file's number of filesystem blocks]" \ {-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)" \ diff --git a/man/exa.1.md b/man/exa.1.md index 3b89d0a..6e00a47 100644 --- a/man/exa.1.md +++ b/man/exa.1.md @@ -143,6 +143,9 @@ These options are available when running with `--long` (`-l`): `-m`, `--modified` : Use the modified timestamp field. +`-n`, `--numeric` +: List numeric user and group IDs. + `-S`, `--blocks` : List each file’s number of file system blocks. diff --git a/src/fs/feature/git.rs b/src/fs/feature/git.rs index 9414c57..1cba373 100644 --- a/src/fs/feature/git.rs +++ b/src/fs/feature/git.rs @@ -211,7 +211,7 @@ fn repo_to_statuses(repo: &git2::Repository, workdir: &Path) -> Git { } } Err(e) => { - error!("Error looking up Git statuses: {:?}", e) + error!("Error looking up Git statuses: {:?}", e); } } diff --git a/src/main.rs b/src/main.rs index ac69533..84f36b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -93,7 +93,7 @@ fn main() { } OptionsResult::InvalidOptions(error) => { - eprintln!("{}", error); + eprintln!("exa: {}", error); if let Some(s) = error.suggestion() { eprintln!("{}", s); diff --git a/src/options/flags.rs b/src/options/flags.rs index 16ab04a..1761d66 100644 --- a/src/options/flags.rs +++ b/src/options/flags.rs @@ -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 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 NUMERIC: Arg = Arg { short: Some(b'n'), long: "numeric", 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 INODE: Arg = Arg { short: Some(b'i'), long: "inode", takes_value: TakesValue::Forbidden }; @@ -75,7 +76,7 @@ pub static ALL_ARGS: Args = Args(&[ &ALL, &LIST_DIRS, &LEVEL, &REVERSE, &SORT, &DIRS_FIRST, &IGNORE_GLOB, &GIT_IGNORE, &ONLY_DIRS, - &BINARY, &BYTES, &GROUP, &HEADER, &ICONS, &INODE, &LINKS, &MODIFIED, &CHANGED, + &BINARY, &BYTES, &GROUP, &NUMERIC, &HEADER, &ICONS, &INODE, &LINKS, &MODIFIED, &CHANGED, &BLOCKS, &TIME, &ACCESSED, &CREATED, &TIME_STYLE, &NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME, &NO_ICONS, diff --git a/src/options/help.rs b/src/options/help.rs index dacf106..8f47a73 100644 --- a/src/options/help.rs +++ b/src/options/help.rs @@ -48,6 +48,7 @@ LONG VIEW OPTIONS -H, --links list each file's number of hard links -i, --inode list each file's inode number -m, --modified use the modified timestamp field + -n, --numeric list numeric user and group IDs -S, --blocks show number of file system blocks -t, --time FIELD which timestamp field to list (modified, accessed, created) -u, --accessed use the accessed timestamp field @@ -111,7 +112,7 @@ impl fmt::Display for HelpString { write!(f, "\n{}", EXTENDED_HELP)?; } - Ok(()) + writeln!(f) } } diff --git a/src/options/view.rs b/src/options/view.rs index 9c2ed13..6f13c87 100644 --- a/src/options/view.rs +++ b/src/options/view.rs @@ -4,7 +4,7 @@ use crate::options::parser::MatchedFlags; use crate::output::{View, Mode, TerminalWidth, grid, details}; use crate::output::grid_details::{self, RowThreshold}; 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; @@ -85,7 +85,7 @@ impl Mode { // user about flags that won’t have any effect. if matches.is_strict() { for option in &[ &flags::BINARY, &flags::BYTES, &flags::INODE, &flags::LINKS, - &flags::HEADER, &flags::BLOCKS, &flags::TIME, &flags::GROUP ] { + &flags::HEADER, &flags::BLOCKS, &flags::TIME, &flags::GROUP, &flags::NUMERIC ] { if matches.has(option)? { return Err(OptionsError::Useless(*option, false, &flags::LONG)); } @@ -183,8 +183,9 @@ impl TableOptions { fn deduce(matches: &MatchedFlags<'_>, vars: &V) -> Result { let time_format = TimeFormat::deduce(matches, vars)?; let size_format = SizeFormat::deduce(matches)?; + let user_format = UserFormat::deduce(matches)?; let columns = Columns::deduce(matches)?; - Ok(Self { time_format, size_format, columns }) + Ok(Self { time_format, size_format, columns , user_format}) } } @@ -266,6 +267,14 @@ impl TimeFormat { } +impl UserFormat { + fn deduce(matches: &MatchedFlags<'_>) -> Result { + let flag = matches.has(&flags::NUMERIC)?; + Ok(if flag { Self::Numeric } else { Self::Name }) + } +} + + impl TimeTypes { /// Determine which of a file’s time fields should be displayed for it @@ -345,7 +354,8 @@ mod test { &flags::CREATED, &flags::ACCESSED, &flags::HEADER, &flags::GROUP, &flags::INODE, &flags::GIT, &flags::LINKS, &flags::BLOCKS, &flags::LONG, &flags::LEVEL, - &flags::GRID, &flags::ACROSS, &flags::ONE_LINE, &flags::TREE ]; + &flags::GRID, &flags::ACROSS, &flags::ONE_LINE, &flags::TREE, + &flags::NUMERIC ]; macro_rules! test { @@ -547,24 +557,26 @@ mod test { test!(long_across: Mode <- ["--long", "--across"], None; Last => like Ok(Mode::Details(_))); // Options that do nothing without --long - test!(just_header: Mode <- ["--header"], None; Last => like Ok(Mode::Grid(_))); - test!(just_group: Mode <- ["--group"], None; Last => like Ok(Mode::Grid(_))); - test!(just_inode: Mode <- ["--inode"], None; Last => like Ok(Mode::Grid(_))); - test!(just_links: Mode <- ["--links"], None; Last => like Ok(Mode::Grid(_))); - test!(just_blocks: Mode <- ["--blocks"], None; Last => like Ok(Mode::Grid(_))); - test!(just_binary: Mode <- ["--binary"], None; Last => like Ok(Mode::Grid(_))); - test!(just_bytes: Mode <- ["--bytes"], None; Last => like Ok(Mode::Grid(_))); + test!(just_header: Mode <- ["--header"], None; Last => like Ok(Mode::Grid(_))); + test!(just_group: Mode <- ["--group"], None; Last => like Ok(Mode::Grid(_))); + test!(just_inode: Mode <- ["--inode"], None; Last => like Ok(Mode::Grid(_))); + test!(just_links: Mode <- ["--links"], None; Last => like Ok(Mode::Grid(_))); + test!(just_blocks: Mode <- ["--blocks"], None; Last => like Ok(Mode::Grid(_))); + test!(just_binary: Mode <- ["--binary"], None; Last => like Ok(Mode::Grid(_))); + test!(just_bytes: Mode <- ["--bytes"], None; Last => like Ok(Mode::Grid(_))); + test!(just_numeric: Mode <- ["--numeric"], None; Last => like Ok(Mode::Grid(_))); #[cfg(feature = "git")] test!(just_git: Mode <- ["--git"], None; Last => like Ok(Mode::Grid(_))); - test!(just_header_2: Mode <- ["--header"], None; Complain => err OptionsError::Useless(&flags::HEADER, false, &flags::LONG)); - test!(just_group_2: Mode <- ["--group"], None; Complain => err OptionsError::Useless(&flags::GROUP, false, &flags::LONG)); - test!(just_inode_2: Mode <- ["--inode"], None; Complain => err OptionsError::Useless(&flags::INODE, false, &flags::LONG)); - test!(just_links_2: Mode <- ["--links"], None; Complain => err OptionsError::Useless(&flags::LINKS, false, &flags::LONG)); - test!(just_blocks_2: Mode <- ["--blocks"], None; Complain => err OptionsError::Useless(&flags::BLOCKS, false, &flags::LONG)); - test!(just_binary_2: Mode <- ["--binary"], None; Complain => err OptionsError::Useless(&flags::BINARY, false, &flags::LONG)); - test!(just_bytes_2: Mode <- ["--bytes"], None; Complain => err OptionsError::Useless(&flags::BYTES, false, &flags::LONG)); + test!(just_header_2: Mode <- ["--header"], None; Complain => err OptionsError::Useless(&flags::HEADER, false, &flags::LONG)); + test!(just_group_2: Mode <- ["--group"], None; Complain => err OptionsError::Useless(&flags::GROUP, false, &flags::LONG)); + test!(just_inode_2: Mode <- ["--inode"], None; Complain => err OptionsError::Useless(&flags::INODE, false, &flags::LONG)); + test!(just_links_2: Mode <- ["--links"], None; Complain => err OptionsError::Useless(&flags::LINKS, false, &flags::LONG)); + test!(just_blocks_2: Mode <- ["--blocks"], None; Complain => err OptionsError::Useless(&flags::BLOCKS, false, &flags::LONG)); + test!(just_binary_2: Mode <- ["--binary"], None; Complain => err OptionsError::Useless(&flags::BINARY, false, &flags::LONG)); + test!(just_bytes_2: Mode <- ["--bytes"], None; Complain => err OptionsError::Useless(&flags::BYTES, false, &flags::LONG)); + test!(just_numeric2: Mode <- ["--numeric"], None; Complain => err OptionsError::Useless(&flags::NUMERIC, false, &flags::LONG)); #[cfg(feature = "git")] test!(just_git_2: Mode <- ["--git"], None; Complain => err OptionsError::Useless(&flags::GIT, false, &flags::LONG)); diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs index ba157c3..df8e53c 100644 --- a/src/output/grid_details.rs +++ b/src/output/grid_details.rs @@ -157,7 +157,11 @@ impl<'a> Render<'a> { .map(|file| self.file_style.for_file(file, self.theme).paint().promote()) .collect::>(); - let mut last_working_table = self.make_grid(1, options, &file_names, rows.clone(), &drender); + let mut last_working_grid = self.make_grid(1, options, &file_names, rows.clone(), &drender); + + if file_names.len() == 1 { + return Some((last_working_grid, 1)); + } // If we can’t fit everything in a grid 100 columns wide, then // something has gone seriously awry @@ -166,23 +170,26 @@ impl<'a> Render<'a> { let the_grid_fits = { let d = grid.fit_into_columns(column_count); - d.is_complete() && d.width() <= self.console_width + d.width() <= self.console_width }; if the_grid_fits { - last_working_table = grid; - } - else { + if column_count == file_names.len() { + return Some((grid, column_count)); + } else { + last_working_grid = grid; + } + } else { // If we’ve figured out how many columns can fit in the user’s // terminal, and it turns out there aren’t enough rows to // make it worthwhile, then just resort to the lines view. if let RowThreshold::MinimumRows(thresh) = self.row_threshold { - if last_working_table.fit_into_columns(column_count - 1).row_count() < thresh { + if last_working_grid.fit_into_columns(column_count - 1).row_count() < thresh { return None; } } - return Some((last_working_table, column_count - 1)); + return Some((last_working_grid, column_count - 1)); } } diff --git a/src/output/render/groups.rs b/src/output/render/groups.rs index 1a1e812..ce33f9f 100644 --- a/src/output/render/groups.rs +++ b/src/output/render/groups.rs @@ -3,10 +3,11 @@ use users::{Users, Groups}; use crate::fs::fields as f; use crate::output::cell::TextCell; +use crate::output::table::UserFormat; impl f::Group { - pub fn render(self, colours: &C, users: &U) -> TextCell { + pub fn render(self, colours: &C, users: &U, format: UserFormat) -> TextCell { use users::os::unix::GroupExt; 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 crate::fs::fields as f; use crate::output::cell::TextCell; + use crate::output::table::UserFormat; use users::{User, Group}; use users::mock::MockUsers; @@ -66,16 +73,21 @@ pub mod test { let group = f::Group(100); 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] fn unnamed() { let users = MockUsers::with_current_uid(1000); let group = f::Group(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] @@ -86,7 +98,7 @@ pub mod test { let group = f::Group(100); 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] @@ -99,13 +111,13 @@ pub mod test { let group = f::Group(100); 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] fn overflow() { let group = f::Group(2_147_483_648); 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)); } } diff --git a/src/output/render/size.rs b/src/output/render/size.rs index 4427a51..7f1acb7 100644 --- a/src/output/render/size.rs +++ b/src/output/render/size.rs @@ -41,9 +41,9 @@ impl f::Size { }; let symbol = prefix.symbol(); - let number = if n < 10_f64 { numerics.format_float(n, 1) } - else { numerics.format_int(n as isize) }; - + let decimal_to_diplay = if n < 10_f64 { 1 } else { 0 }; + let number = numerics.format_float(n, decimal_to_diplay); + // The numbers and symbols are guaranteed to be written in ASCII, so // we can skip the display width calculation. let width = DisplayWidth::from(number.len() + symbol.len()); diff --git a/src/output/render/users.rs b/src/output/render/users.rs index adda168..6a99a98 100644 --- a/src/output/render/users.rs +++ b/src/output/render/users.rs @@ -3,13 +3,15 @@ use users::Users; use crate::fs::fields as f; use crate::output::cell::TextCell; +use crate::output::table::UserFormat; impl f::User { - pub fn render(self, colours: &C, users: &U) -> TextCell { - let user_name = match users.get_user_by_uid(self.0) { - Some(user) => user.name().to_string_lossy().into(), - None => self.0.to_string(), + pub fn render(self, colours: &C, users: &U, format: UserFormat) -> TextCell { + let user_name = match (format, users.get_user_by_uid(self.0)) { + (_, 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() } @@ -31,6 +33,7 @@ pub mod test { use super::Colours; use crate::fs::fields as f; use crate::output::cell::TextCell; + use crate::output::table::UserFormat; use users::User; use users::mock::MockUsers; @@ -53,7 +56,10 @@ pub mod test { let user = f::User(1000); 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] @@ -62,7 +68,8 @@ pub mod test { let user = f::User(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] @@ -72,20 +79,20 @@ pub mod test { let user = f::User(1000); 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] fn different_unnamed() { let user = f::User(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] fn overflow() { let user = f::User(2_147_483_648); 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)); } } diff --git a/src/output/table.rs b/src/output/table.rs index 4bc1162..2fa308f 100644 --- a/src/output/table.rs +++ b/src/output/table.rs @@ -25,6 +25,7 @@ use crate::theme::Theme; pub struct Options { pub size_format: SizeFormat, pub time_format: TimeFormat, + pub user_format: UserFormat, pub columns: Columns, } @@ -213,6 +214,15 @@ pub enum SizeFormat { 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 { fn default() -> Self { Self::DecimalBytes @@ -329,9 +339,20 @@ impl Environment { #[cfg(unix)] fn determine_time_zone() -> TZResult { if let Ok(file) = env::var("TZ") { - TimeZone::from_file(format!("/usr/share/zoneinfo/{}", file)) - } - else { + TimeZone::from_file({ + if file.starts_with("/") { + file + } else { + format!("/usr/share/zoneinfo/{}", { + if file.starts_with(":") { + file.replacen(":", "", 1) + } else { + file + } + }) + } + }) + } else { TimeZone::from_file("/etc/localtime") } } @@ -373,6 +394,7 @@ pub struct Table<'a> { widths: TableWidths, time_format: TimeFormat, size_format: SizeFormat, + user_format: UserFormat, git: Option<&'a GitCache>, } @@ -395,6 +417,7 @@ impl<'a, 'f> Table<'a> { env, time_format: options.time_format, size_format: options.size_format, + user_format: options.user_format, } } @@ -462,11 +485,11 @@ impl<'a, 'f> Table<'a> { } #[cfg(unix)] Column::User => { - file.user().render(self.theme, &*self.env.lock_users()) + file.user().render(self.theme, &*self.env.lock_users(), self.user_format) } #[cfg(unix)] 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 => { self.git_status(file).render(self.theme) diff --git a/xtests/grid-details-view.toml b/xtests/grid-details-view.toml index c307e0c..a76ba15 100644 --- a/xtests/grid-details-view.toml +++ b/xtests/grid-details-view.toml @@ -76,3 +76,24 @@ stdout = { file = "outputs/files_paths_long_grid_3col.ansitxt" } stderr = { empty = true } status = 0 tags = [ 'env', 'long', 'grid' ] + + +# check if exa is using the minimum number of columns with headers + +[[cmd]] +name = "‘COLUMN=200 exa -lGh’ with one file don’t produce extra columns even if there place for more" +shell = "exa -lGh /testcases/files/10_bytes" +environment = { COLUMNS = "200" } +stdout = { file = "outputs/files_paths_long_grid_header_1file.ansitxt" } +stderr = { empty = true } +status = 0 +tags = [ 'env', 'long', 'grid' ] + +[[cmd]] +name = "‘COLUMN=200 exa -lGh’ with several files don’t produce extra columns even if there place for more" +shell = "exa -lGh /testcases/files/10_{bytes,KiB}" +environment = { COLUMNS = "200" } +stdout = { file = "outputs/files_paths_long_grid_header_2files.ansitxt" } +stderr = { empty = true } +status = 0 +tags = [ 'env', 'long', 'grid' ] diff --git a/xtests/help.toml b/xtests/help.toml index 39bba28..84b9609 100644 --- a/xtests/help.toml +++ b/xtests/help.toml @@ -4,4 +4,4 @@ shell = "exa --help" stdout = { file = "outputs/help.ansitxt" } stderr = { empty = true } status = 0 -tags = [ 'help '] +tags = [ 'help' ] diff --git a/xtests/outputs/exts_oneline_icons.ansitxt b/xtests/outputs/exts_oneline_icons.ansitxt index fa484ef..80d2e3a 100644 --- a/xtests/outputs/exts_oneline_icons.ansitxt +++ b/xtests/outputs/exts_oneline_icons.ansitxt @@ -1,26 +1,26 @@ - #SAVEFILE# - backup~ - compiled.class + #SAVEFILE# + backup~ + compiled.class  compiled.coffee - compiled.js - compiled.o - compressed.deb - compressed.tar.gz - compressed.tar.xz - compressed.tgz - compressed.txz - COMPRESSED.ZIP - crypto.asc - crypto.signature - document.pdf - DOCUMENT.XLSX - file.tmp - IMAGE.PNG - image.svg - lossless.flac - lossless.wav - Makefile - music.mp3 - MUSIC.OGG - VIDEO.AVI - video.wmv + compiled.js + compiled.o + compressed.deb + compressed.tar.gz + compressed.tar.xz + compressed.tgz + compressed.txz + COMPRESSED.ZIP + crypto.asc + crypto.signature + document.pdf + DOCUMENT.XLSX + file.tmp + IMAGE.PNG + image.svg + lossless.flac + lossless.wav + Makefile + music.mp3 + MUSIC.OGG + VIDEO.AVI + video.wmv diff --git a/xtests/outputs/files_long.ansitxt b/xtests/outputs/files_long.ansitxt index d20ddfa..c8a41cb 100644 --- a/xtests/outputs/files_long.ansitxt +++ b/xtests/outputs/files_long.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_colourscale.ansitxt b/xtests/outputs/files_long_colourscale.ansitxt index 4bb9a86..b76c62a 100644 --- a/xtests/outputs/files_long_colourscale.ansitxt +++ b/xtests/outputs/files_long_colourscale.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_grid_1col.ansitxt b/xtests/outputs/files_long_grid_1col.ansitxt index d20ddfa..c8a41cb 100644 --- a/xtests/outputs/files_long_grid_1col.ansitxt +++ b/xtests/outputs/files_long_grid_1col.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_grid_2col.ansitxt b/xtests/outputs/files_long_grid_2col.ansitxt index 9e8c79e..6751bb2 100644 --- a/xtests/outputs/files_long_grid_2col.ansitxt +++ b/xtests/outputs/files_long_grid_2col.ansitxt @@ -10,11 +10,11 @@ .rw-r--r-- 4 cassowary  1 Jan 12:34 4_bytes .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 4.1k cassowary  1 Jan 12:34 4_KiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 4.2M cassowary  1 Jan 12:34 4_MiB .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 5.1k cassowary  1 Jan 12:34 5_KiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 5.2M cassowary  1 Jan 12:34 5_MiB .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 6 cassowary  1 Jan 12:34 6_bytes .rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 6 cassowary  1 Jan 12:34 6_bytes .rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 6.1k cassowary  1 Jan 12:34 6_KiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 6.3M cassowary  1 Jan 12:34 6_MiB .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 7 cassowary  1 Jan 12:34 7_bytes .rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 7 cassowary  1 Jan 12:34 7_bytes .rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB .rw-r--r-- 7.2k cassowary  1 Jan 12:34 7_KiB diff --git a/xtests/outputs/files_long_grid_3col.ansitxt b/xtests/outputs/files_long_grid_3col.ansitxt index 0f015a1..1f22716 100644 --- a/xtests/outputs/files_long_grid_3col.ansitxt +++ b/xtests/outputs/files_long_grid_3col.ansitxt @@ -4,10 +4,10 @@ .rw-r--r-- 2 cassowary  1 Jan 12:34 2_bytes .rw-r--r-- 6.1k cassowary  1 Jan 12:34 6_KiB .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 2.0k cassowary  1 Jan 12:34 2_KiB .rw-r--r-- 6.3M cassowary  1 Jan 12:34 6_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 2.1M cassowary  1 Jan 12:34 2_MiB .rw-r--r-- 7 cassowary  1 Jan 12:34 7_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 3 cassowary  1 Jan 12:34 3_bytes .rw-r--r-- 7.2k cassowary  1 Jan 12:34 7_KiB .rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 3 cassowary  1 Jan 12:34 3_bytes .rw-r--r-- 7.2k cassowary  1 Jan 12:34 7_KiB .rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 3.1k cassowary  1 Jan 12:34 3_KiB .rw-r--r-- 7.3M cassowary  1 Jan 12:34 7_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 3.1M cassowary  1 Jan 12:34 3_MiB .rw-r--r-- 8 cassowary  1 Jan 12:34 8_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 4 cassowary  1 Jan 12:34 4_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 8_KiB .rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 4 cassowary  1 Jan 12:34 4_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 8_KiB .rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 4.1k cassowary  1 Jan 12:34 4_KiB .rw-r--r-- 8.4M cassowary  1 Jan 12:34 8_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 4.2M cassowary  1 Jan 12:34 4_MiB .rw-r--r-- 9 cassowary  1 Jan 12:34 9_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 9_KiB .rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 9_KiB .rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_grid_4col.ansitxt b/xtests/outputs/files_long_grid_4col.ansitxt index 1275dd4..9bab271 100644 --- a/xtests/outputs/files_long_grid_4col.ansitxt +++ b/xtests/outputs/files_long_grid_4col.ansitxt @@ -1,10 +1,10 @@ .rw-r--r-- 1 cassowary  1 Jan 12:34 1_bytes .rw-r--r-- 4.1k cassowary  1 Jan 12:34 4_KiB .rw-r--r-- 7.3M cassowary  1 Jan 12:34 7_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 1.0k cassowary  1 Jan 12:34 1_KiB .rw-r--r-- 4.2M cassowary  1 Jan 12:34 4_MiB .rw-r--r-- 8 cassowary  1 Jan 12:34 8_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 1.0M cassowary  1 Jan 12:34 1_MiB .rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 8_KiB .rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 1.0M cassowary  1 Jan 12:34 1_MiB .rw-r--r-- 5 cassowary  1 Jan 12:34 5_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 8_KiB .rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 2 cassowary  1 Jan 12:34 2_bytes .rw-r--r-- 5.1k cassowary  1 Jan 12:34 5_KiB .rw-r--r-- 8.4M cassowary  1 Jan 12:34 8_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 2.0k cassowary  1 Jan 12:34 2_KiB .rw-r--r-- 5.2M cassowary  1 Jan 12:34 5_MiB .rw-r--r-- 9 cassowary  1 Jan 12:34 9_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 2.1M cassowary  1 Jan 12:34 2_MiB .rw-r--r-- 6 cassowary  1 Jan 12:34 6_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 9_KiB .rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 2.1M cassowary  1 Jan 12:34 2_MiB .rw-r--r-- 6 cassowary  1 Jan 12:34 6_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 9_KiB .rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 3 cassowary  1 Jan 12:34 3_bytes .rw-r--r-- 6.1k cassowary  1 Jan 12:34 6_KiB .rw-r--r-- 9.4M cassowary  1 Jan 12:34 9_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 3.1k cassowary  1 Jan 12:34 3_KiB .rw-r--r-- 6.3M cassowary  1 Jan 12:34 6_MiB .rw-r--r-- 10 cassowary  1 Jan 12:34 10_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 3.1M cassowary  1 Jan 12:34 3_MiB .rw-r--r-- 7 cassowary  1 Jan 12:34 7_bytes .rw-r--r-- 10k cassowary  1 Jan 12:34 10_KiB .rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 3.1M cassowary  1 Jan 12:34 3_MiB .rw-r--r-- 7 cassowary  1 Jan 12:34 7_bytes .rw-r--r-- 10k cassowary  1 Jan 12:34 10_KiB .rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB .rw-r--r-- 4 cassowary  1 Jan 12:34 4_bytes .rw-r--r-- 7.2k cassowary  1 Jan 12:34 7_KiB .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB diff --git a/xtests/outputs/files_long_grid_icons.ansitxt b/xtests/outputs/files_long_grid_icons.ansitxt index 5807ff1..06159ae 100644 --- a/xtests/outputs/files_long_grid_icons.ansitxt +++ b/xtests/outputs/files_long_grid_icons.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34  10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34  11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34  11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34  11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34  11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34  12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34  12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34  12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34  12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34  13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34  13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34  13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34  13_MiB diff --git a/xtests/outputs/files_long_header.ansitxt b/xtests/outputs/files_long_header.ansitxt index c0d57a5..65e981d 100644 --- a/xtests/outputs/files_long_header.ansitxt +++ b/xtests/outputs/files_long_header.ansitxt @@ -31,10 +31,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_icons.ansitxt b/xtests/outputs/files_long_icons.ansitxt index 5807ff1..06159ae 100644 --- a/xtests/outputs/files_long_icons.ansitxt +++ b/xtests/outputs/files_long_icons.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34  10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34  11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34  11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34  11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34  11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34  12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34  12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34  12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34  12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34  13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34  13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34  13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34  13_MiB diff --git a/xtests/outputs/files_long_monochrome.ansitxt b/xtests/outputs/files_long_monochrome.ansitxt index 2339466..18e8375 100644 --- a/xtests/outputs/files_long_monochrome.ansitxt +++ b/xtests/outputs/files_long_monochrome.ansitxt @@ -30,10 +30,10 @@ .rw-r--r-- 10M cassowary 1 Jan 12:34 10_MiB .rw-r--r-- 11 cassowary 1 Jan 12:34 11_bytes .rw-r--r-- 11k cassowary 1 Jan 12:34 11_KiB -.rw-r--r-- 11M cassowary 1 Jan 12:34 11_MiB +.rw-r--r-- 12M cassowary 1 Jan 12:34 11_MiB .rw-r--r-- 12 cassowary 1 Jan 12:34 12_bytes .rw-r--r-- 12k cassowary 1 Jan 12:34 12_KiB -.rw-r--r-- 12M cassowary 1 Jan 12:34 12_MiB +.rw-r--r-- 13M cassowary 1 Jan 12:34 12_MiB .rw-r--r-- 13 cassowary 1 Jan 12:34 13_bytes .rw-r--r-- 13k cassowary 1 Jan 12:34 13_KiB -.rw-r--r-- 13M cassowary 1 Jan 12:34 13_MiB +.rw-r--r-- 14M cassowary 1 Jan 12:34 13_MiB diff --git a/xtests/outputs/files_long_tree_icons.ansitxt b/xtests/outputs/files_long_tree_icons.ansitxt index 3c7da81..ac52ef1 100644 --- a/xtests/outputs/files_long_tree_icons.ansitxt +++ b/xtests/outputs/files_long_tree_icons.ansitxt @@ -1,4 +1,4 @@ -drwxrwxr-x - vagrant  1 Jan 12:34  /testcases/files +drwxrwxr-x - vagrant  1 Jan 12:34  /testcases/files .rw-r--r-- 1 cassowary  1 Jan 12:34 ├──  1_bytes .rw-r--r-- 1.0k cassowary  1 Jan 12:34 ├──  1_KiB .rw-r--r-- 1.0M cassowary  1 Jan 12:34 ├──  1_MiB @@ -31,10 +31,10 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 ├──  10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 ├──  11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 ├──  11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 ├──  11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 ├──  11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 ├──  12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 ├──  12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 ├──  12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 ├──  12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 ├──  13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 ├──  13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 └──  13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 └──  13_MiB diff --git a/xtests/outputs/files_paths_long_grid_1col.ansitxt b/xtests/outputs/files_paths_long_grid_1col.ansitxt index d35b5b0..850945f 100644 --- a/xtests/outputs/files_paths_long_grid_1col.ansitxt +++ b/xtests/outputs/files_paths_long_grid_1col.ansitxt @@ -3,13 +3,13 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 /testcases/files/10_MiB .rw-r--r-- 11 cassowary  1 Jan 12:34 /testcases/files/11_bytes .rw-r--r-- 11k cassowary  1 Jan 12:34 /testcases/files/11_KiB -.rw-r--r-- 11M cassowary  1 Jan 12:34 /testcases/files/11_MiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/11_MiB .rw-r--r-- 12 cassowary  1 Jan 12:34 /testcases/files/12_bytes .rw-r--r-- 12k cassowary  1 Jan 12:34 /testcases/files/12_KiB -.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/12_MiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/12_MiB .rw-r--r-- 13 cassowary  1 Jan 12:34 /testcases/files/13_bytes .rw-r--r-- 13k cassowary  1 Jan 12:34 /testcases/files/13_KiB -.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/13_MiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 /testcases/files/13_MiB .rw-r--r-- 1 cassowary  1 Jan 12:34 /testcases/files/1_bytes .rw-r--r-- 1.0k cassowary  1 Jan 12:34 /testcases/files/1_KiB .rw-r--r-- 1.0M cassowary  1 Jan 12:34 /testcases/files/1_MiB diff --git a/xtests/outputs/files_paths_long_grid_2col.ansitxt b/xtests/outputs/files_paths_long_grid_2col.ansitxt index 4f076a8..408c311 100644 --- a/xtests/outputs/files_paths_long_grid_2col.ansitxt +++ b/xtests/outputs/files_paths_long_grid_2col.ansitxt @@ -3,13 +3,13 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 /testcases/files/10_MiB .rw-r--r-- 4.1k cassowary  1 Jan 12:34 /testcases/files/4_KiB .rw-r--r-- 11 cassowary  1 Jan 12:34 /testcases/files/11_bytes .rw-r--r-- 4.2M cassowary  1 Jan 12:34 /testcases/files/4_MiB .rw-r--r-- 11k cassowary  1 Jan 12:34 /testcases/files/11_KiB .rw-r--r-- 5 cassowary  1 Jan 12:34 /testcases/files/5_bytes -.rw-r--r-- 11M cassowary  1 Jan 12:34 /testcases/files/11_MiB .rw-r--r-- 5.1k cassowary  1 Jan 12:34 /testcases/files/5_KiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/11_MiB .rw-r--r-- 5.1k cassowary  1 Jan 12:34 /testcases/files/5_KiB .rw-r--r-- 12 cassowary  1 Jan 12:34 /testcases/files/12_bytes .rw-r--r-- 5.2M cassowary  1 Jan 12:34 /testcases/files/5_MiB .rw-r--r-- 12k cassowary  1 Jan 12:34 /testcases/files/12_KiB .rw-r--r-- 6 cassowary  1 Jan 12:34 /testcases/files/6_bytes -.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/12_MiB .rw-r--r-- 6.1k cassowary  1 Jan 12:34 /testcases/files/6_KiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/12_MiB .rw-r--r-- 6.1k cassowary  1 Jan 12:34 /testcases/files/6_KiB .rw-r--r-- 13 cassowary  1 Jan 12:34 /testcases/files/13_bytes .rw-r--r-- 6.3M cassowary  1 Jan 12:34 /testcases/files/6_MiB .rw-r--r-- 13k cassowary  1 Jan 12:34 /testcases/files/13_KiB .rw-r--r-- 7 cassowary  1 Jan 12:34 /testcases/files/7_bytes -.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/13_MiB .rw-r--r-- 7.2k cassowary  1 Jan 12:34 /testcases/files/7_KiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 /testcases/files/13_MiB .rw-r--r-- 7.2k cassowary  1 Jan 12:34 /testcases/files/7_KiB .rw-r--r-- 1 cassowary  1 Jan 12:34 /testcases/files/1_bytes .rw-r--r-- 7.3M cassowary  1 Jan 12:34 /testcases/files/7_MiB .rw-r--r-- 1.0k cassowary  1 Jan 12:34 /testcases/files/1_KiB .rw-r--r-- 8 cassowary  1 Jan 12:34 /testcases/files/8_bytes .rw-r--r-- 1.0M cassowary  1 Jan 12:34 /testcases/files/1_MiB .rw-r--r-- 8.2k cassowary  1 Jan 12:34 /testcases/files/8_KiB diff --git a/xtests/outputs/files_paths_long_grid_3col.ansitxt b/xtests/outputs/files_paths_long_grid_3col.ansitxt index ce99ce2..71007b6 100644 --- a/xtests/outputs/files_paths_long_grid_3col.ansitxt +++ b/xtests/outputs/files_paths_long_grid_3col.ansitxt @@ -3,11 +3,11 @@ .rw-r--r-- 10M cassowary  1 Jan 12:34 /testcases/files/10_MiB .rw-r--r-- 2 cassowary  1 Jan 12:34 /testcases/files/2_bytes .rw-r--r-- 6.1k cassowary  1 Jan 12:34 /testcases/files/6_KiB .rw-r--r-- 11 cassowary  1 Jan 12:34 /testcases/files/11_bytes .rw-r--r-- 2.0k cassowary  1 Jan 12:34 /testcases/files/2_KiB .rw-r--r-- 6.3M cassowary  1 Jan 12:34 /testcases/files/6_MiB .rw-r--r-- 11k cassowary  1 Jan 12:34 /testcases/files/11_KiB .rw-r--r-- 2.1M cassowary  1 Jan 12:34 /testcases/files/2_MiB .rw-r--r-- 7 cassowary  1 Jan 12:34 /testcases/files/7_bytes -.rw-r--r-- 11M cassowary  1 Jan 12:34 /testcases/files/11_MiB .rw-r--r-- 3 cassowary  1 Jan 12:34 /testcases/files/3_bytes .rw-r--r-- 7.2k cassowary  1 Jan 12:34 /testcases/files/7_KiB +.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/11_MiB .rw-r--r-- 3 cassowary  1 Jan 12:34 /testcases/files/3_bytes .rw-r--r-- 7.2k cassowary  1 Jan 12:34 /testcases/files/7_KiB .rw-r--r-- 12 cassowary  1 Jan 12:34 /testcases/files/12_bytes .rw-r--r-- 3.1k cassowary  1 Jan 12:34 /testcases/files/3_KiB .rw-r--r-- 7.3M cassowary  1 Jan 12:34 /testcases/files/7_MiB .rw-r--r-- 12k cassowary  1 Jan 12:34 /testcases/files/12_KiB .rw-r--r-- 3.1M cassowary  1 Jan 12:34 /testcases/files/3_MiB .rw-r--r-- 8 cassowary  1 Jan 12:34 /testcases/files/8_bytes -.rw-r--r-- 12M cassowary  1 Jan 12:34 /testcases/files/12_MiB .rw-r--r-- 4 cassowary  1 Jan 12:34 /testcases/files/4_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 /testcases/files/8_KiB +.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/12_MiB .rw-r--r-- 4 cassowary  1 Jan 12:34 /testcases/files/4_bytes .rw-r--r-- 8.2k cassowary  1 Jan 12:34 /testcases/files/8_KiB .rw-r--r-- 13 cassowary  1 Jan 12:34 /testcases/files/13_bytes .rw-r--r-- 4.1k cassowary  1 Jan 12:34 /testcases/files/4_KiB .rw-r--r-- 8.4M cassowary  1 Jan 12:34 /testcases/files/8_MiB .rw-r--r-- 13k cassowary  1 Jan 12:34 /testcases/files/13_KiB .rw-r--r-- 4.2M cassowary  1 Jan 12:34 /testcases/files/4_MiB .rw-r--r-- 9 cassowary  1 Jan 12:34 /testcases/files/9_bytes -.rw-r--r-- 13M cassowary  1 Jan 12:34 /testcases/files/13_MiB .rw-r--r-- 5 cassowary  1 Jan 12:34 /testcases/files/5_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 /testcases/files/9_KiB +.rw-r--r-- 14M cassowary  1 Jan 12:34 /testcases/files/13_MiB .rw-r--r-- 5 cassowary  1 Jan 12:34 /testcases/files/5_bytes .rw-r--r-- 9.2k cassowary  1 Jan 12:34 /testcases/files/9_KiB .rw-r--r-- 1 cassowary  1 Jan 12:34 /testcases/files/1_bytes .rw-r--r-- 5.1k cassowary  1 Jan 12:34 /testcases/files/5_KiB .rw-r--r-- 9.4M cassowary  1 Jan 12:34 /testcases/files/9_MiB diff --git a/xtests/outputs/files_paths_long_grid_header_1file.ansitxt b/xtests/outputs/files_paths_long_grid_header_1file.ansitxt new file mode 100644 index 0000000..569a56e --- /dev/null +++ b/xtests/outputs/files_paths_long_grid_header_1file.ansitxt @@ -0,0 +1,2 @@ +Permissions Size User Date Modified Name +.rw-r--r-- 10 cassowary  1 Jan 12:34 /testcases/files/10_bytes diff --git a/xtests/outputs/files_paths_long_grid_header_2files.ansitxt b/xtests/outputs/files_paths_long_grid_header_2files.ansitxt new file mode 100644 index 0000000..dd566b9 --- /dev/null +++ b/xtests/outputs/files_paths_long_grid_header_2files.ansitxt @@ -0,0 +1,2 @@ +Permissions Size User Date Modified Name Permissions Size User Date Modified Name +.rw-r--r-- 10 cassowary  1 Jan 12:34 /testcases/files/10_bytes .rw-r--r-- 10k cassowary  1 Jan 12:34 /testcases/files/10_KiB diff --git a/xtests/outputs/files_tree_icons.ansitxt b/xtests/outputs/files_tree_icons.ansitxt index 2d05bca..1c571ae 100644 --- a/xtests/outputs/files_tree_icons.ansitxt +++ b/xtests/outputs/files_tree_icons.ansitxt @@ -1,4 +1,4 @@ - /testcases/files + /testcases/files ├──  1_bytes ├──  1_KiB ├──  1_MiB diff --git a/xtests/outputs/help.ansitxt b/xtests/outputs/help.ansitxt index 87a491c..750a66f 100644 --- a/xtests/outputs/help.ansitxt +++ b/xtests/outputs/help.ansitxt @@ -16,6 +16,7 @@ DISPLAY OPTIONS --colo[u]r=WHEN when to use terminal colours (always, auto, never) --colo[u]r-scale highlight levels of file sizes distinctly --icons display icons + --no-icons don't display icons (always overrides --icons) FILTERING AND SORTING OPTIONS -a, --all show hidden and 'dot' files @@ -39,6 +40,7 @@ LONG VIEW OPTIONS -H, --links list each file's number of hard links -i, --inode list each file's inode number -m, --modified use the modified timestamp field + -n, --numeric list numeric user and group IDs -S, --blocks show number of file system blocks -t, --time FIELD which timestamp field to list (modified, accessed, created) -u, --accessed use the accessed timestamp field diff --git a/xtests/outputs/links_oneline_icons.ansitxt b/xtests/outputs/links_oneline_icons.ansitxt index 7457089..48a99e0 100644 --- a/xtests/outputs/links_oneline_icons.ansitxt +++ b/xtests/outputs/links_oneline_icons.ansitxt @@ -1,10 +1,10 @@ - broken -> nowhere - current_dir -> . - forbidden -> /proc/1/root - itself -> itself - parent_dir -> .. - root -> / + broken -> nowhere + current_dir -> . + forbidden -> /proc/1/root + itself -> itself + parent_dir -> .. + root -> /  some_file - some_file_absolute -> /testcases/links/some_file - some_file_relative -> some_file - usr -> /usr + some_file_absolute -> /testcases/links/some_file + some_file_relative -> some_file + usr -> /usr diff --git a/xtests/outputs/links_oneline_icons_width0.ansitxt b/xtests/outputs/links_oneline_icons_width0.ansitxt index 867c310..df4a963 100644 --- a/xtests/outputs/links_oneline_icons_width0.ansitxt +++ b/xtests/outputs/links_oneline_icons_width0.ansitxt @@ -1,10 +1,10 @@ -broken -> nowhere -current_dir -> . -forbidden -> /proc/1/root -itself -> itself -parent_dir -> .. -root -> / +broken -> nowhere +current_dir -> . +forbidden -> /proc/1/root +itself -> itself +parent_dir -> .. +root -> / some_file -some_file_absolute -> /testcases/links/some_file -some_file_relative -> some_file -usr -> /usr +some_file_absolute -> /testcases/links/some_file +some_file_relative -> some_file +usr -> /usr diff --git a/xtests/outputs/links_oneline_icons_width2.ansitxt b/xtests/outputs/links_oneline_icons_width2.ansitxt index 914aa12..50df3db 100644 --- a/xtests/outputs/links_oneline_icons_width2.ansitxt +++ b/xtests/outputs/links_oneline_icons_width2.ansitxt @@ -1,10 +1,10 @@ - broken -> nowhere - current_dir -> . - forbidden -> /proc/1/root - itself -> itself - parent_dir -> .. - root -> / + broken -> nowhere + current_dir -> . + forbidden -> /proc/1/root + itself -> itself + parent_dir -> .. + root -> /  some_file - some_file_absolute -> /testcases/links/some_file - some_file_relative -> some_file - usr -> /usr + some_file_absolute -> /testcases/links/some_file + some_file_relative -> some_file + usr -> /usr diff --git a/xtests/outputs/links_oneline_icons_width3.ansitxt b/xtests/outputs/links_oneline_icons_width3.ansitxt index 417a6c3..ee749c3 100644 --- a/xtests/outputs/links_oneline_icons_width3.ansitxt +++ b/xtests/outputs/links_oneline_icons_width3.ansitxt @@ -1,10 +1,10 @@ - broken -> nowhere - current_dir -> . - forbidden -> /proc/1/root - itself -> itself - parent_dir -> .. - root -> / + broken -> nowhere + current_dir -> . + forbidden -> /proc/1/root + itself -> itself + parent_dir -> .. + root -> /  some_file - some_file_absolute -> /testcases/links/some_file - some_file_relative -> some_file - usr -> /usr + some_file_absolute -> /testcases/links/some_file + some_file_relative -> some_file + usr -> /usr diff --git a/xtests/outputs/permissions_oneline_icons.ansitxt b/xtests/outputs/permissions_oneline_icons.ansitxt index e982768..156f478 100644 --- a/xtests/outputs/permissions_oneline_icons.ansitxt +++ b/xtests/outputs/permissions_oneline_icons.ansitxt @@ -5,18 +5,18 @@  010  020  040 - 100 + 100  200  400  644 - 755 - 777 + 755 + 777  1000  1001  2000  2010  4000 - 4100 + 4100  7666 - 7777 - forbidden-directory + 7777 + forbidden-directory diff --git a/xtests/run.sh b/xtests/run.sh index 83682d1..bbae83b 100755 --- a/xtests/run.sh +++ b/xtests/run.sh @@ -7,6 +7,11 @@ case "$1" in *) exa_binary="$HOME/target/debug/exa" ;; esac +if [ ! -e /vagrant ]; then + echo "The extended tests must be run on the Vagrant machine." + exit 1 +fi + if [ ! -f "$exa_binary" ]; then echo "exa binary ($exa_binary) does not exist" if [ "$1" != "--release" ]; then echo -e "create it first with \033[1;32mbuild-exa\033[0m or \033[1;32mb\033[0m"; fi