xref: /onnv-gate/usr/src/lib/libshell/common/fun/pushd (revision 4887:feebf9260c2e)
1*4887Schin#
2*4887Schin# DIRECTORY MANIPULATION FUNCTIONS PUSHD, POPD AND DIRS
3*4887Schin#
4*4887Schin# Uses global parameters _push_max _push_top _push_stack
5*4887Schininteger _push_max=100 _push_top=100
6*4887Schin# Display directory stack -- $HOME displayed as ~
7*4887Schinfunction dirs
8*4887Schin{
9*4887Schin    typeset dir="${PWD#$HOME/}"
10*4887Schin    case $dir in
11*4887Schin    $HOME)
12*4887Schin        dir=\~
13*4887Schin        ;;
14*4887Schin    /*) ;;
15*4887Schin    *)  dir=\~/$dir
16*4887Schin    esac
17*4887Schin    print -r - "$dir ${_push_stack[@]}"
18*4887Schin}
19*4887Schin
20*4887Schin# Change directory and put directory on front of stack
21*4887Schinfunction pushd
22*4887Schin{
23*4887Schin    typeset dir= type=0
24*4887Schin    integer i
25*4887Schin    case $1 in
26*4887Schin    "") # pushd
27*4887Schin        if    ((_push_top >= _push_max))
28*4887Schin        then  print pushd: No other directory.
29*4887Schin              return 1
30*4887Schin        fi
31*4887Schin        type=1 dir=${_push_stack[_push_top]}
32*4887Schin        ;;
33*4887Schin    +[1-9]|+[1-9][0-9]) # pushd +n
34*4887Schin        integer i=_push_top$1-1
35*4887Schin        if    ((i >= _push_max))
36*4887Schin        then  print pushd: Directory stack not that deep.
37*4887Schin              return 1
38*4887Schin        fi
39*4887Schin        type=2 dir=${_push_stack[i]}
40*4887Schin        ;;
41*4887Schin    *)  if    ((_push_top <= 0))
42*4887Schin        then  print pushd: Directory stack overflow.
43*4887Schin              return 1
44*4887Schin        fi
45*4887Schin    esac
46*4887Schin    case $dir in
47*4887Schin    \~*)   dir=$HOME${dir#\~}
48*4887Schin    esac
49*4887Schin    cd "${dir:-$1}" > /dev/null || return 1
50*4887Schin    dir=${OLDPWD#$HOME/}
51*4887Schin    case $dir in
52*4887Schin    $HOME)
53*4887Schin        dir=\~
54*4887Schin        ;;
55*4887Schin    /*) ;;
56*4887Schin    *)  dir=\~/$dir
57*4887Schin    esac
58*4887Schin    case $type in
59*4887Schin    0)  # pushd name
60*4887Schin        _push_stack[_push_top=_push_top-1]=$dir
61*4887Schin        ;;
62*4887Schin    1)  # pushd
63*4887Schin        _push_stack[_push_top]=$dir
64*4887Schin        ;;
65*4887Schin    2)  # push +n
66*4887Schin        type=${1#+} i=_push_top-1
67*4887Schin        set -- "${_push_stack[@]}" "$dir" "${_push_stack[@]}"
68*4887Schin        shift $type
69*4887Schin        for dir
70*4887Schin        do  (((i=i+1) < _push_max)) || break
71*4887Schin            _push_stack[i]=$dir
72*4887Schin        done
73*4887Schin    esac
74*4887Schin    dirs
75*4887Schin}
76*4887Schin
77*4887Schin# Pops the top directory
78*4887Schinfunction popd
79*4887Schin{
80*4887Schin    typeset dir
81*4887Schin    if    ((_push_top >= _push_max))
82*4887Schin    then  print popd: Nothing to pop.
83*4887Schin          return 1
84*4887Schin    fi
85*4887Schin    case $1 in
86*4887Schin    "")
87*4887Schin        dir=${_push_stack[_push_top]}
88*4887Schin        case $dir in
89*4887Schin        \~*)   dir=$HOME${dir#\~}
90*4887Schin        esac
91*4887Schin        cd "$dir" || return 1
92*4887Schin        ;;
93*4887Schin    +[1-9]|+[1-9][0-9])
94*4887Schin        typeset savedir
95*4887Schin        integer i=_push_top$1-1
96*4887Schin        if    ((i >= _push_max))
97*4887Schin        then  print pushd: Directory stack not that deep.
98*4887Schin              return 1
99*4887Schin        fi
100*4887Schin        while ((i > _push_top))
101*4887Schin        do _push_stack[i]=${_push_stack[i-1]}
102*4887Schin              i=i-1
103*4887Schin        done
104*4887Schin        ;;
105*4887Schin    *)  print pushd: Bad directory.
106*4887Schin        return 1
107*4887Schin    esac
108*4887Schin    unset '_push_stack[_push_top]'
109*4887Schin    _push_top=_push_top+1
110*4887Schin    dirs
111*4887Schin}
112