1#autoload 2 3_mailboxes() { 4 #emulate -L zsh 5 local expl ret=1 6 local maildirectory pinedirectory 7 zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" 8 zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory 9 10 if (( ! $+_mailbox_cache )) then 11 _mailbox_cache "$@" 12 fi 13 14 case "${curcontext}:" in 15 (*:mail:*) 16 if [[ "$PREFIX" == +* ]]; then 17 _tags mailboxes 18 else 19 _tags mailboxes files 20 fi;; 21 (*:(mush|zmail|zmlite):*) 22 if [[ "$PREFIX" == [%+]* ]]; then 23 _tags mailboxes 24 else 25 _tags mailboxes files 26 fi;; 27 (*:mutt:*) 28 if [[ "$PREFIX" == (|-f)[+=]* ]]; then 29 _tags mailboxes 30 else 31 _tags mailboxes files 32 fi;; 33 (*:pine:*) 34 # Files for pine must be absolute paths. 35 if [[ "$PREFIX" == (|-f)[/\~]* ]]; then 36 pinedirectory='' 37 _tags mailboxes files 38 else 39 _tags mailboxes 40 fi;; 41 (*) 42 if [[ "$PREFIX" == (|-f)+* ]]; then 43 _tags mailboxes 44 else 45 _tags mailboxes files 46 fi;; 47 esac 48 49 while _tags; do 50 _requested mailboxes expl 'mailbox specification' _mua_mailboxes && ret=0 51 52 if _requested files expl 'mailbox file'; then 53 [[ "${curcontext}:" != *:(mail|mush|mutt|zmail|zmlite):* ]] && 54 compset -P -f 55 _files "$expl[@]" && ret=0 56 fi 57 (( ret )) || return 0 58 done 59 60 return 1 61} 62 63_mailbox_cache () { 64 local i j _mc_tmp 65 local -aU dirboxes 66 local maildirectory pinedirectory muttrc 67 typeset -aU -g _mailbox_cache 68 typeset -aU -g _maildir_cache _mbox_cache _mh_cache _mutt_cache _pine_cache 69 70 zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" 71 zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory 72 zstyle -s ":completion:${curcontext}:" muttrc muttrc || muttrc="~/.muttrc" 73 74 [[ -f ${~muttrc:-.} ]] && 75 _mc_tmp=${=${(M)${(f)"$(<${~muttrc})"}:#mailboxes *}#mailboxes *} && 76 _mutt_cache=( ${=${(Xe)_mc_tmp}} ) 77 78 _mbox_cache=( ${~maildirectory}/*(^/) ) 79 if [[ -n $pinedirectory ]]; then 80 _pine_cache=( ${~pinedirectory}/**/*(.) ) 81 else 82 _pine_cache=() 83 fi 84 85 dirboxes=( ${~maildirectory}/*(/) ) 86 87 while (( $#dirboxes )); do 88 i=${dirboxes[1]} 89 shift dirboxes 90 if [[ -d "$i/cur" ]]; then 91 _maildir_cache=( "${_maildir_cache[@]}" "$i" ) 92 elif j=( "$i"/<1-> ) && [[ -n "$j" ]]; then 93 _mh_cache=( "${_mh_cache[@]}" "$i" ) 94 dirboxes=( $dirboxes "$i"/*(/) ) 95 else 96 _mbox_cache=( "${_mbox_cache[@]}" "$i"/*(.) ) 97 dirboxes=( $dirboxes "$i"/*(/) ) 98 fi 99 done 100 101 [[ -n "$mailpath" ]] && 102 _mailbox_cache=( "${_mailbox_cache[@]}" "${(@)mailpath%%\?*}" ) 103 104 [[ -n "$MAIL" ]] && _mailbox_cache=( "${_mailbox_cache[@]}" $MAIL ) 105} 106 107_mua_mailboxes() { 108 local -a mbox_short 109 local -aU mbox_names 110 local ret=1 111 112 local maildirectory pinedirectory 113 zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" 114 zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory 115 116 case "${curcontext}:" in 117 (*:elm:*) # I've probably got this wrong, or at least incomplete 118 mbox_names=( "${_mbox_cache[@]}" "${_mailbox_cache[@]}" ) 119 mbox_short=( \! \< \> ) 120 ;; 121 (*:mail:*) 122 if compset -P +; then 123 mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) 124 else 125 mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" 126 "${_mailbox_cache[@]}" ) 127 fi 128 ;; 129 (*:mh:*) 130 local lastmhbox=$(mhpath) 131 if compset -P +; then 132 mbox_names=( "${(@)_mh_cache#$~maildirectory/}" ) 133 elif compset -P @; then 134 mbox_names=( "${(@)${(@M)_mh_cache:#$~lastmhbox/*}#$~lastmhbox/}" ) 135 else 136 mbox_names=( +"${(@)^_mh_cache#$~maildirectory/}" 137 @"${(@)^${(@M)_mh_cache:#$~lastmhbox/*}#$~lastmhbox/}" 138 "${_mh_cache[@]}" ) 139 fi 140 ;; 141 (*:mush:*) 142 if compset -P %; then 143 mbox_short=( "${(@k)userdirs}" ) 144 elif compset -P +; then 145 mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) 146 else 147 mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" 148 "${_mailbox_cache[@]}" ) 149 mbox_short=( \& % %"${(@k)^userdirs}" ) 150 fi 151 ;; 152 (*:mutt:*) 153 if compset -P '(|\\)='; then 154 mbox_names=( "${_mutt_cache[@]#[+=]}" "${(@)_mbox_cache#$~maildirectory/}" "${(@)_maildir_cache#$~maildirectory/}" "${(@)_mh_cache#$~maildirectory/}") 155 elif compset -P +; then 156 mbox_names=( "${_mutt_cache[@]#[+=]}" "${(@)_mbox_cache#$~maildirectory/}" "${(@)_maildir_cache#$~maildirectory/}" "${(@)_mh_cache#$~maildirectory/}") 157 else 158 mbox_names=( "${_mutt_cache[@]}" "${_mailbox_cache[@]}" 159 "${_maildir_cache[@]}" "${_mh_cache[@]}" ) 160 mbox_short=( \! \< \> ) 161 fi 162 ;; 163 (*:pine:*) 164 mbox_names=( "${_mbox_cache[@]}" 165 "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) 166 # Pine is like mail but with no leading `+' to disambiguate; 167 # any files not in $pinedirectory must be absolute paths. 168 if [[ -n $pinedirectory ]]; then 169 mbox_names+=( "${(@)_pine_cache#$~pinedirectory/}" ) 170 fi 171 ;; 172 (*:tkrat:*) # Has a couple of custom formats I haven't programmed for. 173 mbox_names=( "${_mbox_cache[@]}" 174 "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) 175 ;; 176 (*:(zmail|zmlite):*) 177 if compset -P %; then 178 mbox_short=( "${(@k)userdirs}" ) 179 elif compset -P +; then 180 mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) 181 else 182 mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" 183 "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) 184 mbox_short=( \& % %"${(@k)^userdirs}" ) 185 fi 186 ;; 187 (*) # Some other program wants mailbox names? Use them all? 188 mbox_names=( "${_mailbox_cache[@]}" "${_mbox_cache[@]}" 189 "${_mh_cache[@]}" "${_mutt_cache[@]}" "${_pine_cache[@]}" ) 190 ;; 191 esac 192 193 (( $#mbox_names )) && _multi_parts "$@" / mbox_names && ret=0 194 (( $#mbox_short )) && compadd "$@" -a mbox_short && ret=0 195 return ret 196} 197 198_mailboxes "$@" 199