diff options
-rw-r--r-- | VERSION | 4 | ||||
-rw-r--r-- | bash/bash_completion.d/_completion_ignore_case.bash | 2 | ||||
-rw-r--r-- | bash/bash_completion.d/bd.bash | 18 | ||||
-rw-r--r-- | bash/bash_completion.d/eds.bash | 6 | ||||
-rw-r--r-- | bash/bash_completion.d/find.bash | 2 | ||||
-rw-r--r-- | bash/bash_completion.d/keep.bash | 4 | ||||
-rw-r--r-- | bash/bash_completion.d/make.bash | 7 | ||||
-rw-r--r-- | bash/bash_completion.d/man.bash | 30 | ||||
-rw-r--r-- | bash/bash_completion.d/sd.bash | 28 | ||||
-rw-r--r-- | bash/bashrc.d/keep.bash | 24 |
10 files changed, 71 insertions, 54 deletions
@@ -1,2 +1,2 @@ -tejr dotfiles v2.7.0 -Sun Dec 2 05:03:14 UTC 2018 +tejr dotfiles v2.8.0 +Sun Dec 2 10:12:15 UTC 2018 diff --git a/bash/bash_completion.d/_completion_ignore_case.bash b/bash/bash_completion.d/_completion_ignore_case.bash index fe8208fc..b2bc3727 100644 --- a/bash/bash_completion.d/_completion_ignore_case.bash +++ b/bash/bash_completion.d/_completion_ignore_case.bash @@ -6,7 +6,7 @@ _completion_ignore_case() { [[ $set == 'completion-ignore-case on' ]] || continue return 0 done < <(bind -v) - + # Didn't find it, stay case-sensitive return 1 } diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash index 09134e6a..32969522 100644 --- a/bash/bash_completion.d/bd.bash +++ b/bash/bash_completion.d/bd.bash @@ -22,7 +22,7 @@ _bd() { done # Continue if we have at least two nodes, counting the leaf - ((${#nodes[@]} > 1)) || return + ((ni > 1)) || return # Shift off the leaf, since it is not meaningful to go "back to" the # current directory @@ -36,10 +36,18 @@ _bd() { # Iterate through the nodes and print the ones that match the word # being completed, with a trailing slash as terminator for node in "${nodes[@]}" ; do - case $node in - ("$2"*) printf '%s/' "$node" ;; - esac + node_quoted=$(printf '%q' "$node") + # Check the quoted and unquoted word for matching + for match in "$node" "$(printf '%q' "$node")" ; do + # Print any match, slash-terminated + case $match in + ("$2"*) + printf '%s/' "$node" + continue + ;; + esac + done done ) } -complete -F _bd bd +complete -F _bd -o filenames bd diff --git a/bash/bash_completion.d/eds.bash b/bash/bash_completion.d/eds.bash index 371962ca..01db4129 100644 --- a/bash/bash_completion.d/eds.bash +++ b/bash/bash_completion.d/eds.bash @@ -26,9 +26,9 @@ _eds() { ! [[ -d $file ]] || continue # Skip non-executable files [[ -x $file ]] || continue - # Print entry, null-terminated - printf '%q\0' "${file##*/}" + # Print quoted entry, slash-terminated + printf '%s/' "${file##*/}" done ) } -complete -F _eds eds +complete -F _eds -o filenames eds diff --git a/bash/bash_completion.d/find.bash b/bash/bash_completion.d/find.bash index f87029e7..893cb0bc 100644 --- a/bash/bash_completion.d/find.bash +++ b/bash/bash_completion.d/find.bash @@ -31,7 +31,7 @@ _find() { -user -xdev ' -- "$2" - return + exit ;; esac diff --git a/bash/bash_completion.d/keep.bash b/bash/bash_completion.d/keep.bash index c7144684..4b479eca 100644 --- a/bash/bash_completion.d/keep.bash +++ b/bash/bash_completion.d/keep.bash @@ -46,9 +46,13 @@ _keep() { # Build list of kept names bashkeep=${BASHKEEP:-"$HOME"/.bashkeep.d} for keep in "$bashkeep"/"$2"*.bash ; do + # Skip directories ! [[ -d $keep ]] || continue + # Strip leading path keep=${keep##*/} + # Strip trailing extension keep=${keep%.bash} + # Print kept name printf '%s\n' "$keep" done ;; diff --git a/bash/bash_completion.d/make.bash b/bash/bash_completion.d/make.bash index 2527d145..7f8b8125 100644 --- a/bash/bash_completion.d/make.bash +++ b/bash/bash_completion.d/make.bash @@ -23,10 +23,10 @@ _make() { # Match expected format case $line in - # Has no equals sign anywhere - (*=*) continue ;; # First char not a tab ($'\t'*) continue ;; + # Has no equals sign anywhere + (*=*) continue ;; # Has a colon on the line (*:*) ;; # Skip anything else @@ -34,7 +34,7 @@ _make() { esac # Break the target up with space delimiters - local -a targets + declare -a targets IFS=' ' read -a targets -r \ < <(printf '%s\n' "${line%%:*}") @@ -47,7 +47,6 @@ _make() { fi # Examine each target for completion suitability - local target for target in "${targets[@]}" ; do case $target in # Not .PHONY, .POSIX etc diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash index 274f663a..50ab852e 100644 --- a/bash/bash_completion.d/man.bash +++ b/bash/bash_completion.d/man.bash @@ -1,3 +1,8 @@ +# 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 + # Autocompletion for man(1) _man() { @@ -8,6 +13,7 @@ _man() { # If previous word started with a number, we'll assume that's a section to # search + local sec case $3 in [0-9]*) sec=$3 ;; esac @@ -19,27 +25,19 @@ _man() { # Read completion results from a subshell and add them to the COMPREPLY # array individually local ci comp - while IFS= read -d '' -r comp ; do + while IFS= read -d / -r comp ; do COMPREPLY[ci++]=$comp done < <( - # Do not return dotfiles, give us extended globbing, and expand empty - # globs to just nothing + # Make globs expand appropriately shopt -u dotglob shopt -s nullglob - - # Make globbing case-insensitive if appropriate - while read -r _ setting ; do - case $setting in - ('completion-ignore-case on') - shopt -s nocaseglob - break - ;; - esac - done < <(bind -v) + if _completion_ignore_case ; then + shopt -s nocaseglob + fi # Figure out the manual paths to search - if hash amanpath 2>/dev/null ; then + if hash manpath 2>/dev/null ; then # manpath(1) exists, run it to find what to search IFS=: read -a manpaths -r \ @@ -84,8 +82,8 @@ _man() { # Strip section suffixes pages=("${pages[@]%.[0-9]*}") - # Print entries, null-delimited - printf '%s\0' "${pages[@]}" + # Print quoted entries, slash-delimited + printf '%q/' "${pages[@]}" ) } complete -F _man -o bashdefault -o default man diff --git a/bash/bash_completion.d/sd.bash b/bash/bash_completion.d/sd.bash index 66dea73b..4dc72f31 100644 --- a/bash/bash_completion.d/sd.bash +++ b/bash/bash_completion.d/sd.bash @@ -15,18 +15,28 @@ _sd() { # Make globs expand appropriately shopt -s dotglob nullglob if _completion_ignore_case ; then - shopt -s nocaseglob + shopt -s nocasematch 2>/dev/null fi # Print matching sibling dirs that are not the current dir - for sibling in ../"$2"*/ ; do - sibling=${sibling%/} - sibling=${sibling#../} - case $sibling in - ("${PWD##*/}") ;; - (*) printf '%q/' "${sibling}" ;; - esac + for sib in ../*/ ; do + # Strip leading ../ + sib=${sib#../} + # Strip trailing slash + sib=${sib%/} + # Skip self + [[ $sib != "${PWD##*/}" ]] || continue + # Check the quoted and unquoted word for matching + for match in "$sib" "$(printf '%q' "$sib")" ; do + # Print any match, slash-terminated + case $match in + ("$2"*) + printf '%s/' "$sib" + continue + ;; + esac + done done ) } -complete -F _sd sd +complete -F _sd -o filenames sd diff --git a/bash/bashrc.d/keep.bash b/bash/bashrc.d/keep.bash index a39d2fa7..48196aeb 100644 --- a/bash/bashrc.d/keep.bash +++ b/bash/bashrc.d/keep.bash @@ -101,19 +101,17 @@ EOF # If -d was given, delete the keep files for the NAME if ((delete)) ; then - rm -- "$bashkeep"/"$name".bash || - ((errors++)) + rm -- "$bashkeep"/"$name".bash # Save a function elif [[ $(type -t "$name") = 'function' ]] ; then - declare -f -- "$name" >"$bashkeep"/"$name".bash || - ((errors++)) + declare -f -- "$name" >"$bashkeep"/"$name".bash # Save a variable elif declare -p -- "$name" >/dev/null ; then - declare -p -- "$name" >"$bashkeep"/"$name".bash || - ((errors++)) - fi + declare -p -- "$name" >"$bashkeep"/"$name".bash + + fi || ((errors++)) ;; esac done @@ -132,12 +130,12 @@ EOF # Otherwise the user must want us to print all the NAMEs kept ( shopt -s nullglob - declare -a keeps - keeps=("$bashkeep"/*.bash) - keeps=("${keeps[@]##*/}") - keeps=("${keeps[@]%.bash}") - ((${#keeps[@]})) || exit 0 - printf '%s\n' "${keeps[@]}" + for keep in "$bashkeep"/*.bash ; do + ! [[ -d $keep ]] || continue + keep=${keep##*/} + keep=${keep%.bash} + printf '%s\n' "$keep" + done ) } |