aboutsummaryrefslogtreecommitdiff
path: root/bash/bash_completion.d/bd.bash
diff options
context:
space:
mode:
Diffstat (limited to 'bash/bash_completion.d/bd.bash')
-rw-r--r--bash/bash_completion.d/bd.bash54
1 files changed, 37 insertions, 17 deletions
diff --git a/bash/bash_completion.d/bd.bash b/bash/bash_completion.d/bd.bash
index e67cdd09..09134e6a 100644
--- a/bash/bash_completion.d/bd.bash
+++ b/bash/bash_completion.d/bd.bash
@@ -1,25 +1,45 @@
+# 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 bd()
_bd() {
- # Only makes sense for the first argument
- ((COMP_CWORD == 1)) || return
+ # Iterate through completions produced by subshell
+ local ci comp
+ while IFS= read -d / -r comp ; do
+ COMPREPLY[ci++]=$comp
+ done < <(
+
+ # Build an array of path nodes, leaf to root
+ path=$PWD
+ while [[ -n $path ]] ; do
+ node=${path##*/}
+ path=${path%/*}
+ [[ -n $node ]] || continue
+ nodes[ni++]=$node
+ done
+
+ # Continue if we have at least two nodes, counting the leaf
+ ((${#nodes[@]} > 1)) || return
- # Build a list of dirnames in $PWD
- local -a dirnames
- IFS=/ read -rd '' -a dirnames < <(printf '%s\0' "${PWD#/}")
+ # Shift off the leaf, since it is not meaningful to go "back to" the
+ # current directory
+ nodes=("${nodes[@]:1}")
- # Remove the last element in the array (the current directory)
- ((${#dirnames[@]})) || return
- dirnames=("${dirnames[@]:0:${#dirnames[@]}-1}")
+ # Make matching behave appropriately
+ if _completion_ignore_case ; then
+ shopt -s nocasematch 2>/dev/null
+ fi
- # Add the matching dirnames to the reply
- local dirname
- for dirname in "${dirnames[@]}" ; do
- case $dirname in
- "${COMP_WORDS[COMP_CWORD]}"*)
- COMPREPLY[${#COMPREPLY[@]}]=$(printf %q "$dirname")
- ;;
- esac
- done
+ # 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
+ done
+ )
}
complete -F _bd bd