Imported from ../bash-1.14.7.tar.gz.
[platform/upstream/bash.git] / examples / functions / dirfuncs
1 #
2 # Directory manipulation functions from the book 'The Korn Shell'
3 # Modified for use with bash Mon Apr 18 08:37 1994 by
4 # Ken Konecki (kenk@wfg.com)
5 #
6 # Modified by Chet Ramey
7 #
8 # This could stand to have calls to `select' added back in
9
10
11 alias integer="declare -i"
12
13 integer  _push_max=${CDSTACK-31} _push_top=${CDSTACK-31}
14
15 unalias cd
16 # alias cd=_cd
17
18 # Display directory stack -- $HOME display as ~
19 dirs()
20 {
21     dir="${PWD#$HOME/}" 
22     case $dir in
23     $HOME) dir=\~ ;;
24     /*) ;;
25     *) dir=\~/$dir ;;
26     esac
27
28     integer i=_push_top
29     integer n=1
30
31     echo "$n) $dir"
32     while let "i < $_push_max"
33     do
34        n=n+1
35        eval "echo \$n\) \$_push_stack_$i"
36        i=i+1
37     done
38 }
39
40 # Change directory and put directory on front of stack
41 cd()
42 {
43     typeset dir=
44     integer n=0 type=4 i
45     case $1 in
46     -|-1|2) # cd -
47         n=_push_top type=1
48         ;;
49     -[1-9]|-[1-9][0-9]) # cd -n
50         n=_push_top+${1#-}-1 type=2
51         ;;
52
53     1) # keep present directory
54         echo "$PWD"
55         return
56         ;;
57
58     [2-9]|[1-9][0-9]) # cd n
59         n=_push_top+${1}-2 type=2
60         ;;
61
62     *)
63         if let "_push_top <= 0"; then
64             type=3 n=_push_max
65         fi
66         ;;
67     esac
68
69     if let "type < 3"; then
70         if let "n >= _push_max"; then
71             echo cd: Directory stack not that deep
72             return 1
73         else
74             eval dir=\${_push_stack_$n}
75         fi
76     fi
77
78     case $dir in
79     ~*) dir=$HOME${dir#\~} ;;
80     esac
81
82     cd2 ${dir:-$@} > /dev/null || return 1
83     dir=${OLDPWD#$HOME/}
84     case $dir in
85     $HOME)      dir=\~ ;;
86     /*)         ;;
87     *)          dir=\~/$dir ;;
88     esac
89
90     case $type in
91     1) # swap first two elements
92         eval _push_stack_$_push_top=\$dir ;;
93
94     2|3) # put $dir on top and shift down by one until top
95         i=_push_top
96         unset _dirlist
97         while let "i < $_push_max" ; do
98             eval _dirlist=\"\$_dirlist \$_push_stack_$i\"
99             i=i+1
100         done
101
102         i=_push_top
103         for dir in "$dir" ${_dirlist} ; do
104             let "i > n" && break
105             eval _push_stack_$i=\$dir
106             i=i+1
107         done
108         ;;
109     4) # push name
110         _push_top=_push_top-1;
111         eval _push_stack_$_push_top=\$dir
112         ;;
113     esac
114
115     echo "$PWD"
116
117 }
118
119 # Menu-driven change directory command
120 function mcd
121 {
122     dirs
123     echo -n "Select by number or enter a name: "
124     read
125     cd $REPLY
126 }
127
128
129 # Emulate ksh cd substitution
130 cd2()
131 {
132     case "$#" in
133     0)  builtin cd "$HOME" ;;
134     1)  builtin cd "$1" ;;
135     2)  newDir=$(echo $PWD | sed -e "s:$1:$2:g")
136         case "$newDir" in
137         $PWD)   echo "bash:: cd: bad substitution" >&2 ; return 1 ;;
138         *)      builtin cd "$newDir" ;;
139         esac ;;
140     *)  echo "bash: cd: wrong arg count" 1>&2 ; return 1 ;;
141     esac
142 }