summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChester Liu <skyline75489@outlook.com>2021-10-29 15:50:54 +0800
committerChester Liu <skyline75489@outlook.com>2021-10-29 15:50:54 +0800
commit99d653b7fa3d6f29efe8c8e4506b3c97a2afa234 (patch)
tree547bf9850801fa9780d386b7e339203f2c790b51
parent9881d00d00e1575229c47570017e386bdc202f6a (diff)
parentb32f441851fdad8b5e3a6aa8cf23e276d7cc1278 (diff)
Merge branch 'master' into chesterliu/dev/win-support
-rw-r--r--.github/workflows/unit-tests.yml54
-rw-r--r--.travis.yml19
-rw-r--r--Cargo.lock10
-rw-r--r--Cargo.toml11
-rw-r--r--README.md12
-rw-r--r--build.rs3
-rw-r--r--completions/bash/exa (renamed from completions/completions.bash)20
-rwxr-xr-xcompletions/fish/exa.fish (renamed from completions/completions.fish)22
-rw-r--r--completions/zsh/_exa (renamed from completions/completions.zsh)4
-rw-r--r--devtools/dev-bash.sh23
-rwxr-xr-xdevtools/dev-create-test-filesystem.sh20
-rw-r--r--devtools/dev-package-for-linux.sh13
-rw-r--r--devtools/local-package-for-macos.sh13
-rw-r--r--src/fs/dir_action.rs2
-rw-r--r--src/fs/feature/git.rs8
-rw-r--r--src/info/filetype.rs14
-rw-r--r--src/main.rs1
-rw-r--r--src/options/parser.rs2
-rw-r--r--src/output/grid_details.rs4
-rw-r--r--src/output/icons.rs14
-rw-r--r--src/output/render/size.rs2
-rw-r--r--xtests/git.toml12
-rw-r--r--xtests/outputs/git4_long.ansitxt1
23 files changed, 195 insertions, 89 deletions
diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
new file mode 100644
index 0000000..4071b3a
--- /dev/null
+++ b/.github/workflows/unit-tests.yml
@@ -0,0 +1,54 @@
+name: Unit tests
+
+on:
+ push:
+ branches: [ master ]
+ paths:
+ - '.github/workflows/*'
+ - 'src/**'
+ - 'Cargo.*'
+ - build.rs
+ pull_request:
+ branches: [ master ]
+ paths:
+ - '.github/workflows/*'
+ - 'src/**'
+ - 'Cargo.*'
+ - build.rs
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ unit-tests:
+ runs-on: ${{ matrix.os }}
+
+ continue-on-error: ${{ matrix.rust == 'nightly' }}
+
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+ rust: [1.48.0, stable, beta, nightly]
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Install Rust toolchain
+ uses: actions-rs/toolchain@v1
+ with:
+ profile: minimal
+ toolchain: ${{ matrix.rust }}
+ override: true
+
+ - name: Install cargo-hack
+ uses: actions-rs/cargo@v1
+ with:
+ command: install
+ args: cargo-hack
+
+ - name: Run unit tests
+ uses: actions-rs/cargo@v1
+ with:
+ command: hack
+ args: test --feature-powerset
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1f08108..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-language: rust
-rust:
- - 1.45.2
- - stable
- - beta
- - nightly
-
-jobs:
- fast_finish: true
- allow_failures:
- - rust: nightly
-
- include:
- - name: 'Rust: test with all features'
- rust: stable
- install:
- - cargo install cargo-hack
- script:
- - cargo hack test --feature-powerset
diff --git a/Cargo.lock b/Cargo.lock
index abe9afd..f62bbc9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "ansi_term"
version = "0.12.1"
@@ -90,9 +92,9 @@ dependencies = [
[[package]]
name = "git2"
-version = "0.13.18"
+version = "0.13.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b483c6c2145421099df1b4efd50e0f6205479a072199460eff852fa15e5603c7"
+checksum = "d9831e983241f8c5591ed53f17d874833e2fa82cac2625f3888c50cbfe136cba"
dependencies = [
"bitflags",
"libc",
@@ -151,9 +153,9 @@ checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
[[package]]
name = "libgit2-sys"
-version = "0.12.19+1.1.0"
+version = "0.12.21+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f322155d574c8b9ebe991a04f6908bb49e68a79463338d24a43d6274cb6443e6"
+checksum = "86271bacd72b2b9e854c3dcfb82efd538f15f870e4c11af66900effb462f6825"
dependencies = [
"cc",
"libc",
diff --git a/Cargo.toml b/Cargo.toml
index 965a7a6..9b384c3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,11 +1,11 @@
[package]
name = "exa"
description = "A modern replacement for ls"
-
authors = ["Benjamin Sago <ogham@bsago.me>"]
categories = ["command-line-utilities"]
edition = "2018"
exclude = ["/devtools/*", "/Justfile", "/Vagrantfile", "/screenshots.png"]
+readme = "README.md"
homepage = "https://the.exa.website/"
license = "MIT"
repository = "https://github.com/ogham/exa"
@@ -65,7 +65,7 @@ lto = true
[package.metadata.deb]
-license-file = [ "LICENCE" ]
+license-file = [ "LICENCE", "4" ]
depends = "$auto"
extended-description = """
exa is a replacement for ls written in Rust.
@@ -74,6 +74,9 @@ section = "utils"
priority = "optional"
assets = [
[ "target/release/exa", "/usr/bin/exa", "0755" ],
- [ "contrib/man/exa.1", "/usr/share/man/man1/exa.1", "0644" ],
- [ "contrib/completions.bash", "/etc/bash_completion.d/exa", "0644" ],
+ [ "target/release/../man/exa.1", "/usr/share/man/man1/exa.1", "0644" ],
+ [ "target/release/../man/exa_colors.5", "/usr/share/man/man5/exa_colors.5", "0644" ],
+ [ "completions/bash/exa", "/usr/share/bash-completion/completions/exa", "0644" ],
+ [ "completions/zsh/_exa", "/usr/share/zsh/site-functions/_exa", "0644" ],
+ [ "completions/fish/exa.fish", "/usr/share/fish/vendor_completions.d/exa.fish", "0644" ],
]
diff --git a/README.md b/README.md
index 898394d..ec4749f 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,13 @@
<div align="center">
-<h1>exa</h1>
+
+# exa
[exa](https://the.exa.website/) is a modern replacement for _ls_.
**README Sections:** [Options](#options) — [Installation](#installation) — [Development](#development)
-<a href="https://travis-ci.org/github/ogham/exa">
- <img src="https://travis-ci.org/ogham/exa.svg?branch=master" alt="Build status" />
-</a>
-
-<a href="https://saythanks.io/to/ogham%40bsago.me">
- <img src="https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg" alt="Say thanks!" />
-</a>
+[![Unit tests](https://github.com/ogham/exa/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/ogham/exa/actions/workflows/unit-tests.yml)
+[![Say thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/ogham%40bsago.me)
</div>
![Screenshots of exa](screenshots.png)
diff --git a/build.rs b/build.rs
index f27aa24..a0a1351 100644
--- a/build.rs
+++ b/build.rs
@@ -38,9 +38,10 @@ fn main() -> io::Result<()> {
// We need to create these files in the Cargo output directory.
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
+ let path = &out.join("version_string.txt");
// Bland version text
- let mut f = File::create(&out.join("version_string.txt"))?;
+ let mut f = File::create(path).expect(&path.to_string_lossy());
writeln!(f, "{}", strip_codes(&ver))?;
Ok(())
diff --git a/completions/completions.bash b/completions/bash/exa
index 4a370f3..d044727 100644
--- a/completions/completions.bash
+++ b/completions/bash/exa
@@ -8,6 +8,11 @@ _exa()
return
;;
+ --colour)
+ COMPREPLY=( $( compgen -W 'always auto never' -- "$cur" ) )
+ return
+ ;;
+
-L|--level)
COMPREPLY=( $( compgen -W '{0..9}' -- "$cur" ) )
return
@@ -19,19 +24,28 @@ _exa()
;;
-t|--time)
- COMPREPLY=( $( compgen -W 'modified changed accessed created --' -- $cur ) )
+ COMPREPLY=( $( compgen -W 'modified changed accessed created --' -- "$cur" ) )
return
;;
--time-style)
- COMPREPLY=( $( compgen -W 'default iso long-iso full-iso --' -- $cur ) )
+ COMPREPLY=( $( compgen -W 'default iso long-iso full-iso --' -- "$cur" ) )
return
;;
esac
case "$cur" in
+ # _parse_help doesn’t pick up short options when they are on the same line than long options
+ --*)
+ # colo[u]r isn’t parsed correctly so we filter these options out and add them by hand
+ parse_help=$( exa --help | grep -oE ' (\-\-[[:alnum:]@-]+)' | tr -d ' ' | grep -v '\-\-colo' )
+ completions=$( echo '--color --colour --color-scale --colour-scale' $parse_help )
+ COMPREPLY=( $( compgen -W "$completions" -- "$cur" ) )
+ ;;
+
-*)
- COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
+ completions=$( exa --help | grep -oE ' (\-[[:alnum:]@])' | tr -d ' ' )
+ COMPREPLY=( $( compgen -W "$completions" -- "$cur" ) )
;;
*)
diff --git a/completions/completions.fish b/completions/fish/exa.fish
index d261196..daf6a4b 100755
--- a/completions/completions.fish
+++ b/completions/fish/exa.fish
@@ -10,10 +10,14 @@ complete -c exa -s 'x' -l 'across' -d "Sort the grid across, rather than d
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"
+complete -c exa -l 'color' \
+ -l 'colour' -d "When to use terminal colours" -x -a "
+ always\t'Always use colour'
+ auto\t'Use colour if standard output is a terminal'
+ never\t'Never use colour'
+"
+complete -c exa -l 'color-scale' \
+ -l 'colour-scale' -d "Highlight levels of file sizes distinctly"
complete -c exa -l 'icons' -d "Display icons"
complete -c exa -l 'no-icons' -d "Don't display icons"
@@ -22,9 +26,9 @@ complete -c exa -l 'group-directories-first' -d "Sort directories before other f
complete -c exa -l 'git-ignore' -d "Ignore files mentioned in '.gitignore'"
complete -c exa -s 'a' -l 'all' -d "Show 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 'L' -l 'level' -d "Limit the depth of recursion" -x -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 "
+complete -c exa -s 's' -l 'sort' -d "Which field to sort by" -x -a "
accessed\t'Sort by file accessed time'
age\t'Sort by file modified time (newest first)'
changed\t'Sort by changed time'
@@ -56,10 +60,10 @@ 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 '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 '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 "
+complete -c exa -s 't' -l 'time' -d "Which timestamp field to list" -x -a "
modified\t'Display modified time'
changed\t'Display changed time'
accessed\t'Display accessed time'
@@ -70,7 +74,7 @@ complete -c exa -s 'n' -l 'numeric' -d "List numeric user and group IDs."
complete -c exa -l 'changed' -d "Use the changed timestamp field"
complete -c exa -s 'u' -l 'accessed' -d "Use the accessed timestamp field"
complete -c exa -s 'U' -l 'created' -d "Use the created timestamp field"
-complete -c exa -l 'time-style' -x -d "How to format timestamps" -a "
+complete -c exa -l 'time-style' -d "How to format timestamps" -x -a "
default\t'Use the default time style'
iso\t'Display brief ISO timestamps'
long-iso\t'Display longer ISO timestaps, up to the minute'
diff --git a/completions/completions.zsh b/completions/zsh/_exa
index f339289..b915a5d 100644
--- a/completions/completions.zsh
+++ b/completions/zsh/_exa
@@ -1,7 +1,7 @@
#compdef exa
# Save this file as _exa in /usr/local/share/zsh/site-functions or in any
-# other folder in $fpath. E. g. save it in a folder called ~/.zfunc and add a
+# other folder in $fpath. E.g. save it in a folder called ~/.zfunc and add a
# line containing `fpath=(~/.zfunc $fpath)` somewhere before `compinit` in your
# ~/.zshrc.
@@ -19,7 +19,7 @@ __exa() {
{-R,--recurse}"[Recurse into directories]" \
{-T,--tree}"[Recurse into directories as a tree]" \
{-F,--classify}"[Display type indicator by file names]" \
- --colo{,u}r"[When to use terminal colours]" \
+ --colo{,u}r="[When to use terminal colours]:(when):(always auto never)" \
--colo{,u}r-scale"[Highlight levels of file sizes distinctly]" \
--icons"[Display icons]" \
--no-icons"[Hide icons]" \
diff --git a/devtools/dev-bash.sh b/devtools/dev-bash.sh
index 95a48a4..8a9073b 100644
--- a/devtools/dev-bash.sh
+++ b/devtools/dev-bash.sh
@@ -11,17 +11,17 @@ bash /vagrant/devtools/dev-versions.sh
# Configure the Cool Prompt™ (not actually trademarked).
# The Cool Prompt tells you whether you’re in debug or strict mode, whether
# you have colours configured, and whether your last command failed.
-function nonzero_return() { RETVAL=$?; [ $RETVAL -ne 0 ] && echo "$RETVAL "; }
-function debug_mode() { [ "$EXA_DEBUG" == "trace" ] && echo -n "trace-"; [ -n "$EXA_DEBUG" ] && echo "debug "; }
-function strict_mode() { [ -n "$EXA_STRICT" ] && echo "strict "; }
-function lsc_mode() { [ -n "$LS_COLORS" ] && echo "lsc "; }
-function exac_mode() { [ -n "$EXA_COLORS" ] && echo "exac "; }
+nonzero_return() { RETVAL=$?; [ "$RETVAL" -ne 0 ] && echo "$RETVAL "; }
+debug_mode() { [ "$EXA_DEBUG" == "trace" ] && echo -n "trace-"; [ -n "$EXA_DEBUG" ] && echo "debug "; }
+strict_mode() { [ -n "$EXA_STRICT" ] && echo "strict "; }
+lsc_mode() { [ -n "$LS_COLORS" ] && echo "lsc "; }
+exac_mode() { [ -n "$EXA_COLORS" ] && echo "exac "; }
export PS1="\[\e[1;36m\]\h \[\e[32m\]\w \[\e[31m\]\`nonzero_return\`\[\e[35m\]\`debug_mode\`\[\e[32m\]\`lsc_mode\`\[\e[1;32m\]\`exac_mode\`\[\e[33m\]\`strict_mode\`\[\e[36m\]\\$\[\e[0m\] "
# The ‘debug’ function lets you switch debug mode on and off.
# Turn it on if you need to see exa’s debugging logs.
-function debug () {
+debug() {
case "$1" in
""|"on") export EXA_DEBUG=1 ;;
"off") export EXA_DEBUG= ;;
@@ -33,11 +33,12 @@ function debug () {
# The ‘strict’ function lets you switch strict mode on and off.
# Turn it on if you’d like exa’s command-line arguments checked.
-function strict () {
- case "$1" in "on") export EXA_STRICT=1 ;;
+strict() {
+ case "$1" in
+ "on") export EXA_STRICT=1 ;;
"off") export EXA_STRICT= ;;
- "") [ -n "$EXA_STRICT" ] && echo "strict on" || echo "strict off" ;;
- *) echo "Usage: strict on|off"; return 1 ;;
+ "") [ -n "$EXA_STRICT" ] && echo "strict on" || echo "strict off" ;;
+ *) echo "Usage: strict on|off"; return 1 ;;
esac;
}
@@ -45,7 +46,7 @@ function strict () {
# environment variables. There’s also a ‘hacker’ theme which turns everything
# green, which is usually used for checking that all colour codes work, and
# for looking cool while you phreak some mainframes or whatever.
-function colors () {
+colors() {
case "$1" in
"ls")
export LS_COLORS="di=34:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43"
diff --git a/devtools/dev-create-test-filesystem.sh b/devtools/dev-create-test-filesystem.sh
index 112b569..74d5e2e 100755
--- a/devtools/dev-create-test-filesystem.sh
+++ b/devtools/dev-create-test-filesystem.sh
@@ -252,7 +252,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/attributes"
# A sample Git repository
# This uses cd because it's easier than telling Git where to go each time
-echo -e "\033[1m[10/13]\033[0m Creating Git testcases (1/3)"
+echo -e "\033[1m[10/13]\033[0m Creating Git testcases (1/4)"
mkdir "$TEST_ROOT/git"
cd "$TEST_ROOT/git"
git init >/dev/null
@@ -281,7 +281,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git"
# A second Git repository
# for testing two at once
-echo -e "\033[1m[11/13]\033[0m Creating Git testcases (2/3)"
+echo -e "\033[1m[11/13]\033[0m Creating Git testcases (2/4)"
mkdir -p "$TEST_ROOT/git2/deeply/nested/directory"
cd "$TEST_ROOT/git2"
git init >/dev/null
@@ -321,7 +321,7 @@ sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git2"
# A third Git repository
# Regression test for https://github.com/ogham/exa/issues/526
-echo -e "\033[1m[12/13]\033[0m Creating Git testcases (3/3)"
+echo -e "\033[1m[12/13]\033[0m Creating Git testcases (3/4)"
mkdir -p "$TEST_ROOT/git3"
cd "$TEST_ROOT/git3"
git init >/dev/null
@@ -334,6 +334,20 @@ find "$TEST_ROOT/git3" -exec touch {} -h -t $FIXED_DATE \;
sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git3"
+# A fourth Git repository
+# Regression test for https://github.com/ogham/exa/issues/698
+echo -e "\033[1m[12/13]\033[0m Creating Git testcases (4/4)"
+mkdir -p "$TEST_ROOT/git4"
+cd "$TEST_ROOT/git4"
+git init >/dev/null
+
+# Create a non UTF-8 file
+touch 'P'$'\b\211''UUU'
+
+find "$TEST_ROOT/git4" -exec touch {} -h -t $FIXED_DATE \;
+sudo chown $FIXED_USER:$FIXED_USER -R "$TEST_ROOT/git4"
+
+
# Hidden and dot file testcases.
# We need to set the permissions of `.` and `..` because they actually
# get displayed in the output here, so this has to come last.
diff --git a/devtools/dev-package-for-linux.sh b/devtools/dev-package-for-linux.sh
index 2e79e00..4497df0 100644
--- a/devtools/dev-package-for-linux.sh
+++ b/devtools/dev-package-for-linux.sh
@@ -9,7 +9,7 @@ set -e
# Linux check!
-uname=`uname -s`
+uname=$(uname -s)
if [[ "$uname" != "Linux" ]]; then
echo "Gotta be on Linux to run this (detected '$uname')!"
exit 1
@@ -29,8 +29,8 @@ fi
# Weekly builds have a bit more information in their version number (see build.rs).
if [[ "$1" == "--weekly" ]]; then
- git_hash=`GIT_DIR=/vagrant/.git git rev-parse --short --verify HEAD`
- date=`date +"%Y-%m-%d"`
+ git_hash=$(GIT_DIR=/vagrant/.git git rev-parse --short --verify HEAD)
+ date=$(date +"%Y-%m-%d")
echo "Building exa weekly v$exa_version, date $date, Git hash $git_hash"
else
echo "Building exa v$exa_version"
@@ -57,9 +57,10 @@ strip -v "$exa_linux_binary"
# the binaries can have consistent names, and it’s still possible to tell
# different *downloads* apart.
echo -e "\n\033[4mZipping binary...\033[0m"
-if [[ "$1" == "--weekly" ]]
- then exa_linux_zip="/vagrant/exa-linux-x86_64-${exa_version}-${date}-${git_hash}.zip"
- else exa_linux_zip="/vagrant/exa-linux-x86_64.zip"
+if [[ "$1" == "--weekly" ]]; then
+ exa_linux_zip="/vagrant/exa-linux-x86_64-${exa_version}-${date}-${git_hash}.zip"
+else
+ exa_linux_zip="/vagrant/exa-linux-x86_64.zip"
fi
rm -vf "$exa_linux_zip"
zip -j "$exa_linux_zip" "$exa_linux_binary"
diff --git a/devtools/local-package-for-macos.sh b/devtools/local-package-for-macos.sh
index 57dfbe6..f82841c 100644
--- a/devtools/local-package-for-macos.sh
+++ b/devtools/local-package-for-macos.sh
@@ -11,7 +11,7 @@ set -e
# Virtualising macOS is a legal minefield, so this script is ‘local’ instead
# of ‘dev’: I run it from my actual machine, rather than from a VM.
-uname=`uname -s`
+uname=$(uname -s)
if [[ "$uname" != "Darwin" ]]; then
echo "Gotta be on Darwin to run this (detected '$uname')!"
exit 1
@@ -36,8 +36,8 @@ fi
# Weekly builds have a bit more information in their version number (see build.rs).
if [[ "$1" == "--weekly" ]]; then
- git_hash=`GIT_DIR=$exa_root/.git git rev-parse --short --verify HEAD`
- date=`date +"%Y-%m-%d"`
+ git_hash=$(GIT_DIR=$exa_root/.git git rev-parse --short --verify HEAD)
+ date=$(date +"%Y-%m-%d")
echo "Building exa weekly v$exa_version, date $date, Git hash $git_hash"
else
echo "Building exa v$exa_version"
@@ -65,9 +65,10 @@ echo "strip $exa_macos_binary"
# the binaries can have consistent names, and it’s still possible to tell
# different *downloads* apart.
echo -e "\n\033[4mZipping binary...\033[0m"
-if [[ "$1" == "--weekly" ]]
- then exa_macos_zip="$exa_root/exa-macos-x86_64-${exa_version}-${date}-${git_hash}.zip"
- else exa_macos_zip="$exa_root/exa-macos-x86_64-${exa_version}.zip"
+if [[ "$1" == "--weekly" ]]; then
+ exa_macos_zip="$exa_root/exa-macos-x86_64-${exa_version}-${date}-${git_hash}.zip"
+else
+ exa_macos_zip="$exa_root/exa-macos-x86_64-${exa_version}.zip"
fi
rm -vf "$exa_macos_zip" | sed 's/^/removing /'
zip -j "$exa_macos_zip" "$exa_macos_binary"
diff --git a/src/fs/dir_action.rs b/src/fs/dir_action.rs
index 26e78d3..ab8ceda 100644
--- a/src/fs/dir_action.rs
+++ b/src/fs/dir_action.rs
@@ -51,7 +51,7 @@ impl DirAction {
match self {
Self::AsFile => true,
Self::Recurse(o) => o.tree,
- _ => false,
+ Self::List => false,
}
}
}
diff --git a/src/fs/feature/git.rs b/src/fs/feature/git.rs
index f6e37ab..c700730 100644
--- a/src/fs/feature/git.rs
+++ b/src/fs/feature/git.rs
@@ -1,5 +1,8 @@
//! Getting the Git status of files and directories.
+use std::ffi::OsStr;
+#[cfg(target_family = "unix")]
+use std::os::unix::ffi::OsStrExt;
use std::path::{Path, PathBuf};
use std::sync::Mutex;
@@ -205,6 +208,11 @@ fn repo_to_statuses(repo: &git2::Repository, workdir: &Path) -> Git {
match repo.statuses(None) {
Ok(es) => {
for e in es.iter() {
+ #[cfg(target_family = "unix")]
+ let path = workdir.join(Path::new(OsStr::from_bytes(e.path_bytes())));
+ // TODO: handle non Unix systems better:
+ // https://github.com/ogham/exa/issues/698
+ #[cfg(not(target_family = "unix"))]
let path = workdir.join(Path::new(e.path().unwrap()));
let elem = (path, e.status());
statuses.push(elem);
diff --git a/src/info/filetype.rs b/src/info/filetype.rs
index 1def7a2..3011d5f 100644
--- a/src/info/filetype.rs
+++ b/src/info/filetype.rs
@@ -26,7 +26,7 @@ impl FileExtensions {
file.name_is_one_of( &[
"Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
"build.gradle", "pom.xml", "Rakefile", "package.json", "Gruntfile.js",
- "Gruntfile.coffee", "BUILD", "BUILD.bazel", "WORKSPACE", "build.xml",
+ "Gruntfile.coffee", "BUILD", "BUILD.bazel", "WORKSPACE", "build.xml", "Podfile",
"webpack.config.js", "meson.build", "composer.json", "RoboFile.php", "PKGBUILD",
"Justfile", "Procfile", "Dockerfile", "Containerfile", "Vagrantfile", "Brewfile",
"Gemfile", "Pipfile", "build.sbt", "mix.exs", "bsconfig.json", "tsconfig.json",
@@ -35,10 +35,10 @@ impl FileExtensions {
fn is_image(&self, file: &File<'_>) -> bool {
file.extension_is_one_of( &[
- "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
- "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
- "svg", "stl", "eps", "dvi", "ps", "cbr", "jpf",
- "cbz", "xpm", "ico", "cr2", "orf", "nef", "heif",
+ "png", "jfi", "jfif", "jif", "jpe", "jpeg", "jpg", "gif", "bmp",
+ "tiff", "tif", "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
+ "svg", "stl", "eps", "dvi", "ps", "cbr", "jpf", "cbz", "xpm",
+ "ico", "cr2", "orf", "nef", "heif", "avif", "jxl",
])
}
@@ -80,14 +80,14 @@ impl FileExtensions {
file.extension_is_one_of( &[
"zip", "tar", "Z", "z", "gz", "bz2", "a", "ar", "7z",
"iso", "dmg", "tc", "rar", "par", "tgz", "xz", "txz",
- "lz", "tlz", "lzma", "deb", "rpm", "zst",
+ "lz", "tlz", "lzma", "deb", "rpm", "zst", "lz4",
])
}
fn is_temp(&self, file: &File<'_>) -> bool {
file.name.ends_with('~')
|| (file.name.starts_with('#') && file.name.ends_with('#'))
- || file.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak", "bk" ])
+ || file.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak", "bkp", "bk" ])
}
fn is_compiled(&self, file: &File<'_>) -> bool {
diff --git a/src/main.rs b/src/main.rs
index c3cdd2d..7bb193a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,6 +18,7 @@
#![allow(clippy::non_ascii_literal)]
#![allow(clippy::option_if_let_else)]
#![allow(clippy::too_many_lines)]
+#![allow(clippy::unnested_or_patterns)] // TODO: remove this when we support Rust 1.53.0
#![allow(clippy::unused_self)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wildcard_imports)]
diff --git a/src/options/parser.rs b/src/options/parser.rs
index 1a765b6..63a1606 100644
--- a/src/options/parser.rs
+++ b/src/options/parser.rs
@@ -430,7 +430,7 @@ impl<'a> MatchedFlags<'a> {
.filter(|tuple| tuple.1.is_some() && predicate(&tuple.0))
.collect::<Vec<_>>();
- if those.len() < 2 { Ok(those.first().cloned().map(|t| t.1.unwrap())) }
+ if those.len() < 2 { Ok(those.first().copied().map(|t| t.1.unwrap())) }
else { Err(OptionsError::Duplicate(those[0].0, those[1].0)) }
}
else {
diff --git a/src/output/grid_details.rs b/src/output/grid_details.rs
index 35ff023..088d7a8 100644
--- a/src/output/grid_details.rs
+++ b/src/output/grid_details.rs
@@ -158,7 +158,7 @@ impl<'a> Render<'a> {
.collect::<Vec<_>>();
let mut last_working_grid = self.make_grid(1, options, &file_names, rows.clone(), &drender);
-
+
if file_names.len() == 1 {
return Some((last_working_grid, 1));
}
@@ -176,7 +176,7 @@ impl<'a> Render<'a> {
if the_grid_fits {
last_working_grid = grid;
}
-
+
if !the_grid_fits || column_count == file_names.len() {
let last_column_count = if the_grid_fits { column_count } else { column_count - 1 };
// If we’ve figured out how many columns can fit in the user’s terminal,
diff --git a/src/output/icons.rs b/src/output/icons.rs
index eea0286..eb7666a 100644
--- a/src/output/icons.rs
+++ b/src/output/icons.rs
@@ -80,7 +80,7 @@ lazy_static! {
m.insert("include", '\u{e5fc}'); // 
m.insert("lib", '\u{f121}'); // 
m.insert("localized", '\u{f179}'); // 
- m.insert("Makefile", '\u{e779}'); // 
+ m.insert("Makefile", '\u{f489}'); // 
m.insert("node_modules", '\u{e718}'); // 
m.insert("npmignore", '\u{e71e}'); // 
m.insert("rubydoc", '\u{e73b}'); // 
@@ -110,6 +110,7 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"apk" => '\u{e70e}', // 
"apple" => '\u{f179}', // 
"avi" => '\u{f03d}', // 
+ "avif" => '\u{f1c5}', // 
"avro" => '\u{e60b}', // 
"awk" => '\u{f489}', // 
"bash" => '\u{f489}', // 
@@ -206,11 +207,16 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"jad" => '\u{e256}', // 
"jar" => '\u{e204}', // 
"java" => '\u{e204}', // 
+ "jfi" => '\u{f1c5}', // 
+ "jfif" => '\u{f1c5}', // 
+ "jif" => '\u{f1c5}', // 
+ "jpe" => '\u{f1c5}', // 
"jpeg" => '\u{f1c5}', // 
"jpg" => '\u{f1c5}', // 
"js" => '\u{e74e}', // 
"json" => '\u{e60b}', // 
"jsx" => '\u{e7ba}', // 
+ "jxl" => '\u{f1c5}', // 
"ksh" => '\u{f489}', // 
"latex" => '\u{f034}', // 
"less" => '\u{e758}', // 
@@ -221,6 +227,7 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"log" => '\u{f18d}', // 
"lua" => '\u{e620}', // 
"lz" => '\u{f410}', // 
+ "lz4" => '\u{f410}', // 
"lzh" => '\u{f410}', // 
"lzma" => '\u{f410}', // 
"lzo" => '\u{f410}', // 
@@ -230,6 +237,7 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"markdown" => '\u{f48a}', // 
"md" => '\u{f48a}', // 
"mjs" => '\u{e74e}', // 
+ "mk" => '\u{f489}', // 
"mkd" => '\u{f48a}', // 
"mkv" => '\u{f03d}', // 
"mobi" => '\u{e28b}', // 
@@ -292,6 +300,7 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"so" => '\u{f17c}', // 
"sql" => '\u{f1c0}', // 
"sqlite3" => '\u{e7c4}', // 
+ "sty" => '\u{f034}', // 
"styl" => '\u{e600}', // 
"stylus" => '\u{e600}', // 
"svg" => '\u{f1c5}', // 
@@ -301,7 +310,9 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"tbz" => '\u{f410}', // 
"tbz2" => '\u{f410}', // 
"tex" => '\u{f034}', // 
+ "tgz" => '\u{f410}', // 
"tiff" => '\u{f1c5}', // 
+ "tlz" => '\u{f410}', // 
"toml" => '\u{e615}', // 
"ts" => '\u{e628}', // 
"tsv" => '\u{f1c3}', // 
@@ -309,6 +320,7 @@ pub fn icon_for_file(file: &File<'_>) -> char {
"ttf" => '\u{f031}', // 
"twig" => '\u{e61c}', // 
"txt" => '\u{f15c}', // 
+ "txz" => '\u{f410}', // 
"tz" => '\u{f410}', // 
"tzo" => '\u{f410}', // 
"video" => '\u{f03d}', // 
diff --git a/src/output/render/size.rs b/src/output/render/size.rs
index 94f751b..5a3ad72 100644
--- a/src/output/render/size.rs
+++ b/src/output/render/size.rs
@@ -46,7 +46,7 @@ impl f::Size {
} else {
numerics.format_int(n.round() as isize)
};
-
+
TextCell {
// symbol is guaranteed to be ASCII since unit prefixes are hardcoded.
width: DisplayWidth::from(&*number) + symbol.len(),
diff --git a/xtests/git.toml b/xtests/git.toml
index c262e9e..ea64cad 100644
--- a/xtests/git.toml
+++ b/xtests/git.toml
@@ -144,6 +144,18 @@ status = 0
tags = [ 'long', 'git' ]
+
+# The forth Git repo: non UTF-8 file
+
+[[cmd]]
+name = "‘exa --git -l’ handles non UTF8 file in Git repositories"
+shell = "exa --git -l /testcases/git4"
+stdout = { file = "outputs/git4_long.ansitxt" }
+stderr = { empty = true }