blob: df8aea785f77ed7de615bd68c7500e4911efd38e (
plain)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
#! /bin/bash
#
# cdhist - cd replacement with a directory stack like pushd/popd
#
# usage: cd [-l] [-n] [-] [dir]
#
# options:
# -l print the cd directory stack, one entry per line
# - equivalent to $OLDPWD
# -n cd to nth directory in cd directory stack
# -s cd to first directory in stack matching (substring) `s'
#
# arguments:
# dir cd to dir and push dir onto the cd directory stack
#
# If the new directory is a directory in the stack and the options selected
# it (-n, -s), the new working directory is printed
#
# If the variable CDHISTFILE is set, the cd directory stack is loaded from
# and written to $CDHISTFILE every time `cd' is executed.
#
# Note: I got this off the net somewhere; I don't know the original author
#
# Chet Ramey
# chet@po.cwru.edu
_cd_print()
{
echo -e "$@"
}
cd()
{
typeset -i cdlen i
typeset t
if [ $# -eq 0 ]
then
set -- $HOME
fi
if [ "$CDHISTFILE" ] && [ -r "$CDHISTFILE" ] # if directory history exists
then
typeset CDHIST
i=-1
while read -r t # read directory history file
do
CDHIST[i=i+1]=$t
done <$CDHISTFILE
fi
if [ "${CDHIST[0]}" != "$PWD" ] && [ -n "$PWD" ]
then
_cdins # insert $PWD into cd history
fi
cdlen=${#CDHIST[*]} # number of elements in history
case "$@" in
-) # cd to new dir
if [ "$OLDPWD" = "" ] && ((cdlen>1))
then
'_cdprint' ${CDHIST[1]}
builtin cd ${CDHIST[1]}
pwd
else
builtin cd "$@"
# pwd
fi
;;
-l) # _cdprint directory list
((i=cdlen))
while (((i=i-1)>=0))
do
num=$i
'_cdprint' "$num ${CDHIST[i]}"
done
return
;;
-[0-9]|-[0-9][0-9]) # cd to dir in list
if (((i=${1#-})<cdlen))
then
'_cdprint' ${CDHIST[i]}
builtin cd ${CDHIST[i]}
pwd
else
builtin cd $@
# pwd
fi
;;
-*) # cd to matched dir in list
t=${1#-}
i=1
while ((i<cdlen))
do
case ${CDHIST[i]} in
*$t*)
'_cdprint' ${CDHIST[i]}
builtin cd ${CDHIST[i]}
pwd
break
;;
esac
((i=i+1))
done
if ((i>=cdlen))
then
builtin cd $@
# pwd
fi
;;
*) # cd to new dir
builtin cd $@
# pwd
;;
esac
_cdins # insert $PWD into cd history
if [ "$CDHISTFILE" ]
then
cdlen=${#CDHIST[*]} # number of elements in history
i=0
while ((i<cdlen))
do
echo ${CDHIST[i]} # update directory history
((i=i+1))
done >$CDHISTFILE
fi
}
_cdins() # insert $PWD into cd history
{ # meant to be called only by cd
typeset -i i
i=0
while (( i < ${#CDHIST[*]} )) # see if dir is already in list
do
if [ "${CDHIST[$i]}" = "$PWD" ]
then
break
fi
((i=i+1))
done
if (( i>22 )) # limit max size of list
then
i=22
fi
while (((i=i-1)>=0)) # bump old dirs in list
do
CDHIST[i+1]=${CDHIST[i]}
done
CDHIST[0]=$PWD # insert new directory in list
}
# examples
shopt -s expand_aliases
# go to known place before doing anything
cd /
echo CDHIST: "${CDHIST[@]}"
for dir in /tmp /bin - -2 -l
do
cd $dir
echo CDHIST: "${CDHIST[@]}"
echo PWD: $PWD
done
exit 0
|