#
# DIRECTORY MANIPULATION FUNCTIONS, REPLACES CD
#
# Uses global parameters _push_max _push_top _push_stack
integer _push_max=${CDSTACK-32} _push_top=${CDSTACK-32}
unalias cd
alias cd=_cd
# Display directory stack -- $HOME displayed as ~
function dirs
{
typeset dir="${PWD#$HOME/}"
case $dir in
$HOME)
dir=\~
;;
/*) ;;
*) dir=\~/$dir
esac
PS3=
select i in "$dir" "${_push_stack[@]}"
do :
done < /dev/null
}
# Change directory and put directory on front of stack
function _cd
{
typeset dir=
integer n=0 type=4
case $1 in
-|-1|2) # \cd -
n=_push_top type=1
;;
-[1-9]*([0-9])) # \cd -n
n=_push_top+${1#-}-1 type=2
;;
1) # keep present directory
print -r - "$PWD"
return
;;
[1-9]*([0-9])) # \cd n
n=_push_top+${1}-2 type=2
;;
*) if ((_push_top <= 0))
then type=3 n=_push_max
fi
esac
if ((type<3))
then if ((n >= _push_max+1))
then print -u2 cd: Directory stack not that deep.
return 1
else dir=${_push_stack[n]}
fi
fi
case $dir in
\~*) dir=$HOME${dir#\~}
esac
\cd "${dir:-$@}" >| /dev/null || return 1
dir=${OLDPWD#$HOME/}
case $TERM in
630)
print "\033[?${#PWD};2v$PWD\c"
;;
esac
case $dir in
$HOME)
dir=\~
;;
/*) ;;
*) dir=\~/$dir
esac
case $type in
1) # swap first two elements
_push_stack[_push_top]=$dir
;;
2|3) # put $dir on top and shift down by one until top
integer i=_push_top
for dir in "$dir" "${_push_stack[@]}"
do ((i > n)) && break
_push_stack[i]=$dir
i=i+1
done
;;
4) # push name
_push_stack[_push_top=_push_top-1]=$dir
;;
esac
print -r - "$PWD"
}
# Menu driven change directory command
function mcd
{
typeset dir="${PWD#$HOME/}"
case $dir in
$HOME)
dir=\~
;;
/*) ;;
*) dir=\~/$dir
esac
PS3='Select by number or enter a name: '
select dir in "$dir" "${_push_stack[@]}"
do if _cd $REPLY
then return
fi
done
}