zsh:ls-show-hidden: Fix non_existing arg parsing

`ls` prints a warning if a non-flag argument is specified that does not
exist.

Previously ls-show-hidden assumed that all arguments that are neither a
directory nor an otherwise existing file are flags. As all flags are
passed to the ls call the warning still got printed, but this also lead
to the current working directory (i.e. `.`) being added to the
directories to process.

If `ls` expects an argument to a flag, it is always passed in the format
`--flag=arg` where the equal sign is mandatory. This makes it possible
to simply filter out all flags (and their arguments) from the other
arguments without needing to know which flags take an argument and which
don't.

Fix this behaviour by printing the same warning as `ls` does when an
argument is neither a flag, nor a directory nor an existing file. Also
only add `.` to the directories if *really* only flags were passed.
This commit is contained in:
2022-09-27 01:05:42 +02:00
parent 14f615f5e1
commit 82fc29f9c0

View File

@@ -14,28 +14,38 @@ builtin emulate -L zsh -o no_glob_dots -o null_glob
# files should always be listed. # files should always be listed.
builtin local LS_SHOW_ALL_DIRS=${LS_SHOW_ALL_DIRS:-"dotfiles|\.config"} builtin local LS_SHOW_ALL_DIRS=${LS_SHOW_ALL_DIRS:-"dotfiles|\.config"}
# ANSI escape codes to print in color
builtin local ansi_bold_red=$'\e[31;1m'
builtin local ansi_reset=$'\e[m'
builtin local LS_COMMAND=ls builtin local LS_COMMAND=ls
# Use GNU version if available under MacOS # Use GNU version if available under MacOS
if [[ $OSTYPE =~ darwin ]] && (( $+commands[gls] )); then if [[ $OSTYPE =~ darwin ]] && (( $+commands[gls] )); then
LS_COMMAND=gls LS_COMMAND=gls
fi fi
builtin local non_existing=0
builtin local -a dirs files builtin local -a dirs files
# Pop files and folders from arguments and put them in the corresponding array. # Pop files and folders from arguments and put them in the corresponding array,
# All other arguments are kept. # keep flags (ls takes flag-arguments behind a '=') and warn when non-existing
# arguments were passed.
for arg in "$@"; do for arg in "$@"; do
shift shift
if [[ -d "$arg" ]]; then if [[ ${arg#-} != $arg ]]; then
set -- "$@" "$arg"
elif [[ -d "$arg" ]]; then
dirs+="$arg" dirs+="$arg"
elif [[ -e "$arg" ]]; then elif [[ -e "$arg" ]]; then
files+="$arg" files+="$arg"
else else
set -- "$@" "$arg" printf >&2 "%s%s: cannot access '%s': No such file or directory%s\n" \
"$ansi_bold_red" "$0" "$arg" "$ansi_reset"
non_existing=1
fi fi
done done
# Print working directory when only flags were given as arguments. # Print working directory when only flags were given as arguments.
if ! (( ${#dirs} + ${#files} )); then if ! (( ${#dirs} + ${#files} + $non_existing )); then
dirs+=. dirs+=.
fi fi