1# Shrink directory paths, e.g. /home/me/foo/bar/quux -> ~/f/b/quux. 2# 3# For a fish-style working directory in your command prompt, add the following 4# to your theme or zshrc: 5# 6# setopt prompt_subst 7# PS1='%n@%m $(shrink_path -f)>' 8# 9# The following options are available: 10# 11# -f, --fish fish simulation, equivalent to -l -s -t. 12# -g, --glob Add asterisk to allow globbing of shrunk path (equivalent to -e "*") 13# -l, --last Print the last directory's full name. 14# -s, --short Truncate directory names to the number of characters given by -#. Without 15# -s, names are truncated without making them ambiguous. 16# -t, --tilde Substitute ~ for the home directory. 17# -T, --nameddirs Substitute named directories as well. 18# -# Truncate each directly to at least this many characters inclusive of the 19# ellipsis character(s) (defaulting to 1). 20# -e SYMBOL Postfix symbol(s) to indicate that a directory name had been truncated. 21# -q, --quote Quote special characters in the shrunk path 22# 23# The long options can also be set via zstyle, like 24# zstyle :prompt:shrink_path fish yes 25# 26# Note: Directory names containing two or more consecutive spaces are not yet 27# supported. 28# 29# Keywords: prompt directory truncate shrink collapse fish 30# 31# Copyright (C) 2008 by Daniel Friesel <derf@xxxxxxxxxxxxxxxxxx> 32# License: WTFPL <http://www.wtfpl.net> 33# 34# Ref: https://www.zsh.org/mla/workers/2009/msg00415.html 35# https://www.zsh.org/mla/workers/2009/msg00419.html 36 37shrink_path () { 38 setopt localoptions 39 setopt rc_quotes null_glob 40 41 typeset -i lastfull=0 42 typeset -i short=0 43 typeset -i tilde=0 44 typeset -i named=0 45 typeset -i length=1 46 typeset ellipsis="" 47 typeset -i quote=0 48 typeset -i expand=0 49 50 if zstyle -t ':prompt:shrink_path' fish; then 51 lastfull=1 52 short=1 53 tilde=1 54 fi 55 if zstyle -t ':prompt:shrink_path' nameddirs; then 56 tilde=1 57 named=1 58 fi 59 zstyle -t ':prompt:shrink_path' last && lastfull=1 60 zstyle -t ':prompt:shrink_path' short && short=1 61 zstyle -t ':prompt:shrink_path' tilde && tilde=1 62 zstyle -t ':prompt:shrink_path' glob && ellipsis='*' 63 zstyle -t ':prompt:shrink_path' quote && quote=1 64 zstyle -t ':prompt:shrink_path' expand && expand=1 65 66 while [[ $1 == -* ]]; do 67 case $1 in 68 --) 69 shift 70 break 71 ;; 72 -f|--fish) 73 lastfull=1 74 short=1 75 tilde=1 76 ;; 77 -h|--help) 78 print 'Usage: shrink_path [-f -l -s -t] [directory]' 79 print ' -f, --fish fish-simulation, like -l -s -t' 80 print ' -g, --glob Add asterisk to allow globbing of shrunk path (equivalent to -e "*")' 81 print ' -l, --last Print the last directory''s full name' 82 print ' -s, --short Truncate directory names to the number of characters given by -#. Without' 83 print ' -s, names are truncated without making them ambiguous.' 84 print ' -t, --tilde Substitute ~ for the home directory' 85 print ' -T, --nameddirs Substitute named directories as well' 86 print ' -# Truncate each directly to at least this many characters inclusive of the' 87 print ' ellipsis character(s) (defaulting to 1).' 88 print ' -e SYMBOL Postfix symbol(s) to indicate that a directory name had been truncated.' 89 print ' -q, --quote Quote special characters in the shrunk path' 90 print ' -x, --expand Print the full path. This takes precedence over the other options' 91 print '' 92 print 'The long options can also be set via zstyle, like' 93 print ' zstyle :prompt:shrink_path fish yes' 94 return 0 95 ;; 96 -l|--last) lastfull=1 ;; 97 -s|--short) short=1 ;; 98 -t|--tilde) tilde=1 ;; 99 -T|--nameddirs) 100 tilde=1 101 named=1 102 ;; 103 -[0-9]|-[0-9][0-9]) 104 length=${1/-/} 105 ;; 106 -e) 107 shift 108 ellipsis="$1" 109 ;; 110 -g|--glob) 111 ellipsis='*' 112 ;; 113 -q|--quote) 114 quote=1 115 ;; 116 -x|--expand) 117 expand=1 118 ;; 119 esac 120 shift 121 done 122 123 typeset -i elllen=${#ellipsis} 124 typeset -a tree expn 125 typeset result part dir=${1-$PWD} 126 typeset -i i 127 128 [[ -d $dir ]] || return 0 129 130 if (( expand )) { 131 echo "$dir" 132 return 0 133 } 134 135 if (( named )) { 136 for part in ${(k)nameddirs}; { 137 [[ $dir == ${nameddirs[$part]}(/*|) ]] && dir=${dir/#${nameddirs[$part]}/\~$part} 138 } 139 } 140 (( tilde )) && dir=${dir/#$HOME/\~} 141 tree=(${(s:/:)dir}) 142 ( 143 if [[ $tree[1] == \~* ]] { 144 cd -q ${~tree[1]} 145 result=$tree[1] 146 shift tree 147 } else { 148 cd -q / 149 } 150 for dir in $tree; { 151 if (( lastfull && $#tree == 1 )) { 152 result+="/$tree" 153 break 154 } 155 expn=(a b) 156 part='' 157 i=0 158 until [[ $i -gt 99 || ( $i -ge $((length - ellen)) || $dir == $part ) && ( (( ${#expn} == 1 )) || $dir = $expn ) ]]; do 159 (( i++ )) 160 part+=$dir[$i] 161 expn=($(echo ${part}*(-/))) 162 (( short )) && [[ $i -ge $((length - ellen)) ]] && break 163 done 164 165 typeset -i dif=$(( ${#dir} - ${#part} - ellen )) 166 if [[ $dif -gt 0 ]] 167 then 168 (( quote )) && part=${(q)part} 169 part+="$ellipsis" 170 else 171 part="$dir" 172 (( quote )) && part=${(q)part} 173 fi 174 result+="/$part" 175 cd -q $dir 176 shift tree 177 } 178 echo ${result:-/} 179 ) 180} 181 182## vim:ft=zsh 183