From 11ec8b93fb463944c6a13724b5043a779fb3ed08 Mon Sep 17 00:00:00 2001 From: druckdev <63563978+druckdev@users.noreply.github.com> Date: Fri, 25 Sep 2020 01:09:59 +0200 Subject: [PATCH] zsh: Heavy improvements to ls_show_hidden Autoload the function instead of declaring it directly. Add functionality for multiple targets. It should now pretty much perform like `command ls`. Refactored code to use more zsh extensions like globbing instead of parsing the output of `ls` making it a lot faster. --- .config/zsh/autoload/ls | 62 ++++++++++++++++++++++++++++ .config/zsh/plugins/alias.zsh | 2 +- .config/zsh/plugins/functionsPre.zsh | 25 ----------- 3 files changed, 63 insertions(+), 26 deletions(-) create mode 100755 .config/zsh/autoload/ls diff --git a/.config/zsh/autoload/ls b/.config/zsh/autoload/ls new file mode 100755 index 0000000..d34c792 --- /dev/null +++ b/.config/zsh/autoload/ls @@ -0,0 +1,62 @@ +## 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 and expand to an empty string instead of giving an +# error when globbing. +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 -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+="$PWD" +fi + +builtin local separator="" + +# Print files. +if (( ${#files} )); then + command ls "$@" -- "${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 "$@" $all_flag -- "$dir" + separator="\n" +done diff --git a/.config/zsh/plugins/alias.zsh b/.config/zsh/plugins/alias.zsh index 2ac3ebe..97a6e88 100644 --- a/.config/zsh/plugins/alias.zsh +++ b/.config/zsh/plugins/alias.zsh @@ -72,7 +72,7 @@ alias gdiff='git diff' alias gd='git diff' ## Navigation -alias ls='_ls_show_hidden --color=auto --group-directories-first -p -v' +alias ls='ls --color=auto --group-directories-first -p -v' alias sl='ls' alias la='ls -A' alias l='ls -lh --time-style=long-iso' diff --git a/.config/zsh/plugins/functionsPre.zsh b/.config/zsh/plugins/functionsPre.zsh index 626d652..1a890af 100644 --- a/.config/zsh/plugins/functionsPre.zsh +++ b/.config/zsh/plugins/functionsPre.zsh @@ -18,28 +18,3 @@ function _nemo_wd_default() { command nemo "$@" fi } - -## ls function that prints hidden files when there are no regular files -## or if we are in a directory that matches the regex in LS_SHOW_ALL_DIRS -function _ls_show_hidden() { - # Can be overwritten by settings it before calling - local LS_SHOW_ALL_DIRS=${LS_SHOW_ALL_DIRS:-"dotfiles|\.config"} - - # if a path is given, target will contain the given directory or the directory in which the - # given file is located - local target - for arg in "$@"; do - if [ -d "$arg" ]; then - target="$arg" - break - elif [ -d "${arg%/*}" ]; then - target="${arg%/*}" - break - fi - done - if [[ -z "$(command ls "$@")" || "$( (cd "$target"; pwd) )" =~ "${LS_SHOW_ALL_DIRS:-^$}" ]]; then - command ls -A "$@" - else - command ls "$@" - fi -}