aboutsummaryrefslogtreecommitdiffstats
path: root/examples/functions/dirfuncs
blob: 3958bbec03c0465842cb1607b4c850f2b5149ca9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#
# 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
}