# # DIRECTORY MANIPULATION FUNCTIONS pushd, popd, and dirs # # This example is from pages 270 - 273 in the "The New Korn Shell Command # and Programming Language" by Morris I. Bolsky and David G. Korn (1995 # Prentice Hall). # # Usage: dirs # pushd [directory] # pushd +n # # Uses global variables _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 -u2 pushd: No other directory. return 1 fi type=1 dir=${_push_stack[_push_top]} ;; +[1-9]*([0-9])) # pushd +n integer i=_push_top$1-1 if ((i >= _push_max)) ; then print -u2 pushd: Directory stack not that deep return 1 fi type=2 dir=${_push_stack[i]} ;; *) if ((_push_top <= 0)) ; then print -u2 pushd: Directory stack overflow. return 1 fi ;; esac case $dir in ~*) dir=$HOME${dir#~} ;; esac cd "${dir:~$1}" || 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) # pushd +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 -u2 popd: Nothing to pop. return 1 fi case $1 in "") dir=${_push_stack[_push_top]} case $dir in ~*) dir=$HOME${dir#~} ;; esac cd "$dir" ;; +[1-9]*([0-9])) integer i=_push_top$1-1 if ((i >= _push_max)) ; then print -u2 pushd: Directory stack not that deep return 1 fi while ((i > _push_top)) ; do _push_stack[i]=${_push_stack[i-1]} (( i -= 1 )) done ;; *) print pushd: Bad directory. return 1 ;; esac unset _push_stack[_push_top] (( _push_top += 1)) dirs }