#autoload _mailboxes() { #emulate -L zsh local expl ret=1 local maildirectory pinedirectory zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory || pinedirectory="~/mail" if (( ! $+_mailbox_cache )) then _mailbox_cache "$@" fi case "${curcontext}:" in (*:mail:*) if [[ "$PREFIX" == +* ]]; then _tags mailboxes else _tags mailboxes files fi;; (*:(mush|zmail|zmlite):*) if [[ "$PREFIX" == [%+]* ]]; then _tags mailboxes else _tags mailboxes files fi;; (*:mutt:*) if [[ "$PREFIX" == (|-f)[+=]* ]]; then _tags mailboxes else _tags mailboxes files fi;; (*:pine:*) # Files for pine must be absolute paths. if [[ "$PREFIX" == (|-f)[/\~]* ]]; then pinedirectory='' _tags mailboxes files else _tags mailboxes fi;; (*) if [[ "$PREFIX" == (|-f)+* ]]; then _tags mailboxes else _tags mailboxes files fi;; esac while _tags; do _requested mailboxes expl 'mailbox specification' _mua_mailboxes && ret=0 if _requested files expl 'mailbox file'; then [[ "${curcontext}:" != *:(mail|mush|mutt|zmail|zmlite):* ]] && compset -P -f _files "$expl[@]" && ret=0 fi (( ret )) || return 0 done return 1 } _mailbox_cache () { local i j _mc_tmp local -aU dirboxes local maildirectory pinedirectory muttrc typeset -aU -g _mailbox_cache typeset -aU -g _maildir_cache _mbox_cache _mh_cache _mutt_cache _pine_cache zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory || pinedirectory="~/mail" zstyle -s ":completion:${curcontext}:" muttrc muttrc || muttrc="~/.muttrc" [[ -f ${~muttrc:-.} ]] && _mc_tmp=${=${(M)${(f)"$(<${~muttrc})"}:#mailboxes *}#mailboxes *} && _mutt_cache=( ${=${(Xe)_mc_tmp}} ) _mbox_cache=( ${~maildirectory}/*(^/) ) _pine_cache=( ${~pinedirectory}/**/*(.) ) dirboxes=( ${~maildirectory}/*(/) ) while (( $#dirboxes )); do i=${dirboxes[1]} shift dirboxes if [[ -d "$i/cur" ]]; then _maildir_cache=( "${_maildir_cache[@]}" "$i" ) elif j=( "$i"/<1-> ) && [[ -n "$j" ]]; then _mh_cache=( "${_mh_cache[@]}" "$i" ) dirboxes=( $dirboxes "$i"/*(/) ) else _mbox_cache=( "${_mbox_cache[@]}" "$i"/*(.) ) dirboxes=( $dirboxes "$i"/*(/) ) fi done [[ -n "$mailpath" ]] && _mailbox_cache=( "${_mailbox_cache[@]}" "${(@)mailpath%%\?*}" ) [[ -n "$MAIL" ]] && _mailbox_cache=( "${_mailbox_cache[@]}" $MAIL ) } _mua_mailboxes() { local -a mbox_short local -aU mbox_names local ret=1 local maildirectory pinedirectory zstyle -s ":completion:${curcontext}:" mail-directory maildirectory || maildirectory="~/Mail" zstyle -s ":completion:${curcontext}:" pine-directory pinedirectory || pinedirectory="~/mail" case "${curcontext}:" in (*:elm:*) # I've probably got this wrong, or at least incomplete mbox_names=( "${_mbox_cache[@]}" "${_mailbox_cache[@]}" ) mbox_short=( \! \< \> ) ;; (*:mail:*) if compset -P +; then mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) else mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" "${_mailbox_cache[@]}" ) fi ;; (*:mh:*) local lastmhbox=$(mhpath) if compset -P +; then mbox_names=( "${(@)_mh_cache#$~maildirectory/}" ) elif compset -P @; then mbox_names=( "${(@)${(@M)_mh_cache:#$~lastmhbox/*}#$~lastmhbox/}" ) else mbox_names=( +"${(@)^_mh_cache#$~maildirectory/}" @"${(@)^${(@M)_mh_cache:#$~lastmhbox/*}#$~lastmhbox/}" "${_mh_cache[@]}" ) fi ;; (*:mush:*) if compset -P %; then mbox_short=( "${(@k)userdirs}" ) elif compset -P +; then mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) else mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" "${_mailbox_cache[@]}" ) mbox_short=( \& % %"${(@k)^userdirs}" ) fi ;; (*:mutt:*) if compset -P '='; then mbox_names=( "${_mutt_cache[@]#[+=]}" "${(@)_mbox_cache#$~maildirectory/}" "${(@)_maildir_cache#$~maildirectory/}" "${(@)_mh_cache#$~maildirectory/}") elif compset -P +; then mbox_names=( "${_mutt_cache[@]#[+=]}" "${(@)_mbox_cache#$~maildirectory/}" "${(@)_maildir_cache#$~maildirectory/}" "${(@)_mh_cache#$~maildirectory/}") else mbox_names=( "${_mutt_cache[@]}" "${_mailbox_cache[@]}" "${_maildir_cache[@]}" "${_mh_cache[@]}" ) mbox_short=( \! \< \> ) fi ;; (*:pine:*) # Pine is like mail but with no leading `+' to disambiguate; # any files not in $pinedirectory must be absolute paths. mbox_names=( "${(@)_pine_cache#$~pinedirectory/}" "${_mbox_cache[@]}" "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) ;; (*:tkrat:*) # Has a couple of custom formats I haven't programmed for. mbox_names=( "${_mbox_cache[@]}" "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) ;; (*:(zmail|zmlite):*) if compset -P %; then mbox_short=( "${(@k)userdirs}" ) elif compset -P +; then mbox_names=( "${(@)_mbox_cache#$~maildirectory/}" ) else mbox_names=( +"${(@)^_mbox_cache#$~maildirectory/}" "${_mailbox_cache[@]}" "${_mh_cache[@]}" ) mbox_short=( \& % %"${(@k)^userdirs}" ) fi ;; (*) # Some other program wants mailbox names? Use them all? mbox_names=( "${_mailbox_cache[@]}" "${_mbox_cache[@]}" "${_mh_cache[@]}" "${_mutt_cache[@]}" "${_pine_cache[@]}" ) ;; esac (( $#mbox_names )) && _multi_parts "$@" / mbox_names && ret=0 (( $#mbox_short )) && compadd "$@" -a mbox_short && ret=0 return ret } _mailboxes "$@"