mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-23 04:22:06 +00:00
Merge branch 'master' into makefile
This commit is contained in:
commit
20b6588552
111
Cargo.lock
generated
111
Cargo.lock
generated
@ -8,7 +8,7 @@ dependencies = [
|
||||
"git2 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"locale 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"natord 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -43,26 +43,13 @@ dependencies = [
|
||||
"gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "datetime"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"iso8601 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"locale 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pad 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -73,15 +60,6 @@ name = "gcc"
|
||||
version = "0.3.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gdi32-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.14"
|
||||
@ -93,10 +71,8 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libgit2-sys 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -130,33 +106,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.21"
|
||||
version = "0.2.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.6.8"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libssh2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libssh2-sys"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -166,7 +127,7 @@ version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -175,7 +136,7 @@ name = "locale"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -265,7 +226,7 @@ name = "num_cpus"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -276,23 +237,6 @@ dependencies = [
|
||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pad"
|
||||
version = "0.1.4"
|
||||
@ -311,7 +255,7 @@ name = "rand"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -359,33 +303,14 @@ dependencies = [
|
||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "user32-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "zoneinfo_compiled"
|
||||
version = "0.2.1"
|
||||
@ -400,19 +325,16 @@ dependencies = [
|
||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
"checksum byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96c8b41881888cc08af32d47ac4edd52bc7fa27fef774be47a92443756451304"
|
||||
"checksum cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "d18d68987ed4c516dcc3e7913659bfa4076f5182eea4a7e0038bb060953e76ac"
|
||||
"checksum curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "23e7e544dc5e1ba42c4a4a678bd47985e84b9c3f4d3404c29700622a029db9c3"
|
||||
"checksum datetime 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2d425bf1f6bbd57cf833081c1e60ac294fd74e7edd66acc91c3fca2e496bcee9"
|
||||
"checksum gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)" = "40899336fb50db0c78710f53e87afc54d8c7266fb76262fecc78ca1a7f09deae"
|
||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
|
||||
"checksum git2 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "046ae03385257040b2a35e56d9669d950dd911ba2bf48202fbef73ee6aab27b2"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac85ec3f80c8e4e99d9325521337e14ec7555c458a14e377d189659a427f375"
|
||||
"checksum iso8601 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "11dc464f8c6f17595d191447c9c6559298b2d023d6f846a4a23ac7ea3c46c477"
|
||||
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||
"checksum libgit2-sys 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68bed1d1198da5d2b047af68fd71613ddfaa3d5b68797181b33e9d8547263b4b"
|
||||
"checksum libssh2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "91e135645c2e198a39552c8c7686bb5b83b1b99f64831c040a6c2798a1195934"
|
||||
"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502"
|
||||
"checksum libgit2-sys 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a3aaa20337a0e79fb75180b6a1970c1f7cff9a413f570d6b999b38a5d5d54e81"
|
||||
"checksum libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e5ee912a45d686d393d5ac87fac15ba0ba18daae14e8e7543c63ebf7fb7e970c"
|
||||
"checksum locale 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ecccf5186e43f84e543bbf61fcddf00b41d69d97093bc8989cc0cf1593681950"
|
||||
"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1"
|
||||
@ -427,8 +349,6 @@ dependencies = [
|
||||
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
|
||||
"checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167"
|
||||
"checksum number_prefix 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "59a14be9c211cb9c602bad35ac99f41e9a84b44d71b8cbd3040e3bd02a214902"
|
||||
"checksum openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98df0270d404ccd3c050a41d579c52d1db15375168bb3471e04ec0f5f378daf"
|
||||
"checksum openssl-sys 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e5e0fd64cb2fa018ed2e7b2c8d9649114fe5da957c9a67432957f01e5dcc82e9"
|
||||
"checksum pad 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d1bf3336e626b898e7263790d432a711d4277e22faea20dd9f70e0cab268fa58"
|
||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
||||
@ -439,8 +359,5 @@ dependencies = [
|
||||
"checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff"
|
||||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||||
"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e"
|
||||
"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47"
|
||||
"checksum users 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7ae8fdf783cb9652109c99886459648feb92ecc749e6b8e7930f6decba74c7c"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum zoneinfo_compiled 0.2.1 (git+https://github.com/rust-datetime/zoneinfo-compiled.git)" = "<none>"
|
||||
|
@ -39,6 +39,7 @@ lto = true
|
||||
[dependencies.git2]
|
||||
version = "0.6.4"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dependencies.zoneinfo_compiled]
|
||||
git = "https://github.com/rust-datetime/zoneinfo-compiled.git"
|
||||
|
70
Makefile
70
Makefile
@ -1,25 +1,63 @@
|
||||
PREFIX ?= /usr/local
|
||||
SRC = \
|
||||
src/info/sources.rs \
|
||||
src/info/mod.rs \
|
||||
src/info/filetype.rs \
|
||||
src/bin/main.rs \
|
||||
src/term.rs \
|
||||
src/exa.rs \
|
||||
src/output/grid_details.rs \
|
||||
src/output/tree.rs \
|
||||
src/output/colours.rs \
|
||||
src/output/grid.rs \
|
||||
src/output/cell.rs \
|
||||
src/output/mod.rs \
|
||||
src/output/details.rs \
|
||||
src/output/lines.rs \
|
||||
src/output/column.rs \
|
||||
src/fs/file.rs \
|
||||
src/fs/fields.rs \
|
||||
src/fs/mod.rs \
|
||||
src/fs/dir.rs \
|
||||
src/fs/feature/xattr.rs \
|
||||
src/fs/feature/git.rs \
|
||||
src/fs/feature/mod.rs \
|
||||
src/options/misfire.rs \
|
||||
src/options/filter.rs \
|
||||
src/options/dir_action.rs \
|
||||
src/options/view.rs \
|
||||
src/options/mod.rs \
|
||||
src/options/help.rs
|
||||
|
||||
BUILD = target/release/exa
|
||||
PREFIX = /usr/local
|
||||
|
||||
$(BUILD):
|
||||
@which rustc > /dev/null || { echo "exa requires Rust to compile. For installation instructions, please visit http://rust-lang.org/"; exit 1; }
|
||||
cargo build --release
|
||||
CARGOFLAGS = --no-default-features
|
||||
|
||||
build: $(BUILD)
|
||||
all: target/release/exa
|
||||
|
||||
build-no-git:
|
||||
@which rustc > /dev/null || { echo "exa requires Rust to compile. For installation instructions, please visit http://rust-lang.org/"; exit 1; }
|
||||
cargo build --release --no-default-features
|
||||
build: CARGOFLAGS=
|
||||
build: all
|
||||
build-no-git: all
|
||||
|
||||
INSTALL = $(PREFIX)/bin/exa
|
||||
target/release/exa: $(SRC)
|
||||
if test -n "$$(echo "$$CC" | cut -d \ -f 1)"; then \
|
||||
env CC="$$(echo "$$CC" | cut -d \ -f 1)" cargo build --release $(CARGOFLAGS); \
|
||||
else\
|
||||
env -u CC cargo build --release $(CARGOFLAGS); \
|
||||
fi
|
||||
|
||||
$(INSTALL):
|
||||
install: target/release/exa
|
||||
# BSD and OSX don't have -D to create leading directories
|
||||
install -dm755 $(PREFIX)/bin/ $(PREFIX)/share/man/man1/
|
||||
install -sm755 target/release/exa $(PREFIX)/bin/
|
||||
install -m644 contrib/man/*.1 $(PREFIX)/share/man/man1/
|
||||
install -dm755 -- "$(DESTDIR)$(PREFIX)/bin/" "$(DESTDIR)$(PREFIX)/share/man/man1/"
|
||||
install -m755 -- target/release/exa "$(DESTDIR)$(PREFIX)/bin/"
|
||||
install -m644 -- contrib/man/exa.1 "$(DESTDIR)$(PREFIX)/share/man/man1/"
|
||||
|
||||
install: build $(INSTALL)
|
||||
uninstall:
|
||||
-rm -- "$(DESTDIR)$(PREFIX)/share/man/man1/exa.1"
|
||||
-rmdir -- "$(DESTDIR)$(PREFIX)/share/man/man1"
|
||||
-rm -- "$(DESTDIR)$(PREFIX)/bin/exa"
|
||||
-rmdir -- "$(DESTDIR)$(PREFIX)/bin"
|
||||
|
||||
.PHONY: $(BUILD) build-no-git $(INSTALL)
|
||||
clean:
|
||||
-rm -rf target
|
||||
|
||||
.PHONY: all build install
|
||||
|
52
README.md
52
README.md
@ -14,21 +14,21 @@ exa’s options are similar, but not exactly the same, as `ls`.
|
||||
### Display Options
|
||||
|
||||
- **-1**, **--oneline**: display one entry per line
|
||||
- **-G**, **--grid**: display entries in a grid view (default)
|
||||
- **-G**, **--grid**: display entries as a grid (default)
|
||||
- **-l**, **--long**: display extended details and attributes
|
||||
- **-R**, **--recurse**: recurse into directories
|
||||
- **-T**, **--tree**: recurse into subdirectories in a tree view
|
||||
- **-x**, **--across**: sort multi-column view entries across
|
||||
- **--color**, **--colour**: when to colourise the output
|
||||
- **--color-scale**, **--colour-scale**: colour file sizes according to their magnitude
|
||||
- **-T**, **--tree**: recurse into directories as a tree
|
||||
- **-x**, **--across**: sort the grid across, rather than downwards
|
||||
- **--colo[u]r**: when to use terminal colours
|
||||
- **--colo[u]r-scale**: highlight levels of file sizes distinctly
|
||||
|
||||
### Filtering Options
|
||||
|
||||
- **-a**, **--all**: show dot files
|
||||
- **-d**, **--list-dirs**: list directories as regular files
|
||||
- **-L**, **--level=(depth)**: maximum depth of recursion
|
||||
- **-r**, **--reverse**: reverse sort order
|
||||
- **-s**, **--sort=(field)**: field to sort by
|
||||
- **-a**, **--all**: don't hide hidden and 'dot' files
|
||||
- **-d**, **--list-dirs**: list directories like regular files
|
||||
- **-L**, **--level=(depth)**: limit the depth of recursion
|
||||
- **-r**, **--reverse**: reverse the sort order
|
||||
- **-s**, **--sort=(field)**: which field to sort by
|
||||
- **--group-directories-first**: list directories before other files
|
||||
- **-I**, **--ignore-glob=(globs)**: glob patterns (pipe-separated) of files to ignore
|
||||
|
||||
@ -36,23 +36,23 @@ exa’s options are similar, but not exactly the same, as `ls`.
|
||||
|
||||
These options are available when running with --long (`-l`):
|
||||
|
||||
- **-b**, **--binary**: use binary (power of two) file sizes
|
||||
- **-B**, **--bytes**: list file sizes in bytes, without prefixes
|
||||
- **-g**, **--group**: show group as well as user
|
||||
- **-h**, **--header**: show a header row
|
||||
- **-H**, **--links**: show number of hard links column
|
||||
- **-i**, **--inode**: show inode number column
|
||||
- **-m**, **--modified**: display timestamp of most recent modification
|
||||
- **-S**, **--blocks**: show number of file system blocks
|
||||
- **-t**, **--time=(field)**: which timestamp to show for a file
|
||||
- **-u**, **--accessed**: display timestamp of last access for a file
|
||||
- **-U**, **--created**: display timestamp of creation of a file
|
||||
- **-@**, **--extended**: display extended attribute keys and sizes
|
||||
- **--git**: show Git status for a file
|
||||
- **-b**, **--binary**: list file sizes with binary prefixes
|
||||
- **-B**, **--bytes**: list file sizes in bytes, without any prefixes
|
||||
- **-g**, **--group**: list each file's group
|
||||
- **-h**, **--header**: add a header row to each column
|
||||
- **-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
|
||||
- **-S**, **--blocks**: list each file's number of file system blocks
|
||||
- **-t**, **--time=(field)**: which timestamp field to use
|
||||
- **-u**, **--accessed**: use the accessed timestamp field
|
||||
- **-U**, **--created**: use the created timestamp field
|
||||
- **-@**, **--extended**: list each file's extended attributes and sizes
|
||||
- **--git**: list each file's Git status, if tracked
|
||||
|
||||
Accepted **--color** options are **always**, **automatic**, and **never**.
|
||||
Valid sort fields are **name**, **size**, **extension**, **modified**, **accessed**, **created**, **inode**, and **none**.
|
||||
Valid time fields are **modified**, **accessed**, and **created**.
|
||||
- Valid **--color** options are **always**, **automatic**, and **never**.
|
||||
- Valid sort fields are **accessed**, **created**, **extension**, **Extension**, **inode**, **modified**, **name**, **Name**, **size**, and **none**. Fields starting with a capital letter are case-sensitive.
|
||||
- Valid time fields are **modified**, **accessed**, and **created**.
|
||||
|
||||
|
||||
## Installation
|
||||
|
87
Vagrantfile
vendored
87
Vagrantfile
vendored
@ -7,6 +7,8 @@ Vagrant.configure(2) do |config|
|
||||
v.cpus = 1
|
||||
end
|
||||
|
||||
developer = 'ubuntu'
|
||||
|
||||
|
||||
# We use Ubuntu instead of Debian because the image comes with two-way
|
||||
# shared folder support by default.
|
||||
@ -16,8 +18,11 @@ Vagrant.configure(2) do |config|
|
||||
|
||||
# Install the dependencies needed for exa to build, as quietly as
|
||||
# apt can do.
|
||||
config.vm.provision :shell, privileged: true, inline:
|
||||
%[apt-get install -qq -o=Dpkg::Use-Pty=0 -y git cmake libssl-dev libgit2-dev libssh2-1-dev curl attr pkg-config]
|
||||
config.vm.provision :shell, privileged: true, inline: <<-EOF
|
||||
apt-get install -qq -o=Dpkg::Use-Pty=0 -y \
|
||||
git cmake curl attr pkg-config libgit2-dev \
|
||||
fish zsh bash bash-completion
|
||||
EOF
|
||||
|
||||
|
||||
# Guarantee that the timezone is UTC -- some of the tests
|
||||
@ -38,13 +43,40 @@ Vagrant.configure(2) do |config|
|
||||
# By default it just uses the one in /vagrant/target, which can
|
||||
# cause problems if it has different permissions than the other
|
||||
# directories, or contains object files compiled for the host.
|
||||
config.vm.provision :shell, privileged: false, inline:
|
||||
%[echo "export CARGO_TARGET_DIR=/home/ubuntu/target" >> ~/.bashrc]
|
||||
config.vm.provision :shell, privileged: false, inline: <<-EOF
|
||||
function put_line() {
|
||||
grep -q -F "$2" $1 || echo "$2" >> $1
|
||||
}
|
||||
|
||||
put_line ~/.bashrc 'export CARGO_TARGET_DIR=/home/#{developer}/target'
|
||||
EOF
|
||||
|
||||
|
||||
# Create "dexa" and "rexa" scripts that run the debug and release
|
||||
# compiled versions of exa.
|
||||
config.vm.provision :shell, privileged: true, inline: <<-EOF
|
||||
echo -e "#!/bin/sh\n/home/#{developer}/target/debug/exa \\$*" > /usr/bin/exa
|
||||
echo -e "#!/bin/sh\n/home/#{developer}/target/release/exa \\$*" > /usr/bin/rexa
|
||||
chmod +x /usr/bin/{exa,rexa}
|
||||
EOF
|
||||
|
||||
|
||||
# Link the completion files so they’re “installed”.
|
||||
config.vm.provision :shell, privileged: true, inline: <<-EOF
|
||||
test -h /etc/bash_completion.d/exa \
|
||||
|| ln -s /vagrant/contrib/completions.bash /etc/bash_completion.d/exa
|
||||
|
||||
test -h /usr/share/zsh/vendor-completions/_exa \
|
||||
|| ln -s /vagrant/contrib/completions.zsh /usr/share/zsh/vendor-completions/_exa
|
||||
|
||||
test -h /usr/share/fish/completions/exa.fish \
|
||||
|| ln -s /vagrant/contrib/completions.fish /usr/share/fish/completions/exa.fish
|
||||
EOF
|
||||
|
||||
|
||||
# We create two users that own the test files.
|
||||
# The first one just owns the ordinary ones, because we don’t want to
|
||||
# depend on “vagrant” or “ubuntu” existing.
|
||||
# The first one just owns the ordinary ones, because we don’t want the
|
||||
# test outputs to depend on “vagrant” or “ubuntu” existing.
|
||||
user = "cassowary"
|
||||
config.vm.provision :shell, privileged: true, inline:
|
||||
%[id -u #{user} &>/dev/null || useradd #{user}]
|
||||
@ -142,6 +174,49 @@ Vagrant.configure(2) do |config|
|
||||
EOF
|
||||
|
||||
|
||||
# File name testcases.
|
||||
# bash really doesn’t want you to create a file with escaped characters
|
||||
# in its name, so we have to resort to the echo builtin and touch!
|
||||
#
|
||||
# The double backslashes are not strictly necessary; without them, Ruby
|
||||
# will interpolate them instead of bash, but because Vagrant prints out
|
||||
# each command it runs, your *own* terminal will go “ding” from the alarm!
|
||||
config.vm.provision :shell, privileged: false, inline: <<-EOF
|
||||
set -xe
|
||||
mkdir "#{test_dir}/file-names"
|
||||
|
||||
echo -ne "#{test_dir}/file-names/ascii: hello" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/emoji: [🆒]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/utf-8: pâté" | xargs -0 touch
|
||||
|
||||
echo -ne "#{test_dir}/file-names/bell: [\\a]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/backspace: [\\b]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/form-feed: [\\f]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/new-line: [\\n]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/return: [\\r]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/tab: [\\t]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/vertical-tab: [\\v]" | xargs -0 touch
|
||||
|
||||
echo -ne "#{test_dir}/file-names/escape: [\\033]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/ansi: [\\033[34mblue\\033[0m]" | xargs -0 touch
|
||||
|
||||
echo -ne "#{test_dir}/file-names/invalid-utf8-1: [\\xFF]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/invalid-utf8-2: [\\xc3\\x28]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/invalid-utf8-3: [\\xe2\\x82\\x28]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/invalid-utf8-4: [\\xf0\\x28\\x8c\\x28]" | xargs -0 touch
|
||||
|
||||
echo -ne "#{test_dir}/file-names/new-line-dir: [\\n]" | xargs -0 mkdir
|
||||
echo -ne "#{test_dir}/file-names/new-line-dir: [\\n]/subfile" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/new-line-dir: [\\n]/another: [\\n]" | xargs -0 touch
|
||||
echo -ne "#{test_dir}/file-names/new-line-dir: [\\n]/broken" | xargs -0 touch
|
||||
|
||||
mkdir "#{test_dir}/file-names/links"
|
||||
ln -s "#{test_dir}/file-names/new-line-dir"*/* "#{test_dir}/file-names/links"
|
||||
|
||||
echo -ne "#{test_dir}/file-names/new-line-dir: [\\n]/broken" | xargs -0 rm
|
||||
EOF
|
||||
|
||||
|
||||
# Special file testcases.
|
||||
config.vm.provision :shell, privileged: false, inline: <<-EOF
|
||||
set -xe
|
||||
|
37
contrib/completions.bash
Normal file
37
contrib/completions.bash
Normal file
@ -0,0 +1,37 @@
|
||||
_exa()
|
||||
{
|
||||
cur=${COMP_WORDS[COMP_CWORD]}
|
||||
prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
-'?'|--help|-v|--version)
|
||||
return
|
||||
;;
|
||||
|
||||
-L|--level)
|
||||
COMPREPLY=( $( compgen -W '{0..9}' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
|
||||
-s|--sort)
|
||||
COMPREPLY=( $( compgen -W 'name filename Name Filename size filesize extension Extension modified accessed created none inode --' -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
|
||||
-t|--time)
|
||||
COMPREPLY=( $( compgen -W 'accessed modified created --' -- $cur ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
|
||||
;;
|
||||
|
||||
*)
|
||||
_filedir
|
||||
;;
|
||||
esac
|
||||
} &&
|
||||
complete -o filenames -o bashdefault -F _exa exa
|
62
contrib/completions.fish
Normal file
62
contrib/completions.fish
Normal file
@ -0,0 +1,62 @@
|
||||
# Meta-stuff
|
||||
complete -c exa -s 'v' -l 'version' -d "Show version of exa"
|
||||
complete -c exa -s '?' -l 'help' -d "Show list of command-line options"
|
||||
|
||||
# Display options
|
||||
complete -c exa -s '1' -l 'oneline' -d "Display one entry per line"
|
||||
complete -c exa -s 'l' -l 'long' -d "Display extended file metadata as a table"
|
||||
complete -c exa -s 'G' -l 'grid' -d "Display entries in a grid"
|
||||
complete -c exa -s 'x' -l 'across' -d "Sort the grid across, rather than downwards"
|
||||
complete -c exa -s 'R' -l 'recurse' -d "Recurse into directories"
|
||||
complete -c exa -s 'T' -l 'tree' -d "Recurse into directories as a tree"
|
||||
complete -c exa -s 'F' -l 'classify' -d "Display type indicator by file names"
|
||||
complete -c exa -l 'color' -d "When to use terminal colours"
|
||||
complete -c exa -l 'colour' -d "When to use terminal colours"
|
||||
complete -c exa -l 'color-scale' -d "Highlight levels of file sizes distinctly"
|
||||
complete -c exa -l 'colour-scale' -d "Highlight levels of file sizes distinctly"
|
||||
|
||||
# Filtering and sorting options
|
||||
complete -c exa -l 'group-directories-first' -d "Sort directories before other files"
|
||||
complete -c exa -s 'a' -l 'all' -d "Don't hide hidden and 'dot' files"
|
||||
complete -c exa -s 'd' -l 'list-dirs' -d "List directories like regular files"
|
||||
complete -c exa -s 'L' -l 'level' -d "Limit the depth of recursion" -a "1 2 3 4 5 6 7 8 9"
|
||||
complete -c exa -s 'r' -l 'reverse' -d "Reverse the sort order"
|
||||
complete -c exa -s 's' -l 'sort' -x -d "Which field to sort by" -a "
|
||||
accessed\t'Sort by file accessed time'
|
||||
created\t'Sort by file modified time'
|
||||
ext\t'Sort by file extension'
|
||||
Ext\t'Sort by file extension (case-insensitive)'
|
||||
extension\t'Sort by file extension'
|
||||
Extension\t'Sort by file extension (case-insensitive)'
|
||||
filename\t'Sort by filename'
|
||||
Filename\t'Sort by filename (case-insensitive)'
|
||||
inode\t'Sort by file inode'
|
||||
modified\t'Sort by file modified time'
|
||||
name\t'Sort by filename'
|
||||
Name\t'Sort by filename (case-insensitive)'
|
||||
none\t'Do not sort files at all'
|
||||
size\t'Sort by file size'
|
||||
"
|
||||
|
||||
complete -c exa -s 'I' -l 'ignore-glob' -d "Ignore files that match these glob patterns" -r
|
||||
|
||||
# Long view options
|
||||
complete -c exa -s 'b' -l 'binary' -d "List file sizes with binary prefixes"
|
||||
complete -c exa -s 'B' -l 'bytes' -d "List file sizes in bytes, without any prefixes"
|
||||
complete -c exa -s 'g' -l 'group' -d "List each file's group"
|
||||
complete -c exa -s 'h' -l 'header' -d "Add a header row to each column"
|
||||
complete -c exa -s 'h' -l 'links' -d "List each file's number of hard links"
|
||||
complete -c exa -s 'g' -l 'group' -d "List each file's inode number"
|
||||
complete -c exa -s 'm' -l 'modified' -d "Use the modified timestamp field"
|
||||
complete -c exa -s 'S' -l 'blocks' -d "List each file's number of filesystem blocks"
|
||||
complete -c exa -s 't' -l 'time' -x -d "Which timestamp field to list" -a "
|
||||
accessed\t'Display accessed time'
|
||||
created\t'Display created time'
|
||||
modified\t'Display modified time'
|
||||
"
|
||||
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"
|
||||
|
||||
# Optional extras
|
||||
complete -c exa -s 'g' -l 'git' -d "List each file's Git status, if tracked"
|
||||
complete -c exa -s '@' -l 'extended' -d "List each file's extended attributes and sizes"
|
39
contrib/completions.zsh
Normal file
39
contrib/completions.zsh
Normal file
@ -0,0 +1,39 @@
|
||||
#compdef exa
|
||||
|
||||
__exa() {
|
||||
_arguments \
|
||||
"(- 1 *)"{-v,--version}"[Show version of exa]" \
|
||||
"(- 1 *)"{-\?,--help}"[Show list of command-line options]" \
|
||||
{-1,--oneline}"[Display one entry per line]" \
|
||||
{-l,--long}"[Display extended file metadata as a table]" \
|
||||
{-G,--grid}"[Display entries as a grid]" \
|
||||
{-x,--across}"[Sort the grid across, rather than downwards]" \
|
||||
{-R,--recurse}"[Recurse into directories]" \
|
||||
{-T,--tree}"[Recurse into directories as a tree]" \
|
||||
{-F,--classify}"[Display type indicator by file names]" \
|
||||
{--color,--colour}"[When to use terminal colours]" \
|
||||
{--color,--colour}-scale"[Highlight levels of file sizes distinctly]" \
|
||||
--group-directories-first"[Sort directories before other files]" \
|
||||
{-a,--all}"[Don't hide hidden and 'dot' files]" \
|
||||
{-d,--list-dirs}"[List directories like regular files]" \
|
||||
{-L,--level}"+[Limit the depth of recursion]" \
|
||||
{-r,--reverse}"[Reverse the sort order]" \
|
||||
{-s,--sort}"[Which field to sort by]:(sort field):(accessed created extension Extension filename Filename inode modified name Name none size)" \
|
||||
{-I,--ignore-glob}"[Ignore files that match these glob patterns]" \
|
||||
{-b,--binary}"[List file sizes with binary prefixes]" \
|
||||
{-B,--bytes}"[List file sizes in bytes, without any prefixes]" \
|
||||
{-g,--group}"[List each file's group]" \
|
||||
{-h,--header}"[Add a header row to each column]" \
|
||||
{-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]" \
|
||||
{-S,--blocks}"[List each file's number of filesystem blocks]" \
|
||||
{-t,--time}"[Which time field to show]:(time field):(accessed created modified)" \
|
||||
{-u,--accessed}"[Use the accessed timestamp field]" \
|
||||
{-U,--created}"[Use the created timestamp field]" \
|
||||
--git"[List each file's Git status, if tracked]" \
|
||||
{-@,--extended}"[List each file's extended attributes and sizes]" \
|
||||
'*:filename:_files'
|
||||
}
|
||||
|
||||
__exa
|
@ -1,5 +1,5 @@
|
||||
.hy
|
||||
.TH "exa" "1" "2015\-10\-18" "exa 0.4.0" ""
|
||||
.TH "exa" "1" "2017\-05\-06" "exa 0.5.0" ""
|
||||
.SH NAME
|
||||
.PP
|
||||
exa \- a modern replacement for ls
|
||||
@ -23,12 +23,17 @@ display one entry per line
|
||||
.RE
|
||||
.TP
|
||||
.B \-G, \-\-grid
|
||||
display entries in a grid view (default)
|
||||
display entries as a grid (default)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-l, \-\-long
|
||||
display extended details and attributes
|
||||
display extended file metadata as a table
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-x, \-\-across
|
||||
sort the grid across, rather than downwards
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
@ -38,39 +43,45 @@ recurse into directories
|
||||
.RE
|
||||
.TP
|
||||
.B \-T, \-\-tree
|
||||
recurse into subdirectories in a tree view
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-x, \-\-across
|
||||
sort multi\-column view entries across
|
||||
recurse into directories as a tree
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-color, \-\-colour=\f[I]WHEN\f[]
|
||||
when to colourise the output (always, automatic, never)
|
||||
when to use terminal colours (always, automatic, never)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-color-scale, \-\-colour-scale
|
||||
highlight levels of file sizes distinctly
|
||||
.RS
|
||||
.RE
|
||||
.SH FILTERING AND SORTING OPTIONS
|
||||
.TP
|
||||
.B \-a, \-\-all
|
||||
show dot\-files
|
||||
don\[aq]t hide hidden and \[aq]dot\[aq] files
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-d, \-\-list\-dirs
|
||||
list directories as regular files
|
||||
list directories like regular files
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-r, \-\-reverse
|
||||
reverse order of files
|
||||
reverse the sort order
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-s, \-\-sort=\f[I]WORD\f[]
|
||||
field to sort by (name, size, extension, modified, accessed, created,
|
||||
inode, none)
|
||||
.B \-s, \-\-sort=\f[I]SORT_FIELD\f[]
|
||||
which field to sort by.
|
||||
Valid fields are name, Name, extension, Extension, size, modified, accessed, created, inode, and none.
|
||||
Fields starting with a capital letter are case-sensitive.
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-I, \-\-ignore\-glob=\f[I]GLOBS\f[]
|
||||
Glob patterns, pipe-separated, of files to ignore
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
@ -84,72 +95,72 @@ These options are available when running with \f[C]\-\-long\f[]
|
||||
(\f[C]\-l\f[]):
|
||||
.TP
|
||||
.B \-b, \-\-binary
|
||||
use binary prefixes in file sizes
|
||||
list file sizes with binary prefixes
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-B, \-\-bytes
|
||||
list file sizes in bytes, without prefixes
|
||||
list file sizes in bytes, without any prefixes
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-g, \-\-group
|
||||
show group as well as user
|
||||
list each file\[aq]s group
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-h, \-\-header
|
||||
show a header row at the top
|
||||
add a header row to each column
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-H, \-\-links
|
||||
show number of hard links
|
||||
list each file\[aq]s number of hard links
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-i, \-\-inode
|
||||
show each file\[aq]s inode number
|
||||
list each file\[aq]s inode number
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-L, \-\-level=\f[I]DEPTH\f[]
|
||||
maximum depth of recursion
|
||||
limit the depth of recursion
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-m, \-\-modified
|
||||
display timestamp of most recent modification
|
||||
use the modified timestamp field
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-S, \-\-blocks
|
||||
show number of file system blocks
|
||||
list each file\[aq]s number of file system blocks
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-t, \-\-time=\f[I]WORD\f[]
|
||||
which timestamp to show for a file (modified, accessed, created)
|
||||
which timestamp field to list (modified, accessed, created)
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-u, \-\-accessed
|
||||
display timestamp of last access for a file
|
||||
use the accessed timestamp field
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-U, \-\-created
|
||||
display timestamp of creation for a file
|
||||
use the created timestamp field
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\@, \-\-extended
|
||||
display extended attribute keys and sizes
|
||||
list each file\[aq]s extended attributes and sizes
|
||||
.RS
|
||||
.RE
|
||||
.TP
|
||||
.B \-\-git
|
||||
display Git status for a file, if available
|
||||
list each file\[aq]s Git status, if tracked
|
||||
.RS
|
||||
.RE
|
||||
.SH EXAMPLES
|
||||
|
@ -23,9 +23,12 @@ use std::ffi::OsStr;
|
||||
use std::io::{stderr, Write, Result as IOResult};
|
||||
use std::path::{Component, Path};
|
||||
|
||||
use ansi_term::{ANSIStrings, Style};
|
||||
|
||||
use fs::{Dir, File};
|
||||
use options::{Options, View};
|
||||
pub use options::Misfire;
|
||||
use output::escape;
|
||||
|
||||
mod fs;
|
||||
mod info;
|
||||
@ -116,7 +119,9 @@ impl<'w, W: Write + 'w> Exa<'w, W> {
|
||||
}
|
||||
|
||||
if !is_only_dir {
|
||||
writeln!(self.writer, "{}:", dir.path.display())?;
|
||||
let mut bits = Vec::new();
|
||||
escape(dir.path.display().to_string(), &mut bits, Style::default(), Style::default());
|
||||
writeln!(self.writer, "{}:", ANSIStrings(&bits))?;
|
||||
}
|
||||
|
||||
let mut children = Vec::new();
|
||||
|
131
src/fs/file.rs
131
src/fs/file.rs
@ -1,45 +1,32 @@
|
||||
//! Files, and methods and fields to access their metadata.
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::env::current_dir;
|
||||
use std::fs;
|
||||
use std::io::Error as IOError;
|
||||
use std::io::Result as IOResult;
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||
use std::os::unix::fs::{MetadataExt, PermissionsExt, FileTypeExt};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use fs::dir::Dir;
|
||||
use fs::fields as f;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
|
||||
/// Constant table copied from https://doc.rust-lang.org/src/std/sys/unix/ext/fs.rs.html#11-259
|
||||
/// which is currently unstable and lacks vision for stabilization,
|
||||
/// see https://github.com/rust-lang/rust/issues/27712
|
||||
#[allow(dead_code, non_camel_case_types)]
|
||||
#[allow(trivial_numeric_casts)]
|
||||
mod modes {
|
||||
pub type mode_t = u32;
|
||||
use libc;
|
||||
|
||||
pub const USER_READ: mode_t = 0o400;
|
||||
pub const USER_WRITE: mode_t = 0o200;
|
||||
pub const USER_EXECUTE: mode_t = 0o100;
|
||||
pub const USER_RWX: mode_t = 0o700;
|
||||
pub const GROUP_READ: mode_t = 0o040;
|
||||
pub const GROUP_WRITE: mode_t = 0o020;
|
||||
pub const GROUP_EXECUTE: mode_t = 0o010;
|
||||
pub const GROUP_RWX: mode_t = 0o070;
|
||||
pub const OTHER_READ: mode_t = 0o004;
|
||||
pub const OTHER_WRITE: mode_t = 0o002;
|
||||
pub const OTHER_EXECUTE: mode_t = 0o001;
|
||||
pub const OTHER_RWX: mode_t = 0o007;
|
||||
pub const ALL_READ: mode_t = 0o444;
|
||||
pub const ALL_WRITE: mode_t = 0o222;
|
||||
pub const ALL_EXECUTE: mode_t = 0o111;
|
||||
pub const ALL_RWX: mode_t = 0o777;
|
||||
pub const SETUID: mode_t = 0o4000;
|
||||
pub const SETGID: mode_t = 0o2000;
|
||||
pub const STICKY_BIT: mode_t = 0o1000;
|
||||
pub type Mode = u32;
|
||||
// The `libc::mode_t` type’s actual type varies, but the value returned
|
||||
// from `metadata.permissions().mode()` is always `u32`.
|
||||
|
||||
pub const USER_READ: Mode = libc::S_IRUSR as Mode;
|
||||
pub const USER_WRITE: Mode = libc::S_IWUSR as Mode;
|
||||
pub const USER_EXECUTE: Mode = libc::S_IXUSR as Mode;
|
||||
pub const GROUP_READ: Mode = libc::S_IRGRP as Mode;
|
||||
pub const GROUP_WRITE: Mode = libc::S_IWGRP as Mode;
|
||||
pub const GROUP_EXECUTE: Mode = libc::S_IXGRP as Mode;
|
||||
pub const OTHER_READ: Mode = libc::S_IROTH as Mode;
|
||||
pub const OTHER_WRITE: Mode = libc::S_IWOTH as Mode;
|
||||
pub const OTHER_EXECUTE: Mode = libc::S_IXOTH as Mode;
|
||||
}
|
||||
|
||||
|
||||
@ -150,6 +137,27 @@ impl<'dir> File<'dir> {
|
||||
self.metadata.file_type().is_symlink()
|
||||
}
|
||||
|
||||
/// Whether this file is a named pipe on the filesystem.
|
||||
pub fn is_pipe(&self) -> bool {
|
||||
self.metadata.file_type().is_fifo()
|
||||
}
|
||||
|
||||
/// Whether this file is a char device on the filesystem.
|
||||
pub fn is_char_device(&self) -> bool {
|
||||
self.metadata.file_type().is_char_device()
|
||||
}
|
||||
|
||||
/// Whether this file is a block device on the filesystem.
|
||||
pub fn is_block_device(&self) -> bool {
|
||||
self.metadata.file_type().is_block_device()
|
||||
}
|
||||
|
||||
/// Whether this file is a socket on the filesystem.
|
||||
pub fn is_socket(&self) -> bool {
|
||||
self.metadata.file_type().is_socket()
|
||||
}
|
||||
|
||||
|
||||
/// Whether this file is a dotfile, based on its name. In Unix, file names
|
||||
/// beginning with a dot represent system or configuration files, and
|
||||
/// should be hidden by default.
|
||||
@ -344,6 +352,8 @@ impl<'dir> File<'dir> {
|
||||
/// directory, so will not work if this file has just been passed in on
|
||||
/// the command line.
|
||||
pub fn git_status(&self) -> f::Git {
|
||||
use std::env::current_dir;
|
||||
|
||||
match self.dir {
|
||||
None => f::Git { staged: f::GitStatus::NotModified, unstaged: f::GitStatus::NotModified },
|
||||
Some(d) => {
|
||||
@ -358,52 +368,6 @@ impl<'dir> File<'dir> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
impl<'dir> File<'dir> {
|
||||
/// Whether this file is a named pipe on the filesystem.
|
||||
pub fn is_pipe(&self) -> bool {
|
||||
self.metadata.file_type().is_fifo()
|
||||
}
|
||||
|
||||
/// Whether this file is a char device on the filesystem.
|
||||
pub fn is_char_device(&self) -> bool {
|
||||
self.metadata.file_type().is_char_device()
|
||||
}
|
||||
|
||||
/// Whether this file is a block device on the filesystem.
|
||||
pub fn is_block_device(&self) -> bool {
|
||||
self.metadata.file_type().is_block_device()
|
||||
}
|
||||
|
||||
/// Whether this file is a socket on the filesystem.
|
||||
pub fn is_socket(&self) -> bool {
|
||||
self.metadata.file_type().is_socket()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||
impl<'dir> File<'dir> {
|
||||
/// Whether this file is a named pipe on the filesystem.
|
||||
pub fn is_pipe(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether this file is a char device on the filesystem.
|
||||
pub fn is_char_device(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether this file is a block device on the filesystem.
|
||||
pub fn is_block_device(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Whether this file is a socket on the filesystem.
|
||||
pub fn is_socket(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a> AsRef<File<'a>> for File<'a> {
|
||||
fn as_ref(&self) -> &File<'a> {
|
||||
@ -421,6 +385,8 @@ impl<'a> AsRef<File<'a>> for File<'a> {
|
||||
/// against a pre-compiled list of extensions which are known to only exist
|
||||
/// within ASCII, so it's alright.
|
||||
fn ext(path: &Path) -> Option<String> {
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
let name = match path.file_name() {
|
||||
Some(f) => f.to_string_lossy().to_string(),
|
||||
None => return None,
|
||||
@ -441,11 +407,24 @@ pub enum FileTarget<'dir> {
|
||||
Broken(PathBuf),
|
||||
|
||||
/// There was an IO error when following the link. This can happen if the
|
||||
/// file isn't a link to begin with, but also if, say, we don't have
|
||||
/// file isn’t a link to begin with, but also if, say, we don’t have
|
||||
/// permission to follow it.
|
||||
Err(IOError),
|
||||
}
|
||||
|
||||
impl<'dir> FileTarget<'dir> {
|
||||
|
||||
/// Whether this link doesn’t lead to a file, for whatever reason. This
|
||||
/// gets used to determine how to highlight the link in grid views.
|
||||
pub fn is_broken(&self) -> bool {
|
||||
match self {
|
||||
&FileTarget::Ok(_) => false,
|
||||
&FileTarget::Broken(_) => true,
|
||||
&FileTarget::Err(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -1,44 +1,46 @@
|
||||
|
||||
pub static OPTIONS: &'static str = r##"
|
||||
-?, --help show list of command-line options
|
||||
-v, --version show version of exa
|
||||
|
||||
DISPLAY OPTIONS
|
||||
-1, --oneline display one entry per line
|
||||
-G, --grid display entries in a grid view (default)
|
||||
-l, --long display extended details and attributes
|
||||
-l, --long display extended file metadata as a table
|
||||
-G, --grid display entries as a grid (default)
|
||||
-x, --across sort the grid across, rather than downwards
|
||||
-R, --recurse recurse into directories
|
||||
-T, --tree recurse into subdirectories in a tree view
|
||||
-x, --across sort multi-column view entries across
|
||||
-F, --classify show file type indicator (one of */=@|)
|
||||
|
||||
--color=WHEN, --colour=WHEN when to colourise the output (always, auto, never)
|
||||
--color-scale, --colour-scale colour file sizes according to their magnitude
|
||||
-T, --tree recurse into directories as a tree
|
||||
-F, --classify display type indicator by file names
|
||||
--colo[u]r=WHEN when to use terminal colours (always, auto, never)
|
||||
--colo[u]r-scale highlight levels of file sizes distinctly
|
||||
|
||||
FILTERING AND SORTING OPTIONS
|
||||
-a, --all show dot-files
|
||||
-d, --list-dirs list directories as regular files
|
||||
-r, --reverse reverse order of files
|
||||
-s, --sort SORT_FIELD field to sort by. Choices: name,
|
||||
size, extension, modified,
|
||||
accessed, created, inode, none
|
||||
-a, --all don't hide hidden and 'dot' files
|
||||
-d, --list-dirs list directories like regular files
|
||||
-r, --reverse reverse the sort order
|
||||
-s, --sort SORT_FIELD which field to sort by:
|
||||
--group-directories-first list directories before other files
|
||||
-I, --ignore-glob GLOBS glob patterns (pipe-separated) of files to ignore
|
||||
Valid sort fields: name, Name, extension, Extension, size,
|
||||
modified, accessed, created, inode, none
|
||||
|
||||
"##;
|
||||
|
||||
pub static LONG_OPTIONS: &'static str = r##"
|
||||
LONG VIEW OPTIONS
|
||||
-b, --binary use binary prefixes in file sizes
|
||||
-B, --bytes list file sizes in bytes, without prefixes
|
||||
-g, --group show group as well as user
|
||||
-h, --header show a header row at the top
|
||||
-H, --links show number of hard links
|
||||
-i, --inode show each file's inode number
|
||||
-L, --level DEPTH maximum depth of recursion
|
||||
-m, --modified display timestamp of most recent modification
|
||||
-b, --binary list file sizes with binary prefixes
|
||||
-B, --bytes list file sizes in bytes, without any prefixes
|
||||
-g, --group list each file's group
|
||||
-h, --header add a header row to each column
|
||||
-H, --links list each file's number of hard links
|
||||
-i, --inode list each file's inode number
|
||||
-L, --level DEPTH limit the depth of recursion
|
||||
-m, --modified use the modified timestamp field
|
||||
-S, --blocks show number of file system blocks
|
||||
-t, --time FIELD which timestamp to show for a file. Choices:
|
||||
modified, accessed, created
|
||||
-u, --accessed display timestamp of last access for a file
|
||||
-U, --created display timestamp of creation for a file
|
||||
-t, --time FIELD which timestamp field to list (modified, accessed, created)
|
||||
-u, --accessed use the accessed timestamp field
|
||||
-U, --created use the created timestamp field
|
||||
"##;
|
||||
|
||||
pub static GIT_HELP: &'static str = r##" --git show git status for files"##;
|
||||
pub static EXTENDED_HELP: &'static str = r##" -@, --extended display extended attribute keys and sizes"##;
|
||||
pub static GIT_HELP: &'static str = r##" --git list each file's Git status, if tracked"##;
|
||||
pub static EXTENDED_HELP: &'static str = r##" -@, --extended list each file's extended attributes and sizes"##;
|
||||
|
@ -45,50 +45,50 @@ impl Options {
|
||||
where S: AsRef<OsStr> {
|
||||
let mut opts = getopts::Options::new();
|
||||
|
||||
opts.optflag("v", "version", "display version of exa");
|
||||
opts.optflag("v", "version", "show version of exa");
|
||||
opts.optflag("?", "help", "show list of command-line options");
|
||||
|
||||
// Display options
|
||||
opts.optflag("1", "oneline", "display one entry per line");
|
||||
opts.optflag("G", "grid", "display entries in a grid view (default)");
|
||||
opts.optflag("l", "long", "display extended details and attributes");
|
||||
opts.optflag("l", "long", "display extended file metadata in a table");
|
||||
opts.optflag("G", "grid", "display entries as a grid (default)");
|
||||
opts.optflag("x", "across", "sort the grid across, rather than downwards");
|
||||
opts.optflag("R", "recurse", "recurse into directories");
|
||||
opts.optflag("T", "tree", "recurse into subdirectories in a tree view");
|
||||
opts.optflag("x", "across", "sort multi-column view entries across");
|
||||
opts.optflag("F", "classify", "show file type indicator (one of */=@|)");
|
||||
opts.optopt ("", "color", "when to show anything in colours", "WHEN");
|
||||
opts.optopt ("", "colour", "when to show anything in colours (alternate spelling)", "WHEN");
|
||||
opts.optflag("", "color-scale", "use a colour scale when displaying file sizes (alternate spelling)");
|
||||
opts.optflag("", "colour-scale", "use a colour scale when displaying file sizes");
|
||||
opts.optflag("T", "tree", "recurse into directories as a tree");
|
||||
opts.optflag("F", "classify", "display type indicator by file names (one of */=@|)");
|
||||
opts.optopt ("", "color", "when to use terminal colours", "WHEN");
|
||||
opts.optopt ("", "colour", "when to use terminal colours", "WHEN");
|
||||
opts.optflag("", "color-scale", "highlight levels of file sizes distinctly");
|
||||
opts.optflag("", "colour-scale", "highlight levels of file sizes distinctly");
|
||||
|
||||
// Filtering and sorting options
|
||||
opts.optflag("", "group-directories-first", "list directories before other files");
|
||||
opts.optflag("a", "all", "show dot-files");
|
||||
opts.optflag("d", "list-dirs", "list directories as regular files");
|
||||
opts.optflag("r", "reverse", "reverse order of files");
|
||||
opts.optopt ("s", "sort", "field to sort by", "WORD");
|
||||
opts.optopt ("I", "ignore-glob", "patterns (|-separated) of names to ignore", "GLOBS");
|
||||
opts.optflag("", "group-directories-first", "sort directories before other files");
|
||||
opts.optflag("a", "all", "don't hide hidden and 'dot' files");
|
||||
opts.optflag("d", "list-dirs", "list directories like regular files");
|
||||
opts.optopt ("L", "level", "limit the depth of recursion", "DEPTH");
|
||||
opts.optflag("r", "reverse", "reverse the sert order");
|
||||
opts.optopt ("s", "sort", "which field to sort by", "WORD");
|
||||
opts.optopt ("I", "ignore-glob", "ignore files that match these glob patterns", "GLOB1|GLOB2...");
|
||||
|
||||
// Long view options
|
||||
opts.optflag("b", "binary", "use binary prefixes in file sizes");
|
||||
opts.optflag("b", "binary", "list file sizes with binary prefixes");
|
||||
opts.optflag("B", "bytes", "list file sizes in bytes, without prefixes");
|
||||
opts.optflag("g", "group", "show group as well as user");
|
||||
opts.optflag("h", "header", "show a header row at the top");
|
||||
opts.optflag("H", "links", "show number of hard links");
|
||||
opts.optflag("i", "inode", "show each file's inode number");
|
||||
opts.optopt ("L", "level", "maximum depth of recursion", "DEPTH");
|
||||
opts.optflag("m", "modified", "display timestamp of most recent modification");
|
||||
opts.optflag("S", "blocks", "show number of file system blocks");
|
||||
opts.optopt ("t", "time", "which timestamp to show for a file", "WORD");
|
||||
opts.optflag("u", "accessed", "display timestamp of last access for a file");
|
||||
opts.optflag("U", "created", "display timestamp of creation for a file");
|
||||
opts.optflag("g", "group", "list each file's group");
|
||||
opts.optflag("h", "header", "add a header row to each column");
|
||||
opts.optflag("H", "links", "list each file's number of hard links");
|
||||
opts.optflag("i", "inode", "list each file's inode number");
|
||||
opts.optflag("m", "modified", "use the modified timestamp field");
|
||||
opts.optflag("S", "blocks", "list each file's number of file system blocks");
|
||||
opts.optopt ("t", "time", "which timestamp field to show", "WORD");
|
||||
opts.optflag("u", "accessed", "use the accessed timestamp field");
|
||||
opts.optflag("U", "created", "use the created timestamp field");
|
||||
|
||||
if cfg!(feature="git") {
|
||||
opts.optflag("", "git", "show git status");
|
||||
opts.optflag("", "git", "list each file's git status");
|
||||
}
|
||||
|
||||
if xattr::ENABLED {
|
||||
opts.optflag("@", "extended", "display extended attribute keys and sizes");
|
||||
opts.optflag("@", "extended", "list each file's extended attribute keys and sizes");
|
||||
}
|
||||
|
||||
let matches = match opts.parse(args) {
|
||||
|
@ -4,8 +4,9 @@ use getopts;
|
||||
|
||||
use output::Colours;
|
||||
use output::{Grid, Details, GridDetails, Lines};
|
||||
use options::{FileFilter, DirAction, Misfire};
|
||||
use output::column::{Columns, TimeTypes, SizeFormat};
|
||||
use output::file_name::Classify;
|
||||
use options::{FileFilter, DirAction, Misfire};
|
||||
use term::dimensions;
|
||||
use fs::feature::xattr;
|
||||
|
||||
@ -58,7 +59,7 @@ impl View {
|
||||
filter: filter.clone(),
|
||||
xattr: xattr::ENABLED && matches.opt_present("extended"),
|
||||
colours: colours,
|
||||
classify: matches.opt_present("classify"),
|
||||
classify: Classify::deduce(matches),
|
||||
};
|
||||
|
||||
Ok(details)
|
||||
@ -87,8 +88,7 @@ impl View {
|
||||
};
|
||||
|
||||
let other_options_scan = || {
|
||||
let classify = matches.opt_present("classify");
|
||||
|
||||
let classify = Classify::deduce(matches);
|
||||
let term_colours = TerminalColours::deduce(matches)?;
|
||||
let term_width = TerminalWidth::deduce()?;
|
||||
|
||||
@ -366,3 +366,12 @@ impl TerminalColours {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl Classify {
|
||||
fn deduce(matches: &getopts::Matches) -> Classify {
|
||||
if matches.opt_present("classify") { Classify::AddFileIndicators }
|
||||
else { Classify::JustFilenames }
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ use std::ops::{Add, Deref, DerefMut};
|
||||
use ansi_term::{Style, ANSIString, ANSIStrings};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use fs::File;
|
||||
|
||||
|
||||
/// An individual cell that holds text in a table, used in the details and
|
||||
/// lines views to store ANSI-terminal-formatted data before it is printed.
|
||||
@ -161,6 +159,22 @@ impl TextCellContents {
|
||||
pub fn strings(&self) -> ANSIStrings {
|
||||
ANSIStrings(&self.0)
|
||||
}
|
||||
|
||||
/// Calculates the width that a cell with these contents would take up, by
|
||||
/// counting the number of characters in each unformatted ANSI string.
|
||||
pub fn width(&self) -> DisplayWidth {
|
||||
let foo = self.0.iter().map(|anstr| anstr.chars().count()).sum();
|
||||
DisplayWidth(foo)
|
||||
}
|
||||
|
||||
/// Promotes these contents to a full cell containing them alongside
|
||||
/// their calculated width.
|
||||
pub fn promote(self) -> TextCell {
|
||||
TextCell {
|
||||
width: self.width(),
|
||||
contents: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -180,19 +194,6 @@ impl TextCellContents {
|
||||
#[derive(PartialEq, Debug, Clone, Copy, Default)]
|
||||
pub struct DisplayWidth(usize);
|
||||
|
||||
impl DisplayWidth {
|
||||
pub fn from_file(file: &File, classify: bool) -> DisplayWidth {
|
||||
let name_width = *DisplayWidth::from(&*file.name);
|
||||
if classify {
|
||||
if file.is_executable_file() || file.is_directory() ||
|
||||
file.is_pipe() || file.is_link() || file.is_socket() {
|
||||
return DisplayWidth(name_width + 1);
|
||||
}
|
||||
}
|
||||
DisplayWidth(name_width)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for DisplayWidth {
|
||||
fn from(input: &'a str) -> DisplayWidth {
|
||||
DisplayWidth(UnicodeWidthStr::width(input))
|
||||
|
@ -22,6 +22,7 @@ pub struct Colours {
|
||||
pub symlink_path: Style,
|
||||
pub broken_arrow: Style,
|
||||
pub broken_filename: Style,
|
||||
pub control_char: Style,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
@ -170,7 +171,8 @@ impl Colours {
|
||||
|
||||
symlink_path: Cyan.normal(),
|
||||
broken_arrow: Red.normal(),
|
||||
broken_filename: Red.underline()
|
||||
broken_filename: Red.underline(),
|
||||
control_char: Red.normal(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,9 +99,9 @@ use fs::feature::xattr::{Attribute, FileAttributes};
|
||||
use options::{FileFilter, RecurseOptions};
|
||||
use output::colours::Colours;
|
||||
use output::column::{Alignment, Column, Columns, SizeFormat};
|
||||
use output::cell::{TextCell, DisplayWidth};
|
||||
use output::cell::{TextCell, TextCellContents, DisplayWidth};
|
||||
use output::tree::TreeTrunk;
|
||||
use super::filename;
|
||||
use output::file_name::{FileName, LinkStyle, Classify};
|
||||
|
||||
|
||||
/// With the **Details** view, the output gets formatted into columns, with
|
||||
@ -142,7 +142,7 @@ pub struct Details {
|
||||
pub colours: Colours,
|
||||
|
||||
/// Whether to show a file type indiccator.
|
||||
pub classify: bool,
|
||||
pub classify: Classify,
|
||||
}
|
||||
|
||||
/// The **environment** struct contains any data that could change between
|
||||
@ -306,23 +306,11 @@ impl Details {
|
||||
for (index, egg) in file_eggs.into_iter().enumerate() {
|
||||
let mut files = Vec::new();
|
||||
let mut errors = egg.errors;
|
||||
let mut width = DisplayWidth::from_file(&egg.file, self.classify);
|
||||
|
||||
if egg.file.dir.is_none() {
|
||||
if let Some(parent) = egg.file.path.parent() {
|
||||
width = width + 1 + DisplayWidth::from(parent.to_string_lossy().as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
let name = TextCell {
|
||||
contents: filename(&egg.file, &self.colours, true, self.classify),
|
||||
width: width,
|
||||
};
|
||||
|
||||
let row = Row {
|
||||
depth: depth,
|
||||
cells: Some(egg.cells),
|
||||
name: name,
|
||||
name: FileName::new(&egg.file, LinkStyle::FullLinkPaths, self.classify, &self.colours).paint().promote(),
|
||||
last: index == num_eggs - 1,
|
||||
};
|
||||
|
||||
@ -455,19 +443,8 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
|
||||
self.rows.push(row);
|
||||
}
|
||||
|
||||
pub fn filename_cell(&self, file: File, links: bool) -> TextCell {
|
||||
let mut width = DisplayWidth::from_file(&file, self.opts.classify);
|
||||
|
||||
if file.dir.is_none() {
|
||||
if let Some(parent) = file.path.parent() {
|
||||
width = width + 1 + DisplayWidth::from(parent.to_string_lossy().as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
TextCell {
|
||||
contents: filename(&file, &self.opts.colours, links, self.opts.classify),
|
||||
width: width,
|
||||
}
|
||||
pub fn filename(&self, file: File, links: LinkStyle) -> TextCellContents {
|
||||
FileName::new(&file, links, self.opts.classify, &self.opts.colours).paint()
|
||||
}
|
||||
|
||||
pub fn add_file_with_cells(&mut self, cells: Vec<TextCell>, name_cell: TextCell, depth: usize, last: bool) {
|
||||
|
25
src/output/escape.rs
Normal file
25
src/output/escape.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use ansi_term::{ANSIString, Style};
|
||||
|
||||
|
||||
pub fn escape<'a>(string: String, bits: &mut Vec<ANSIString<'a>>, good: Style, bad: Style) {
|
||||
if string.chars().all(|c| c >= 0x20 as char) {
|
||||
bits.push(good.paint(string));
|
||||
}
|
||||
else {
|
||||
for c in string.chars() {
|
||||
// The `escape_default` method on `char` is *almost* what we want here, but
|
||||
// it still escapes non-ASCII UTF-8 characters, which are still printable.
|
||||
|
||||
if c >= 0x20 as char {
|
||||
// TODO: This allocates way too much,
|
||||
// hence the `all` check above.
|
||||
let mut s = String::new();
|
||||
s.push(c);
|
||||
bits.push(good.paint(s));
|
||||
} else {
|
||||
let s = c.escape_default().collect::<String>();
|
||||
bits.push(bad.paint(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
238
src/output/file_name.rs
Normal file
238
src/output/file_name.rs
Normal file
@ -0,0 +1,238 @@
|
||||
use std::path::Path;
|
||||
|
||||
use ansi_term::{ANSIString, Style};
|
||||
|
||||
use fs::{File, FileTarget};
|
||||
use output::Colours;
|
||||
use output::escape;
|
||||
use output::cell::TextCellContents;
|
||||
|
||||
|
||||
/// A **file name** holds all the information necessary to display the name
|
||||
/// of the given file. This is used in all of the views.
|
||||
pub struct FileName<'a, 'dir: 'a> {
|
||||
|
||||
/// A reference to the file that we're getting the name of.
|
||||
file: &'a File<'dir>,
|
||||
|
||||
/// The colours used to paint the file name and its surrounding text.
|
||||
colours: &'a Colours,
|
||||
|
||||
/// The file that this file points to if it's a link.
|
||||
target: Option<FileTarget<'dir>>,
|
||||
|
||||
/// How to handle displaying links.
|
||||
link_style: LinkStyle,
|
||||
|
||||
/// Whether to append file class characters to file names.
|
||||
classify: Classify,
|
||||
}
|
||||
|
||||
|
||||
impl<'a, 'dir> FileName<'a, 'dir> {
|
||||
|
||||
/// Create a new `FileName` that prints the given file’s name, painting it
|
||||
/// with the remaining arguments.
|
||||
pub fn new(file: &'a File<'dir>, link_style: LinkStyle, classify: Classify, colours: &'a Colours) -> FileName<'a, 'dir> {
|
||||
let target = if file.is_link() { Some(file.link_target()) }
|
||||
else { None };
|
||||
FileName {
|
||||
file: file,
|
||||
colours: colours,
|
||||
target: target,
|
||||
link_style: link_style,
|
||||
classify: classify,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Paints the name of the file using the colours, resulting in a vector
|
||||
/// of coloured cells that can be printed to the terminal.
|
||||
///
|
||||
/// This method returns some `TextCellContents`, rather than a `TextCell`,
|
||||
/// because for the last cell in a table, it doesn’t need to have its
|
||||
/// width calculated.
|
||||
pub fn paint(&self) -> TextCellContents {
|
||||
let mut bits = Vec::new();
|
||||
|
||||
if self.file.dir.is_none() {
|
||||
if let Some(parent) = self.file.path.parent() {
|
||||
self.add_parent_bits(&mut bits, parent);
|
||||
}
|
||||
}
|
||||
|
||||
if !self.file.name.is_empty() {
|
||||
for bit in self.coloured_file_name() {
|
||||
bits.push(bit);
|
||||
}
|
||||
}
|
||||
|
||||
if let (LinkStyle::FullLinkPaths, Some(ref target)) = (self.link_style, self.target.as_ref()) {
|
||||
match **target {
|
||||
FileTarget::Ok(ref target) => {
|
||||
bits.push(Style::default().paint(" "));
|
||||
bits.push(self.colours.punctuation.paint("->"));
|
||||
bits.push(Style::default().paint(" "));
|
||||
|
||||
if let Some(parent) = target.path.parent() {
|
||||
self.add_parent_bits(&mut bits, parent);
|
||||
}
|
||||
|
||||
if !target.name.is_empty() {
|
||||
let target = FileName::new(&target, LinkStyle::FullLinkPaths, Classify::JustFilenames, self.colours);
|
||||
for bit in target.coloured_file_name() {
|
||||
bits.push(bit);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
FileTarget::Broken(ref broken_path) => {
|
||||
bits.push(Style::default().paint(" "));
|
||||
bits.push(self.colours.broken_arrow.paint("->"));
|
||||
bits.push(Style::default().paint(" "));
|
||||
escape(broken_path.display().to_string(), &mut bits, self.colours.broken_filename, self.colours.control_char.underline());
|
||||
},
|
||||
|
||||
FileTarget::Err(_) => {
|
||||
// Do nothing -- the error gets displayed on the next line
|
||||
},
|
||||
}
|
||||
}
|
||||
else if let Classify::AddFileIndicators = self.classify {
|
||||
if let Some(class) = self.classify_char() {
|
||||
bits.push(Style::default().paint(class));
|
||||
}
|
||||
}
|
||||
|
||||
bits.into()
|
||||
}
|
||||
|
||||
|
||||
/// Adds the bits of the parent path to the given bits vector.
|
||||
/// The path gets its characters escaped based on the colours.
|
||||
fn add_parent_bits(&self, bits: &mut Vec<ANSIString>, parent: &Path) {
|
||||
let coconut = parent.components().count();
|
||||
|
||||
if coconut == 1 && parent.has_root() {
|
||||
bits.push(self.colours.symlink_path.paint("/"));
|
||||
}
|
||||
else if coconut >= 1 {
|
||||
escape(parent.to_string_lossy().to_string(), bits, self.colours.symlink_path, self.colours.control_char);
|
||||
bits.push(self.colours.symlink_path.paint("/"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The character to be displayed after a file when classifying is on, if
|
||||
/// the file’s type has one associated with it.
|
||||
fn classify_char(&self) -> Option<&'static str> {
|
||||
if self.file.is_executable_file() {
|
||||
Some("*")
|
||||
} else if self.file.is_directory() {
|
||||
Some("/")
|
||||
} else if self.file.is_pipe() {
|
||||
Some("|")
|
||||
} else if self.file.is_link() {
|
||||
Some("@")
|
||||
} else if self.file.is_socket() {
|
||||
Some("=")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Returns at least one ANSI-highlighted string representing this file’s
|
||||
/// name using the given set of colours.
|
||||
///
|
||||
/// Ordinarily, this will be just one string: the file’s complete name,
|
||||
/// coloured according to its file type. If the name contains control
|
||||
/// characters such as newlines or escapes, though, we can’t just print them
|
||||
/// to the screen directly, because then there’ll be newlines in weird places.
|
||||
///
|
||||
/// So in that situation, those characters will be escaped and highlighted in
|
||||
/// a different colour.
|
||||
fn coloured_file_name<'unused>(&self) -> Vec<ANSIString<'unused>> {
|
||||
let file_style = self.style();
|
||||
let mut bits = Vec::new();
|
||||
escape(self.file.name.clone(), &mut bits, file_style, self.colours.control_char);
|
||||
bits
|
||||
}
|
||||
|
||||
|
||||
/// Figures out which colour to paint the filename part of the output,
|
||||
/// depending on which “type” of file it appears to be -- either from the
|
||||
/// class on the filesystem or from its name.
|
||||
pub fn style(&self) -> Style {
|
||||
|
||||
// Override the style with the “broken link” style when this file is
|
||||
// a link that we can’t follow for whatever reason. This is used when
|
||||
// there’s no other place to show that the link doesn’t work.
|
||||
if let LinkStyle::JustFilenames = self.link_style {
|
||||
if let Some(ref target) = self.target {
|
||||
if target.is_broken() {
|
||||
return self.colours.broken_arrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, just apply a bunch of rules in order. For example,
|
||||
// executable image files should be executable rather than images.
|
||||
match self.file {
|
||||
f if f.is_directory() => self.colours.filetypes.directory,
|
||||
f if f.is_executable_file() => self.colours.filetypes.executable,
|
||||
f if f.is_link() => self.colours.filetypes.symlink,
|
||||
f if f.is_pipe() => self.colours.filetypes.pipe,
|
||||
f if f.is_char_device()
|
||||
| f.is_block_device() => self.colours.filetypes.device,
|
||||
f if f.is_socket() => self.colours.filetypes.socket,
|
||||
f if !f.is_file() => self.colours.filetypes.special,
|
||||
f if f.is_immediate() => self.colours.filetypes.immediate,
|
||||
f if f.is_image() => self.colours.filetypes.image,
|
||||
f if f.is_video() => self.colours.filetypes.video,
|
||||
f if f.is_music() => self.colours.filetypes.music,
|
||||
f if f.is_lossless() => self.colours.filetypes.lossless,
|
||||
f if f.is_crypto() => self.colours.filetypes.crypto,
|
||||
f if f.is_document() => self.colours.filetypes.document,
|
||||
f if f.is_compressed() => self.colours.filetypes.compressed,
|
||||
f if f.is_temp() => self.colours.filetypes.temp,
|
||||
f if f.is_compiled() => self.colours.filetypes.compiled,
|
||||
_ => self.colours.filetypes.normal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// When displaying a file name, there needs to be some way to handle broken
|
||||
/// links, depending on how long the resulting Cell can be.
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub enum LinkStyle {
|
||||
|
||||
/// Just display the file names, but colour them differently if they’re
|
||||
/// a broken link or can’t be followed.
|
||||
JustFilenames,
|
||||
|
||||
/// Display all files in their usual style, but follow each link with an
|
||||
/// arrow pointing to their path, colouring the path differently if it’s
|
||||
/// a broken link, and doing nothing if it can’t be followed.
|
||||
FullLinkPaths,
|
||||
}
|
||||
|
||||
|
||||
/// Whether to append file class characters to the file names.
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
pub enum Classify {
|
||||
|
||||
/// Just display the file names, without any characters.
|
||||
JustFilenames,
|
||||
|
||||
/// Add a character after the file name depending on what class of file
|
||||
/// it is.
|
||||
AddFileIndicators,
|
||||
}
|
||||
|
||||
impl Default for Classify {
|
||||
fn default() -> Classify {
|
||||
Classify::JustFilenames
|
||||
}
|
||||
}
|
@ -3,9 +3,8 @@ use std::io::{Write, Result as IOResult};
|
||||
use term_grid as grid;
|
||||
|
||||
use fs::File;
|
||||
use output::DisplayWidth;
|
||||
use output::colours::Colours;
|
||||
use super::filename;
|
||||
use output::file_name::{FileName, LinkStyle, Classify};
|
||||
|
||||
|
||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||
@ -13,7 +12,7 @@ pub struct Grid {
|
||||
pub across: bool,
|
||||
pub console_width: usize,
|
||||
pub colours: Colours,
|
||||
pub classify: bool,
|
||||
pub classify: Classify,
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
@ -29,16 +28,11 @@ impl Grid {
|
||||
grid.reserve(files.len());
|
||||
|
||||
for file in files.iter() {
|
||||
let mut width = DisplayWidth::from_file(file, self.classify);
|
||||
|
||||
if file.dir.is_none() {
|
||||
if let Some(parent) = file.path.parent() {
|
||||
width = width + 1 + DisplayWidth::from(parent.to_string_lossy().as_ref());
|
||||
}
|
||||
}
|
||||
let filename = FileName::new(file, LinkStyle::JustFilenames, self.classify, &self.colours).paint();
|
||||
let width = filename.width();
|
||||
|
||||
grid.add(grid::Cell {
|
||||
contents: filename(file, &self.colours, false, self.classify).strings().to_string(),
|
||||
contents: filename.strings().to_string(),
|
||||
width: *width,
|
||||
});
|
||||
}
|
||||
@ -49,7 +43,8 @@ impl Grid {
|
||||
else {
|
||||
// File names too long for a grid - drop down to just listing them!
|
||||
for file in files.iter() {
|
||||
writeln!(w, "{}", filename(file, &self.colours, false, self.classify).strings())?;
|
||||
let name_cell = FileName::new(file, LinkStyle::JustFilenames, self.classify, &self.colours).paint();
|
||||
writeln!(w, "{}", name_cell.strings())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ use output::cell::TextCell;
|
||||
use output::column::Column;
|
||||
use output::details::{Details, Table, Environment};
|
||||
use output::grid::Grid;
|
||||
use output::file_name::LinkStyle;
|
||||
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct GridDetails {
|
||||
@ -45,7 +47,7 @@ impl GridDetails {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let file_names = files.into_iter()
|
||||
.map(|file| first_table.filename_cell(file, false))
|
||||
.map(|file| first_table.filename(file, LinkStyle::JustFilenames).promote())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(cells, file_names)
|
||||
|
@ -4,21 +4,22 @@ use ansi_term::ANSIStrings;
|
||||
|
||||
use fs::File;
|
||||
|
||||
use super::filename;
|
||||
use output::file_name::{FileName, LinkStyle, Classify};
|
||||
use super::colours::Colours;
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Lines {
|
||||
pub colours: Colours,
|
||||
pub classify: bool,
|
||||
pub classify: Classify,
|
||||
}
|
||||
|
||||
/// The lines view literally just displays each file, line-by-line.
|
||||
impl Lines {
|
||||
pub fn view<W: Write>(&self, files: Vec<File>, w: &mut W) -> IOResult<()> {
|
||||
for file in files {
|
||||
writeln!(w, "{}", ANSIStrings(&filename(&file, &self.colours, true, self.classify)))?;
|
||||
let name_cell = FileName::new(&file, LinkStyle::FullLinkPaths, self.classify, &self.colours).paint();
|
||||
writeln!(w, "{}", ANSIStrings(&name_cell))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
use ansi_term::Style;
|
||||
|
||||
use fs::{File, FileTarget};
|
||||
|
||||
pub use self::cell::{TextCell, TextCellContents, DisplayWidth};
|
||||
pub use self::colours::Colours;
|
||||
pub use self::details::Details;
|
||||
pub use self::grid_details::GridDetails;
|
||||
pub use self::grid::Grid;
|
||||
pub use self::lines::Lines;
|
||||
pub use self::escape::escape;
|
||||
|
||||
mod grid;
|
||||
pub mod details;
|
||||
@ -17,101 +14,5 @@ pub mod column;
|
||||
mod cell;
|
||||
mod colours;
|
||||
mod tree;
|
||||
|
||||
|
||||
pub fn filename(file: &File, colours: &Colours, links: bool, classify: bool) -> TextCellContents {
|
||||
let mut bits = Vec::new();
|
||||
|
||||
if file.dir.is_none() {
|
||||
if let Some(parent) = file.path.parent() {
|
||||
let coconut = parent.components().count();
|
||||
|
||||
if coconut == 1 && parent.has_root() {
|
||||
bits.push(colours.symlink_path.paint("/"));
|
||||
}
|
||||
else if coconut >= 1 {
|
||||
bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string()));
|
||||
bits.push(colours.symlink_path.paint("/"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !file.name.is_empty() {
|
||||
bits.push(file_colour(colours, file).paint(file.name.clone()));
|
||||
}
|
||||
|
||||
if links && file.is_link() {
|
||||
match file.link_target() {
|
||||
FileTarget::Ok(target) => {
|
||||
bits.push(Style::default().paint(" "));
|
||||
bits.push(colours.punctuation.paint("->"));
|
||||
bits.push(Style::default().paint(" "));
|
||||
|
||||
if let Some(parent) = target.path.parent() {
|
||||
let coconut = parent.components().count();
|
||||
|
||||
if coconut == 1 && parent.has_root() {
|
||||
bits.push(colours.symlink_path.paint("/"));
|
||||
}
|
||||
else if coconut >= 1 {
|
||||
bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string()));
|
||||
bits.push(colours.symlink_path.paint("/"));
|
||||
}
|
||||
}
|
||||
|
||||
if !target.name.is_empty() {
|
||||
bits.push(file_colour(colours, &target).paint(target.name));
|
||||
}
|
||||
},
|
||||
|
||||
FileTarget::Broken(broken_path) => {
|
||||
bits.push(Style::default().paint(" "));
|
||||
bits.push(colours.broken_arrow.paint("->"));
|
||||
bits.push(Style::default().paint(" "));
|
||||
bits.push(colours.broken_filename.paint(broken_path.display().to_string()));
|
||||
},
|
||||
|
||||
FileTarget::Err(_) => {
|
||||
// Do nothing -- the error gets displayed on the next line
|
||||
}
|
||||
}
|
||||
} else if classify {
|
||||
if file.is_executable_file() {
|
||||
bits.push(Style::default().paint("*"));
|
||||
} else if file.is_directory() {
|
||||
bits.push(Style::default().paint("/"));
|
||||
} else if file.is_pipe() {
|
||||
bits.push(Style::default().paint("|"));
|
||||
} else if file.is_link() {
|
||||
bits.push(Style::default().paint("@"));
|
||||
} else if file.is_socket() {
|
||||
bits.push(Style::default().paint("="));
|
||||
}
|
||||
}
|
||||
|
||||
bits.into()
|
||||
}
|
||||
|
||||
pub fn file_colour(colours: &Colours, file: &File) -> Style {
|
||||
match file {
|
||||
f if f.is_directory() => colours.filetypes.directory,
|
||||
f if f.is_executable_file() => colours.filetypes.executable,
|
||||
f if f.is_link() => colours.filetypes.symlink,
|
||||
f if f.is_pipe() => colours.filetypes.pipe,
|
||||
f if f.is_char_device()
|
||||
| f.is_block_device() => colours.filetypes.device,
|
||||
f if f.is_socket() => colours.filetypes.socket,
|
||||
f if !f.is_file() => colours.filetypes.special,
|
||||
f if f.is_immediate() => colours.filetypes.immediate,
|
||||
f if f.is_image() => colours.filetypes.image,
|
||||
f if f.is_video() => colours.filetypes.video,
|
||||
f if f.is_music() => colours.filetypes.music,
|
||||
f if f.is_lossless() => colours.filetypes.lossless,
|
||||
f if f.is_crypto() => colours.filetypes.crypto,
|
||||
f if f.is_document() => colours.filetypes.document,
|
||||
f if f.is_compressed() => colours.filetypes.compressed,
|
||||
f if f.is_temp() => colours.filetypes.temp,
|
||||
f if f.is_compiled() => colours.filetypes.compiled,
|
||||
_ => colours.filetypes.normal,
|
||||
}
|
||||
}
|
||||
pub mod file_name;
|
||||
mod escape;
|
||||
|
6
xtests/file_names
Normal file
6
xtests/file_names
Normal file
@ -0,0 +1,6 @@
|
||||
ansi: [[31m\u{1b}[0m[34mblue[31m\u{1b}[0m[0m] form-feed: [[31m\u{c}[0m] [1;34mnew-line-dir: [[0m[31m\n[1;34m][0m
|
||||
ascii: hello invalid-utf8-1: [<5B>] new-line: [[31m\n[0m]
|
||||
backspace: [[31m\u{8}[0m] invalid-utf8-2: [<5B>(] return: [[31m\r[0m]
|
||||
bell: [[31m\u{7}[0m] invalid-utf8-3: [<5B>(] tab: [[31m\t[0m]
|
||||
emoji: [🆒] invalid-utf8-4: [<5B>(<28>(] utf-8: pâté
|
||||
escape: [[31m\u{1b}[0m] [1;34mlinks[0m vertical-tab: [[31m\u{b}[0m]
|
18
xtests/file_names_1
Normal file
18
xtests/file_names_1
Normal file
@ -0,0 +1,18 @@
|
||||
ansi: [[31m\u{1b}[0m[34mblue[31m\u{1b}[0m[0m]
|
||||
ascii: hello
|
||||
backspace: [[31m\u{8}[0m]
|
||||
bell: [[31m\u{7}[0m]
|
||||
emoji: [🆒]
|
||||
escape: [[31m\u{1b}[0m]
|
||||
form-feed: [[31m\u{c}[0m]
|
||||
invalid-utf8-1: [<5B>]
|
||||
invalid-utf8-2: [<5B>(]
|
||||
invalid-utf8-3: [<5B>(]
|
||||
invalid-utf8-4: [<5B>(<28>(]
|
||||
[1;34mlinks[0m
|
||||
[1;34mnew-line-dir: [[0m[31m\n[1;34m][0m
|
||||
new-line: [[31m\n[0m]
|
||||
return: [[31m\r[0m]
|
||||
tab: [[31m\t[0m]
|
||||
utf-8: pâté
|
||||
vertical-tab: [[31m\u{b}[0m]
|
12
xtests/file_names_R
Normal file
12
xtests/file_names_R
Normal file
@ -0,0 +1,12 @@
|
||||
ansi: [[31m\u{1b}[0m[34mblue[31m\u{1b}[0m[0m] form-feed: [[31m\u{c}[0m] [1;34mnew-line-dir: [[0m[31m\n[1;34m][0m
|
||||
ascii: hello invalid-utf8-1: [<5B>] new-line: [[31m\n[0m]
|
||||
backspace: [[31m\u{8}[0m] invalid-utf8-2: [<5B>(] return: [[31m\r[0m]
|
||||
bell: [[31m\u{7}[0m] invalid-utf8-3: [<5B>(] tab: [[31m\t[0m]
|
||||
emoji: [🆒] invalid-utf8-4: [<5B>(<28>(] utf-8: pâté
|
||||
escape: [[31m\u{1b}[0m] [1;34mlinks[0m vertical-tab: [[31m\u{b}[0m]
|
||||
|
||||
/testcases/file-names/links:
|
||||
[36manother: [[31m\n[36m][0m [31mbroken[0m [36msubfile[0m
|
||||
|
||||
/testcases/file-names/new-line-dir: [\n]:
|
||||
another: [[31m\n[0m] subfile
|
29
xtests/file_names_T
Normal file
29
xtests/file_names_T
Normal file
@ -0,0 +1,29 @@
|
||||
[36m/testcases/[1;34mfile-names[0m
|
||||
[38;5;244m├──[0m ansi: [[31m\u{1b}[0m[34mblue[31m\u{1b}[0m[0m]
|
||||
[38;5;244m├──[0m ascii: hello
|
||||
[38;5;244m├──[0m backspace: [[31m\u{8}[0m]
|
||||
[38;5;244m├──[0m bell: [[31m\u{7}[0m]
|
||||
[38;5;244m├──[0m emoji: [🆒]
|
||||
[38;5;244m├──[0m escape: [[31m\u{1b}[0m]
|
||||
[38;5;244m├──[0m form-feed: [[31m\u{c}[0m]
|
||||
[38;5;244m├──[0m invalid-utf8-1: [<5B>]
|
||||
[38;5;244m│ └──[0m [31m<Error: path somehow contained a NUL?>[0m
|
||||
[38;5;244m├──[0m invalid-utf8-2: [<5B>(]
|
||||
[38;5;244m│ └──[0m [31m<Error: path somehow contained a NUL?>[0m
|
||||
[38;5;244m├──[0m invalid-utf8-3: [<5B>(]
|
||||
[38;5;244m│ └──[0m [31m<Error: path somehow contained a NUL?>[0m
|
||||
[38;5;244m├──[0m invalid-utf8-4: [<5B>(<28>(]
|
||||
[38;5;244m│ └──[0m [31m<Error: path somehow contained a NUL?>[0m
|
||||
[38;5;244m├──[0m [1;34mlinks[0m
|
||||
[38;5;244m│ ├──[0m [36manother: [[31m\n[36m][0m [38;5;244m->[0m [36m/testcases/file-names/new-line-dir: [[31m\n[36m]/[0manother: [[31m\n[0m]
|
||||
[38;5;244m│ ├──[0m [36mbroken[0m [31m->[0m [4;31m/testcases/file-names/new-line-dir: [\n]/broken[0m
|
||||
[38;5;244m│ │ └──[0m [31m<No such file or directory (os error 2)>[0m
|
||||
[38;5;244m│ └──[0m [36msubfile[0m [38;5;244m->[0m [36m/testcases/file-names/new-line-dir: [[31m\n[36m]/[0msubfile
|
||||
[38;5;244m├──[0m [1;34mnew-line-dir: [[0m[31m\n[1;34m][0m
|
||||
[38;5;244m│ ├──[0m another: [[31m\n[0m]
|
||||
[38;5;244m│ └──[0m subfile
|
||||
[38;5;244m├──[0m new-line: [[31m\n[0m]
|
||||
[38;5;244m├──[0m return: [[31m\r[0m]
|
||||
[38;5;244m├──[0m tab: [[31m\t[0m]
|
||||
[38;5;244m├──[0m utf-8: pâté
|
||||
[38;5;244m└──[0m vertical-tab: [[31m\u{b}[0m]
|
6
xtests/file_names_x
Normal file
6
xtests/file_names_x
Normal file
@ -0,0 +1,6 @@
|
||||
ansi: [[31m\u{1b}[0m[34mblue[31m\u{1b}[0m[0m] ascii: hello backspace: [[31m\u{8}[0m]
|
||||
bell: [[31m\u{7}[0m] emoji: [🆒] escape: [[31m\u{1b}[0m]
|
||||
form-feed: [[31m\u{c}[0m] invalid-utf8-1: [<5B>] invalid-utf8-2: [<5B>(]
|
||||
invalid-utf8-3: [<5B>(] invalid-utf8-4: [<5B>(<28>(] [1;34mlinks[0m
|
||||
[1;34mnew-line-dir: [[0m[31m\n[1;34m][0m new-line: [[31m\n[0m] return: [[31m\r[0m]
|
||||
tab: [[31m\t[0m] utf-8: pâté vertical-tab: [[31m\u{b}[0m]
|
13
xtests/files_star_100
Normal file
13
xtests/files_star_100
Normal file
@ -0,0 +1,13 @@
|
||||
[36m/testcases/files/[0m10_bytes [36m/testcases/files/[0m1_KiB [36m/testcases/files/[0m5_MiB
|
||||
[36m/testcases/files/[0m10_KiB [36m/testcases/files/[0m1_MiB [36m/testcases/files/[0m6_bytes
|
||||
[36m/testcases/files/[0m10_MiB [36m/testcases/files/[0m2_bytes [36m/testcases/files/[0m6_KiB
|
||||
[36m/testcases/files/[0m11_bytes [36m/testcases/files/[0m2_KiB [36m/testcases/files/[0m6_MiB
|
||||
[36m/testcases/files/[0m11_KiB [36m/testcases/files/[0m2_MiB [36m/testcases/files/[0m7_bytes
|
||||
[36m/testcases/files/[0m11_MiB [36m/testcases/files/[0m3_bytes [36m/testcases/files/[0m7_KiB
|
||||
[36m/testcases/files/[0m12_bytes [36m/testcases/files/[0m3_KiB [36m/testcases/files/[0m7_MiB
|
||||
[36m/testcases/files/[0m12_KiB [36m/testcases/files/[0m3_MiB [36m/testcases/files/[0m8_bytes
|
||||
[36m/testcases/files/[0m12_MiB [36m/testcases/files/[0m4_bytes [36m/testcases/files/[0m8_KiB
|
||||
[36m/testcases/files/[0m13_bytes [36m/testcases/files/[0m4_KiB [36m/testcases/files/[0m8_MiB
|
||||
[36m/testcases/files/[0m13_KiB [36m/testcases/files/[0m4_MiB [36m/testcases/files/[0m9_bytes
|
||||
[36m/testcases/files/[0m13_MiB [36m/testcases/files/[0m5_bytes [36m/testcases/files/[0m9_KiB
|
||||
[36m/testcases/files/[0m1_bytes [36m/testcases/files/[0m5_KiB [36m/testcases/files/[0m9_MiB
|
8
xtests/files_star_150
Normal file
8
xtests/files_star_150
Normal file
@ -0,0 +1,8 @@
|
||||
[36m/testcases/files/[0m10_bytes [36m/testcases/files/[0m12_MiB [36m/testcases/files/[0m2_KiB [36m/testcases/files/[0m5_bytes [36m/testcases/files/[0m7_MiB
|
||||
[36m/testcases/files/[0m10_KiB [36m/testcases/files/[0m13_bytes [36m/testcases/files/[0m2_MiB [36m/testcases/files/[0m5_KiB [36m/testcases/files/[0m8_bytes
|
||||
[36m/testcases/files/[0m10_MiB [36m/testcases/files/[0m13_KiB [36m/testcases/files/[0m3_bytes [36m/testcases/files/[0m5_MiB [36m/testcases/files/[0m8_KiB
|
||||
[36m/testcases/files/[0m11_bytes [36m/testcases/files/[0m13_MiB [36m/testcases/files/[0m3_KiB [36m/testcases/files/[0m6_bytes [36m/testcases/files/[0m8_MiB
|
||||
[36m/testcases/files/[0m11_KiB [36m/testcases/files/[0m1_bytes [36m/testcases/files/[0m3_MiB [36m/testcases/files/[0m6_KiB [36m/testcases/files/[0m9_bytes
|
||||
[36m/testcases/files/[0m11_MiB [36m/testcases/files/[0m1_KiB [36m/testcases/files/[0m4_bytes [36m/testcases/files/[0m6_MiB [36m/testcases/files/[0m9_KiB
|
||||
[36m/testcases/files/[0m12_bytes [36m/testcases/files/[0m1_MiB [36m/testcases/files/[0m4_KiB [36m/testcases/files/[0m7_bytes [36m/testcases/files/[0m9_MiB
|
||||
[36m/testcases/files/[0m12_KiB [36m/testcases/files/[0m2_bytes [36m/testcases/files/[0m4_MiB [36m/testcases/files/[0m7_KiB
|
6
xtests/files_star_200
Normal file
6
xtests/files_star_200
Normal file
@ -0,0 +1,6 @@
|
||||
[36m/testcases/files/[0m10_bytes [36m/testcases/files/[0m12_bytes [36m/testcases/files/[0m1_bytes [36m/testcases/files/[0m3_bytes [36m/testcases/files/[0m5_bytes [36m/testcases/files/[0m7_bytes [36m/testcases/files/[0m9_bytes
|
||||
[36m/testcases/files/[0m10_KiB [36m/testcases/files/[0m12_KiB [36m/testcases/files/[0m1_KiB [36m/testcases/files/[0m3_KiB [36m/testcases/files/[0m5_KiB [36m/testcases/files/[0m7_KiB [36m/testcases/files/[0m9_KiB
|
||||
[36m/testcases/files/[0m10_MiB [36m/testcases/files/[0m12_MiB [36m/testcases/files/[0m1_MiB [36m/testcases/files/[0m3_MiB [36m/testcases/files/[0m5_MiB [36m/testcases/files/[0m7_MiB [36m/testcases/files/[0m9_MiB
|
||||
[36m/testcases/files/[0m11_bytes [36m/testcases/files/[0m13_bytes [36m/testcases/files/[0m2_bytes [36m/testcases/files/[0m4_bytes [36m/testcases/files/[0m6_bytes [36m/testcases/files/[0m8_bytes
|
||||
[36m/testcases/files/[0m11_KiB [36m/testcases/files/[0m13_KiB [36m/testcases/files/[0m2_KiB [36m/testcases/files/[0m4_KiB [36m/testcases/files/[0m6_KiB [36m/testcases/files/[0m8_KiB
|
||||
[36m/testcases/files/[0m11_MiB [36m/testcases/files/[0m13_MiB [36m/testcases/files/[0m2_MiB [36m/testcases/files/[0m4_MiB [36m/testcases/files/[0m6_MiB [36m/testcases/files/[0m8_MiB
|
39
xtests/files_star_lG_100
Normal file
39
xtests/files_star_lG_100
Normal file
@ -0,0 +1,39 @@
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_MiB
|
20
xtests/files_star_lG_150
Normal file
20
xtests/files_star_lG_150
Normal file
@ -0,0 +1,20 @@
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_KiB
|
13
xtests/files_star_lG_200
Normal file
13
xtests/files_star_lG_200
Normal file
@ -0,0 +1,13 @@
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1.0[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m10[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m10_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.0[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m6.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m6_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m2.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m2_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m11[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m11_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m7.3[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m7_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m3.1[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m3_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m12[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m12_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m8.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m8_MiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m4.2[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m4_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_bytes
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m13[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m13_MiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.2[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_KiB
|
||||
.[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m1[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m1_bytes .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m5.1[0m[32mk[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m5_KiB .[1;33mr[31mw[0m[38;5;244m-[33mr[38;5;244m--[33mr[38;5;244m--[0m [1;32m9.4[0m[32mM[0m cassowary [34m 1 Jan 12:34[0m [36m/testcases/files/[0m9_MiB
|
@ -1,2 +1,2 @@
|
||||
[36mbroken[0m [36mforbidden[0m [36mparent_dir[0m some_file [36msome_file_relative[0m
|
||||
[36mcurrent_dir[0m [36mitself[0m [36mroot[0m [36msome_file_absolute[0m [36musr[0m
|
||||
[31mbroken[0m [31mforbidden[0m [36mparent_dir[0m some_file [36msome_file_relative[0m
|
||||
[36mcurrent_dir[0m [31mitself[0m [36mroot[0m [36msome_file_absolute[0m [36musr[0m
|
||||
|
@ -33,6 +33,10 @@ COLUMNS=120 $exa $testcases/files | diff -q - $results/files_120 || exit 1
|
||||
COLUMNS=160 $exa $testcases/files | diff -q - $results/files_160 || exit 1
|
||||
COLUMNS=200 $exa $testcases/files | diff -q - $results/files_200 || exit 1
|
||||
|
||||
COLUMNS=100 $exa $testcases/files/* | diff -q - $results/files_star_100 || exit 1
|
||||
COLUMNS=150 $exa $testcases/files/* | diff -q - $results/files_star_150 || exit 1
|
||||
COLUMNS=200 $exa $testcases/files/* | diff -q - $results/files_star_200 || exit 1
|
||||
|
||||
|
||||
# Long grid view tests
|
||||
COLUMNS=40 $exa $testcases/files -lG | diff -q - $results/files_lG_40 || exit 1
|
||||
@ -41,6 +45,10 @@ COLUMNS=120 $exa $testcases/files -lG | diff -q - $results/files_lG_120 || exit
|
||||
COLUMNS=160 $exa $testcases/files -lG | diff -q - $results/files_lG_160 || exit 1
|
||||
COLUMNS=200 $exa $testcases/files -lG | diff -q - $results/files_lG_200 || exit 1
|
||||
|
||||
COLUMNS=100 $exa $testcases/files/* -lG | diff -q - $results/files_star_lG_100 || exit 1
|
||||
COLUMNS=150 $exa $testcases/files/* -lG | diff -q - $results/files_star_lG_150 || exit 1
|
||||
COLUMNS=200 $exa $testcases/files/* -lG | diff -q - $results/files_star_lG_200 || exit 1
|
||||
|
||||
|
||||
# Attributes
|
||||
$exa $testcases/attributes -l@T | diff -q - $results/attributes || exit 1
|
||||
@ -54,6 +62,13 @@ $exa $testcases/passwd -lgh | diff -q - $results/passwd || exit 1
|
||||
sudo -u cassowary $exa $testcases/permissions -lghR 2>&1 | diff -q - $results/permissions_sudo || exit 1
|
||||
$exa $testcases/permissions -lghR 2>&1 | diff -q - $results/permissions || exit 1
|
||||
|
||||
# File names
|
||||
# (Mostly escaping control characters in file names)
|
||||
COLUMNS=80 $exa $testcases/file-names 2>&1 | diff -q - $results/file_names || exit 1
|
||||
COLUMNS=80 $exa $testcases/file-names -x 2>&1 | diff -q - $results/file_names_x || exit 1
|
||||
COLUMNS=80 $exa $testcases/file-names -R 2>&1 | diff -q - $results/file_names_R || exit 1
|
||||
$exa $testcases/file-names -1 2>&1 | diff -q - $results/file_names_1 || exit 1
|
||||
$exa $testcases/file-names -T 2>&1 | diff -q - $results/file_names_T || exit 1
|
||||
|
||||
# File types
|
||||
$exa $testcases/file-names-exts -1 2>&1 | diff -q - $results/file-names-exts || exit 1
|
||||
|
Loading…
Reference in New Issue
Block a user