Merge branch 'master' into chesterliu/dev/win-support

This commit is contained in:
skyline75489 2021-04-03 21:12:19 +08:00
commit 8ad46e2ee5
44 changed files with 345 additions and 243 deletions

50
Cargo.lock generated
View File

@ -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",

View File

@ -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]

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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)" \

View File

@ -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 files number of file system blocks.

View File

@ -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);
}
}

View File

@ -93,7 +93,7 @@ fn main() {
}
OptionsResult::InvalidOptions(error) => {
eprintln!("{}", error);
eprintln!("exa: {}", error);
if let Some(s) = error.suggestion() {
eprintln!("{}", s);

View File

@ -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,

View File

@ -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)
}
}

View File

@ -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 wont 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<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
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<Self, OptionsError> {
let flag = matches.has(&flags::NUMERIC)?;
Ok(if flag { Self::Numeric } else { Self::Name })
}
}
impl TimeTypes {
/// Determine which of a files 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));

View File

@ -157,7 +157,11 @@ impl<'a> Render<'a> {
.map(|file| self.file_style.for_file(file, self.theme).paint().promote())
.collect::<Vec<_>>();
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 cant 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 weve figured out how many columns can fit in the users
// terminal, and it turns out there arent 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));
}
}

View File

@ -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<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;
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));
}
}

View File

@ -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());

View File

@ -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<C: Colours, U: Users>(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<C: Colours, U: Users>(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));
}
}

View File

@ -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<TimeZone> {
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)

View File

@ -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 dont 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 dont 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' ]

View File

@ -4,4 +4,4 @@ shell = "exa --help"
stdout = { file = "outputs/help.ansitxt" }
stderr = { empty = true }
status = 0
tags = [ 'help ']
tags = [ 'help' ]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
Permissions Size User Date Modified Name
.rw-r--r-- 10 cassowary  1 Jan 12:34 /testcases/files/10_bytes

View File

@ -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

View File

@ -1,4 +1,4 @@
 /testcases/files
 /testcases/files
├──  1_bytes
├──  1_KiB
├──  1_MiB

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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