By adding a shebang to the scripts they can be executed directly without an interactive shell. The shebang also makes vims modeline that only set the filetype obsolete.
87 lines
2.5 KiB
Bash
Executable File
87 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/zsh
|
|
## Author: druckdev
|
|
## Created: 2019-10-21
|
|
##
|
|
## An ls wrapper that adds the -A flag (show hidden files except . and ..) when
|
|
## there are no visible files or the directory matches the pattern (POSIX ERE)
|
|
## defined in $LS_SHOW_ALL_DIRS.
|
|
|
|
# Do not include hidden files when globbing and expand to an empty string
|
|
# instead of giving an error when no files match.
|
|
builtin emulate -L zsh -o no_glob_dots -o null_glob
|
|
|
|
# Overwrite here or before calling to change the directories in which hidden
|
|
# files should always be listed.
|
|
builtin local LS_SHOW_ALL_DIRS=${LS_SHOW_ALL_DIRS:-"dotfiles|\.config"}
|
|
|
|
builtin local LS_COMMAND=ls
|
|
if [[ $OSTYPE =~ darwin ]] && command -v gls &>/dev/null; then
|
|
LS_COMMAND=gls
|
|
fi
|
|
|
|
builtin local -a dirs files
|
|
# Pop files and folders from arguments and put them in the corresponding array.
|
|
# All other arguments are kept.
|
|
for arg in "$@"; do
|
|
shift
|
|
if [[ -d "$arg" ]]; then
|
|
dirs+="$arg"
|
|
elif [[ -e "$arg" ]]; then
|
|
files+="$arg"
|
|
else
|
|
set -- "$@" "$arg"
|
|
fi
|
|
done
|
|
|
|
# Print working directory when only flags were given as arguments.
|
|
if ! (( ${#dirs} + ${#files} )); then
|
|
dirs+=.
|
|
fi
|
|
|
|
# Just pass everything to ls when the -d flag is given since then the -A flag
|
|
# makes no difference.
|
|
# Remove all long options because `getopts` cannot handle those and sees for
|
|
# example -d in --group-directories-first. Remove the resulting empty strings
|
|
# afterwards since that confuses `getopts` apparently.
|
|
builtin local -a all_opts empty
|
|
all_opts=("$@")
|
|
empty=("")
|
|
set -- "${(@)${(@)all_opts//--*}:|empty}"
|
|
while getopts d flag 2>/dev/null; do
|
|
[[ "$flag" = "d" ]] || continue
|
|
command $LS_COMMAND "${all_opts[@]}" -- "${files[@]}" "${dirs[@]}"
|
|
return
|
|
done
|
|
# Restore options.
|
|
set -- "${all_opts[@]}"
|
|
unset all_opts empty
|
|
|
|
builtin local separator=""
|
|
|
|
# Print files.
|
|
if (( ${#files} )); then
|
|
command $LS_COMMAND "$@" -- "${files[@]}"
|
|
# Print a newline between files and folder segment.
|
|
separator="\n"
|
|
fi
|
|
|
|
# Print directories.
|
|
builtin local all_flag
|
|
builtin local -a content
|
|
for dir in ${(@f)dirs}; do
|
|
content=( "$dir"/* )
|
|
# If the directory contains no visible files or it matches a pattern, then
|
|
# show hidden files when listing
|
|
if (( ! ${#content} )) || [[ "${dir:A}" =~ "${LS_SHOW_ALL_DIRS:-^$}" ]]; then
|
|
all_flag="-A"
|
|
else
|
|
all_flag=
|
|
fi
|
|
# If there are multiple items to list, print a newline (if ls was already
|
|
# executed) followed by the dir-name.
|
|
! (( ${#dirs} + ${#files} - 1 )) || echo "$separator$dir:"
|
|
# Print directory. $all_flag has to be unquoted else ls will fail.
|
|
command $LS_COMMAND "$@" $all_flag -- "$dir"
|
|
separator="\n"
|
|
done
|