shrink-path.plugin.zsh 6.13 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
# Shrink directory paths, e.g. /home/me/foo/bar/quux -> ~/f/b/quux.
#
# For a fish-style working directory in your command prompt, add the following
# to your theme or zshrc:
#
#   setopt prompt_subst
#   PS1='%n@%m $(shrink_path -f)>'
#
# The following options are available:
#
#   -f, --fish       fish simulation, equivalent to -l -s -t.
#   -l, --last       Print the last directory's full name.
13
#   -s, --short      Truncate directory names to the number of characters given by -#. Without
14
15
16
#                    -s, names are truncated without making them ambiguous.
#   -t, --tilde      Substitute ~ for the home directory.
#   -T, --nameddirs  Substitute named directories as well.
17
18
19
#   -#               Truncate each directly to at least this many characters inclusive of the
#                    ellipsis character(s) (defaulting to 1).
#   -e SYMBOL        Postfix symbol(s) to indicate that a directory name had been truncated.
20
21
22
23
24
25
26
27
28
29
#
# The long options can also be set via zstyle, like
#   zstyle :prompt:shrink_path fish yes
#
# Note: Directory names containing two or more consecutive spaces are not yet
# supported.
#
# Keywords: prompt directory truncate shrink collapse fish
#
# Copyright (C) 2008 by Daniel Friesel <derf@xxxxxxxxxxxxxxxxxx>
Janosch Schwalm's avatar
Janosch Schwalm committed
30
# License: WTFPL <http://www.wtfpl.net>
31
#
Janosch Schwalm's avatar
Janosch Schwalm committed
32
33
# Ref: https://www.zsh.org/mla/workers/2009/msg00415.html
#      https://www.zsh.org/mla/workers/2009/msg00419.html
34
35
36
37
38
39
40
41
42

shrink_path () {
        setopt localoptions
        setopt rc_quotes null_glob

        typeset -i lastfull=0
        typeset -i short=0
        typeset -i tilde=0
        typeset -i named=0
43
44
        typeset -i length=1
        typeset ellipsis=""
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

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

        while [[ $1 == -* ]]; do
                case $1 in
61
62
63
64
                        --)
                                shift
                                break
                        ;;
65
66
67
68
69
70
71
72
73
                        -f|--fish)
                                lastfull=1
                                short=1
                                tilde=1
                        ;;
                        -h|--help)
                                print 'Usage: shrink_path [-f -l -s -t] [directory]'
                                print ' -f, --fish      fish-simulation, like -l -s -t'
                                print ' -l, --last      Print the last directory''s full name'
74
75
                                print ' -s, --short     Truncate directory names to the number of characters given by -#. Without'
                                print '                 -s, names are truncated without making them ambiguous.'
76
77
                                print ' -t, --tilde     Substitute ~ for the home directory'
                                print ' -T, --nameddirs Substitute named directories as well'
78
79
80
                                print ' -#              Truncate each directly to at least this many characters inclusive of the'
                                print '                 ellipsis character(s) (defaulting to 1).'
                                print ' -e SYMBOL       Postfix symbol(s) to indicate that a directory name had been truncated.'
81
82
83
84
85
86
87
88
89
90
91
                                print 'The long options can also be set via zstyle, like'
                                print '  zstyle :prompt:shrink_path fish yes'
                                return 0
                        ;;
                        -l|--last) lastfull=1 ;;
                        -s|--short) short=1 ;;
                        -t|--tilde) tilde=1 ;;
                        -T|--nameddirs)
                                tilde=1
                                named=1
                        ;;
92
93
94
95
96
97
98
                        -[0-9]|-[0-9][0-9])
                                length=${1/-/}
                        ;;
                        -e)
                                shift
                                ellipsis="$1"
                        ;;
99
100
101
102
                esac
                shift
        done

103
        typeset -i elllen=${#ellipsis}
104
105
106
107
108
109
110
111
        typeset -a tree expn
        typeset result part dir=${1-$PWD}
        typeset -i i

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

        if (( named )) {
                for part in ${(k)nameddirs}; {
112
                        [[ $dir == ${nameddirs[$part]}(/*|) ]] && dir=${dir/#${nameddirs[$part]}/\~$part}
113
114
                }
        }
115
        (( tilde )) && dir=${dir/#$HOME/\~}
116
117
118
        tree=(${(s:/:)dir})
        (
                if [[ $tree[1] == \~* ]] {
119
                        cd -q ${~tree[1]}
120
121
122
                        result=$tree[1]
                        shift tree
                } else {
123
                        cd -q /
124
125
126
127
128
129
130
131
132
                }
                for dir in $tree; {
                        if (( lastfull && $#tree == 1 )) {
                                result+="/$tree"
                                break
                        }
                        expn=(a b)
                        part=''
                        i=0
133
                        until [[ $i -gt 99 || ( $i -ge $((length - ellen)) || $dir == $part ) && ( (( ${#expn} == 1 )) || $dir = $expn ) ]]; do
134
135
136
                                (( i++ ))
                                part+=$dir[$i]
                                expn=($(echo ${part}*(-/)))
137
                                (( short )) && [[ $i -ge $((length - ellen)) ]] && break
138
                        done
139
140
141
142
143
144
145
146

                        typeset -i dif=$(( ${#dir} - ${#part} - ellen ))
                        if [[ $dif -gt 0 ]]
                        then
                            part+="$ellipsis"
                        else
                            part="$dir"
                        fi
147
                        result+="/$part"
148
                        cd -q $dir
149
150
151
152
153
154
155
                        shift tree
                }
                echo ${result:-/}
        )
}

## vim:ft=zsh