about summary refs log tree commit diff
path: root/Completion/User/_mailboxes
blob: 784bc4e6e70b8923531e39fc38ecf540203e77cb (plain) (blame)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#autoload

_mailboxes() {
  #emulate -L zsh
  local expl ret=1
  local pinedirectory="${pinedirectory:-~/mail}"
  local maildirectory="${maildirectory:-~/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;;
    (*: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|zmail|zmlite):* ]] &&
	compset -P -f
      _files "$expl[@]" && ret=0
    fi
    (( ret )) || return 0
  done

  return 1
}

_mailbox_cache () {
  # Depends on $maildirectory and $pinedirectory from _mailboxes!

  local i j muttrc="${muttrc:-~/.muttrc}"
  local -aU dirboxes
  typeset -aU -g _mailbox_cache
  typeset -aU -g _maildir_cache _mbox_cache _mh_cache _mutt_cache _pine_cache

  setopt localoptions nullglob

  [[ -f ${~muttrc:-.} ]] &&
    _mutt_cache=( ${$(grep mailboxes ${~muttrc})[2,-1]} )

  _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" )
    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() {
  # Depends on $maildirectory and $pinedirectory from _mailboxes!

  local -a mbox_short
  local -aU mbox_names
  local ret=1

  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:*) # I've probably got this wrong, or at least incomplete
      (( $#_mh_cache )) && _multi_parts "${expl[@]}" / _mh_cache && ret=0
      ;;
    (*: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:*)
      mbox_names=( "${_mutt_cache[@]}" "${_mailbox_cache[@]}"
		   "${_maildir_cache[@]}" )
      mbox_short=( \! \< \> );;
    (*: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 "$@" - "$mbox_short[@]" && ret=0
  return ret
}

[[ -o kshautoload ]] || _mailboxes "$@"