dirfuncs   [plain text]


#
# Directory manipulation functions from the book 'The Korn Shell'
# Modified for use with bash Mon Apr 18 08:37 1994 by
# Ken Konecki (kenk@wfg.com)
#
# Modified by Chet Ramey
#
# This could stand to have calls to `select' added back in
# 

alias integer="declare -i"

integer  _push_max=${CDSTACK-31} _push_top=${CDSTACK-31}

unalias cd
# alias cd=_cd

# Display directory stack -- $HOME display as ~
dirs()
{
    dir="${PWD#$HOME/}" 
    case $dir in
    $HOME) dir=\~ ;;
    /*) ;;
    *) dir=\~/$dir ;;
    esac

    integer i=_push_top
    integer n=1

    echo "$n) $dir"
    while let "i < $_push_max"
    do
       n=n+1
       eval "echo \$n\) \$_push_stack_$i"
       i=i+1
    done
}

# Change directory and put directory on front of stack
cd()
{
    typeset dir=
    integer n=0 type=4 i
    case $1 in
    -|-1|2) # cd -
	n=_push_top type=1
	;;
    -[1-9]|-[1-9][0-9]) # cd -n
	n=_push_top+${1#-}-1 type=2
	;;

    1) # keep present directory
	echo "$PWD"
	return
	;;

    [2-9]|[1-9][0-9]) # cd n
	n=_push_top+${1}-2 type=2
	;;

    *)
	if let "_push_top <= 0"; then
	    type=3 n=_push_max
	fi
	;;
    esac

    if let "type < 3"; then
	if let "n >= _push_max"; then
	    echo cd: Directory stack not that deep
	    return 1
	else
	    eval dir=\${_push_stack_$n}
	fi
    fi

    case $dir in
    ~*) dir=$HOME${dir#\~} ;;
    esac

    cd2 ${dir:-$@} > /dev/null || return 1
    dir=${OLDPWD#$HOME/}
    case $dir in
    $HOME)	dir=\~ ;;
    /*) 	;;
    *) 		dir=\~/$dir ;;
    esac

    case $type in
    1) # swap first two elements
	eval _push_stack_$_push_top=\$dir ;;

    2|3) # put $dir on top and shift down by one until top
	i=_push_top
	unset _dirlist
	while let "i < $_push_max" ; do
	    eval _dirlist=\"\$_dirlist \$_push_stack_$i\"
	    i=i+1
	done

	i=_push_top
	for dir in "$dir" ${_dirlist} ; do
	    let "i > n" && break
	    eval _push_stack_$i=\$dir
	    i=i+1
	done
	;;
    4) # push name
	_push_top=_push_top-1;
	eval _push_stack_$_push_top=\$dir
	;;
    esac

    echo "$PWD"

}

# Menu-driven change directory command
function mcd
{
    dirs
    echo -n "Select by number or enter a name: "
    read
    cd $REPLY
}


# Emulate ksh cd substitution
cd2()
{
    case "$#" in
    0)	builtin cd "$HOME" ;;
    1)  builtin cd "$1" ;;
    2)  newDir=$(echo $PWD | sed -e "s:$1:$2:g")
	case "$newDir" in
	$PWD)	echo "bash:: cd: bad substitution" >&2 ; return 1 ;;
	*)	builtin cd "$newDir" ;;
	esac ;;
    *)  echo "bash: cd: wrong arg count" 1>&2 ; return 1 ;;
    esac
}