about summary refs log tree commit diff
path: root/Completion/Unix/Type/_mailboxes
blob: d3c60790dc4759500ebd5884e0d57aeaebd29a0c (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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#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 "$@"