blob: 2b0f1a534ab9e65002207e655b331aa6a97cec9e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# Move back up the directory tree to the first directory matching the name
bd() {
# For completeness' sake, we'll pass any options to cd
local arg
local -a opts
for arg ; do
case $arg in
--)
shift
break
;;
-*)
shift
opts=("${opts[@]}" "$arg")
;;
*)
break
;;
esac
done
# We should have zero or one arguments after all that, bail if there are
# more
if (($# > 1)) ; then
printf 'bash: %s: usage: %s [PATH]\n' \
"$FUNCNAME" "$FUNCNAME" >&2
return 2
fi
# The requested pattern is the first argument; strip trailing slashes if
# there are any
local req=$1
[[ $req != / ]] || req=${req%/}
# What to do now depends on the request
local dir
case $req in
# If no argument at all, just go up one level
'')
dir=..
;;
# Just go straight to the root or dot directories if asked
/|.|..)
dir=$req
;;
# Anything else with a leading / needs to anchor to the start of the
# path
/*)
if [[ ${PWD%*/} != "$dir"/* ]] ; then
printf 'bash: %s: Directory name not in path\n' \
"$FUNCNAME" >&2
return 1
fi
;;
# In all other cases, iterate through the directory tree to find a
# match, or whittle the dir down to an empty string trying
*)
dir=${PWD%/*}
while [[ -n $dir && $dir != */"$req" ]] ; do
dir=${dir%/*}
done
if [[ -z $dir ]] ; then
printf 'bash: %s: Directory name not in path\n' \
"$FUNCNAME" >&2
return 1
fi
;;
esac
# Try to change into the determined directory
builtin cd "${opts[@]}" -- "$dir"
}
# Completion setup for bd
_bd() {
local word
word=${COMP_WORDS[COMP_CWORD]}
# Build a list of dirs in $PWD
local -a dirs
while read -d / -r dir ; do
if [[ -n $dir ]] ; then
dirs=("${dirs[@]}" "$dir")
fi
done < <(printf %s "$PWD")
# Complete with matching dirs
COMPREPLY=( $(compgen -W "${dirs[*]}" -- "$word") )
}
complete -F _bd bd
|