summaryrefslogtreecommitdiff
path: root/etc/functions/rtab
blob: 7444fef07e5fd992e3941adf9cb511d82f2c4ec9 (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
## vim:ft=zsh
## reverse tabbing, useful in the prompt
## Copyright (C) 2008, 2009 by Daniel Friesel <derf@derf.homelinux.org>
## License: WTFPL <http://sam.zoy.org/wtfpl>

## CAVEAT: directory-names containing two or more consecutive spaces
## are not yet supported

setopt localoptions
setopt rc_quotes null_glob

typeset -i lastfull=0
typeset -i short=0
typeset -i tilde=0
typeset -i named=0

if zstyle -t ':prompt:rtab' fish; then
	lastfull=1
	short=1
	tilde=1
fi
if zstyle -t ':prompt:rtab' nameddirs; then
	tilde=1
	named=1
fi
zstyle -t ':prompt:rtab' last && lastfull=1
zstyle -t ':prompt:rtab' short && short=1
zstyle -t ':prompt:rtab' tilde && tilde=1

while [[ $1 == -* ]]; do
	case $1 in
		-f|--fish)
			lastfull=1
			short=1
			tilde=1
		;;
		-h|--help)
			print 'Usage: rtab [-f -l -s -t] [directory]'
			print ' -f, --fish      fish-simulation, like -l -s -t'
			print ' -l, --last      Print the last directory''s full name'
			print ' -s, --short     Truncate directory names to the first character'
			print ' -t, --tilde     Substitute ~ for the home directory'
			print ' -T, --nameddirs Substitute named directories as well'
			print 'The long options can also be set via zstyle, like'
			print '  zstyle :prompt:rtab fish yes'
			return 0
		;;
		-l|--last) lastfull=1 ;;
		-s|--short) short=1 ;;
		-t|--tilde) tilde=1 ;;
		-T|--nameddirs)
			tilde=1
			named=1
		;;
		-|--)
			shift
			break
		;;
	esac
	shift
done

typeset -a tree expn
typeset result part dir=${1-$PWD}
typeset -i i

[[ -d $dir ]] || return 0

if (( named )) {
	for part in ${(k)nameddirs}; {
		[[ $dir == ${nameddirs[$part]}(/*|) ]] && dir=${dir/${nameddirs[$part]}/\~$part}
	}
}
(( tilde )) && dir=${dir/#$HOME/\~}
tree=(${(s:/:)dir})
(
	unfunction chpwd 2> /dev/null

	# Start either in the currrent named directory or in /
	if [[ $tree[1] == \~* ]] {
		cd ${~tree[1]}
		result=$tree[1]
		shift tree
	} else {
		cd /
	}
	for dir in $tree; {
		if (( lastfull && $#tree == 1 )) {
			result+="/$tree"
			break
		}

		# required for the until loop
		expn=(a b)
		part=''
		i=0
		until [[ (( ${#expn} == 1 )) || $dir == $expn || $i -gt 99 ]]  do
			(( i++ ))
			part+=$dir[$i]
			expn=($(echo ${part}*(-/)))
			# Never show a single . as directory
			if [[ $i == 1 && $dir[$i] == . ]] {
				expn=(a b)
			} elif [[ $short == 1 ]] {
				break
			}
		done
		result+="/$part"
		cd $dir
		shift tree
	}
	echo ${result:-/}
)