# # DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS # # Uses global parameters _push_max _push_top _push_stack integer _push_max=100 _push_top=100 # Display directory stack -- $HOME displayed as ~ function dirs { typeset dir="${PWD#$HOME/}" case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac print -r - "$dir ${_push_stack[@]}" } # Change directory and put directory on front of stack function pushd { typeset dir= type=0 integer i case $1 in "") # pushd if ((_push_top >= _push_max)) then print pushd: No other directory. return 1 fi type=1 dir=${_push_stack[_push_top]} ;; +[1-9]|+[1-9][0-9]) # pushd +n integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi type=2 dir=${_push_stack[i]} ;; *) if ((_push_top <= 0)) then print pushd: Directory stack overflow. return 1 fi esac case $dir in \~*) dir=$HOME${dir#\~} esac cd "${dir:-$1}" > /dev/null || return 1 dir=${OLDPWD#$HOME/} case $dir in $HOME) dir=\~ ;; /*) ;; *) dir=\~/$dir esac case $type in 0) # pushd name _push_stack[_push_top=_push_top-1]=$dir ;; 1) # pushd _push_stack[_push_top]=$dir ;; 2) # push +n type=${1#+} i=_push_top-1 set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}" shift $type for dir do (((i=i+1) < _push_max)) || break _push_stack[i]=$dir done esac dirs } # Pops the top directory function popd { typeset dir if ((_push_top >= _push_max)) then print popd: Nothing to pop. return 1 fi case $1 in "") dir=${_push_stack[_push_top]} case $dir in \~*) dir=$HOME${dir#\~} esac cd "$dir" || return 1 ;; +[1-9]|+[1-9][0-9]) typeset savedir integer i=_push_top$1-1 if ((i >= _push_max)) then print pushd: Directory stack not that deep. return 1 fi while ((i > _push_top)) do _push_stack[i]=${_push_stack[i-1]} i=i-1 done ;; *) print pushd: Bad directory. return 1 esac unset '_push_stack[_push_top]' _push_top=_push_top+1 dirs }