From 7d6fe8b1886f902f8ffbec2a9985fae9f91121cb Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 2 Dec 2018 17:59:29 +1300 Subject: Overhaul Bash completion scripts Some general changes: * Apply case sensitivity switching in more contexts, using a dynamically loaded helper function * Use array counters for appending to COMPREPLY where possible * Lots more short-circuiting to limit structural depth These changes are expansive and there will definitely be bugs. --- bash/bash_completion.d/mex.bash | 60 +++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) (limited to 'bash/bash_completion.d/mex.bash') diff --git a/bash/bash_completion.d/mex.bash b/bash/bash_completion.d/mex.bash index bc3d2c7b..b1e0e1a7 100644 --- a/bash/bash_completion.d/mex.bash +++ b/bash/bash_completion.d/mex.bash @@ -1,16 +1,54 @@ +# Load _completion_ignore_case helper function +if ! declare -F _completion_ignore_case >/dev/null ; then + source "$HOME"/.bash_completion.d/_completion_ignore_case.bash +fi + # Completion setup for mex(1df), completing non-executable files in $PATH _mex() { - local -a path - IFS=: read -ra path < <(printf '%s\n' "$PATH") - local dir name - for dir in "${path[@]}" ; do - [[ -d $dir ]] || continue - for name in "$dir"/* ; do - [[ -e $name ]] || continue - ! [[ -d $name ]] || continue - ! [[ -x $name ]] || continue - COMPREPLY[${#COMPREPLY[@]}]=${name##*/} + + # Iterate through completions produced by subshell + local ci comp + while IFS= read -d / -r comp ; do + COMPREPLY[ci++]=$comp + done < <( + + # Make globs expand appropriately + shopt -u dotglob + shopt -s nullglob + if _completion_ignore_case ; then + shopt -s nocaseglob + fi + + # Break $PATH up into an array + declare -a paths + IFS=: read -a paths -r \ + < <(printf '%s\n' "$PATH") + + # Iterate through each path, collecting non-executable filenames + for path in "${paths[@]}" ; do + for name in "$path"/"$2"* ; do + + # Skip anything that is not a plain file + [[ -f $name ]] || continue + # Skip files that are already executable + ! [[ -x $name ]] || continue + + # Chop off leading path + name=${name##*/} + + # Skip certain filename patterns + case $name in + # DOS batch file + (*.bat) continue ;; + # README files + (README*) continue ;; + esac + + # Print name of the file + printf '%s/' "${name##*/}" + + done done - done + ) } complete -F _mex mex -- cgit v1.2.3