completion: complete bash completion rewrite
[notmuch] / completion / notmuch-completion.bash
1 # bash completion for notmuch                              -*- shell-script -*-
2 #
3 # Copyright © 2013 Jani Nikula
4 #
5 # Based on the bash-completion package:
6 # http://bash-completion.alioth.debian.org/
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see http://www.gnu.org/licenses/ .
20 #
21 # Author: Jani Nikula <jani@nikula.org>
22 #
23 #
24 # BUGS:
25 #
26 # Add space after an --option without parameter (e.g. reply --decrypt)
27 # on completion.
28 #
29
30 _notmuch_user_emails()
31 {
32     notmuch config get user.primary_email
33     notmuch config get user.other_email
34 }
35
36 _notmuch_search_terms()
37 {
38     local cur prev words cword split
39     # handle search prefixes and tags with colons and equal signs
40     _init_completion -n := || return
41
42     case "${cur}" in
43         tag:*)
44             COMPREPLY=( $(compgen -P "tag:" -W "`notmuch search --output=tags \*`" -- ${cur##tag:}) )
45             ;;
46         to:*)
47             COMPREPLY=( $(compgen -P "to:" -W "`_notmuch_user_emails`" -- ${cur##to:}) )
48             ;;
49         from:*)
50             COMPREPLY=( $(compgen -P "from:" -W "`_notmuch_user_emails`" -- ${cur##from:}) )
51             ;;
52         *)
53             local search_terms="from: to: subject: attachment: tag: id: thread: folder: date:"
54             compopt -o nospace
55             COMPREPLY=( $(compgen -W "${search_terms}" -- ${cur}) )
56             ;;
57     esac
58     # handle search prefixes and tags with colons
59     __ltrim_colon_completions "${cur}"
60 }
61
62 _notmuch_config()
63 {
64     local cur prev words cword split
65     _init_completion || return
66
67     case "${prev}" in
68         config)
69             COMPREPLY=( $(compgen -W "get set list" -- ${cur}) )
70             ;;
71         get|set)
72             COMPREPLY=( $(compgen -W "`notmuch config list | sed 's/=.*\$//'`" -- ${cur}) )
73             ;;
74         # these will also complete on config get, but we don't care
75         database.path)
76             _filedir
77             ;;
78         maildir.synchronize_flags)
79             COMPREPLY=( $(compgen -W "true false" -- ${cur}) )
80             ;;
81     esac
82 }
83
84 _notmuch_count()
85 {
86     local cur prev words cword split
87     _init_completion -s || return
88
89     $split &&
90     case "${prev}" in
91         --output)
92             COMPREPLY=( $( compgen -W "messages threads" -- "${cur}" ) )
93             return
94             ;;
95         --exclude)
96             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
97             return
98             ;;
99     esac
100
101     ! $split &&
102     case "${cur}" in
103         -*)
104             local options="--output= --exclude="
105             compopt -o nospace
106             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
107             ;;
108         *)
109             _notmuch_search_terms
110             ;;
111     esac
112 }
113
114 _notmuch_dump()
115 {
116     local cur prev words cword split
117     _init_completion -s || return
118
119     $split &&
120     case "${prev}" in
121         --format)
122             COMPREPLY=( $( compgen -W "sup batch-tag" -- "${cur}" ) )
123             return
124             ;;
125         --output)
126             _filedir
127             return
128             ;;
129     esac
130
131     ! $split &&
132     case "${cur}" in
133         -*)
134             local options="--format= --output="
135             compopt -o nospace
136             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
137             ;;
138         *)
139             _notmuch_search_terms
140             ;;
141     esac
142 }
143
144 _notmuch_new()
145 {
146     local cur prev words cword split
147     _init_completion || return
148
149     case "${cur}" in
150         -*)
151             local options="--no-hooks"
152             COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
153             ;;
154     esac
155 }
156
157 _notmuch_reply()
158 {
159     local cur prev words cword split
160     _init_completion -s || return
161
162     $split &&
163     case "${prev}" in
164         --format)
165             COMPREPLY=( $( compgen -W "default json sexp headers-only" -- "${cur}" ) )
166             return
167             ;;
168         --reply-to)
169             COMPREPLY=( $( compgen -W "all sender" -- "${cur}" ) )
170             return
171             ;;
172     esac
173
174     ! $split &&
175     case "${cur}" in
176         -*)
177             local options="--format= --format-version= --reply-to= --decrypt"
178             compopt -o nospace
179             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
180             ;;
181         *)
182             _notmuch_search_terms
183             ;;
184     esac
185 }
186
187 _notmuch_restore()
188 {
189     local cur prev words cword split
190     _init_completion -s || return
191
192     $split &&
193     case "${prev}" in
194         --format)
195             COMPREPLY=( $( compgen -W "sup batch-tag auto" -- "${cur}" ) )
196             return
197             ;;
198         --input)
199             _filedir
200             return
201             ;;
202     esac
203
204     ! $split &&
205     case "${cur}" in
206         -*)
207             local options="--format= --accumulate --input="
208             compopt -o nospace
209             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
210             ;;
211     esac
212 }
213
214 _notmuch_search()
215 {
216     local cur prev words cword split
217     _init_completion -s || return
218
219     $split &&
220     case "${prev}" in
221         --format)
222             COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) )
223             return
224             ;;
225         --output)
226             COMPREPLY=( $( compgen -W "summary threads messages files tags" -- "${cur}" ) )
227             return
228             ;;
229         --sort)
230             COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) )
231             return
232             ;;
233         --exclude)
234             COMPREPLY=( $( compgen -W "true false flag" -- "${cur}" ) )
235             return
236             ;;
237     esac
238
239     ! $split &&
240     case "${cur}" in
241         -*)
242             local options="--format= --output= --sort= --offset= --limit= --exclude="
243             compopt -o nospace
244             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
245             ;;
246         *)
247             _notmuch_search_terms
248             ;;
249     esac
250 }
251
252 _notmuch_show()
253 {
254     local cur prev words cword split
255     _init_completion -s || return
256
257     $split &&
258     case "${prev}" in
259         --entire-thread)
260             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
261             return
262             ;;
263         --format)
264             COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
265             return
266             ;;
267         --exclude|--body)
268             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
269             return
270             ;;
271     esac
272
273     ! $split &&
274     case "${cur}" in
275         -*)
276             local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt"
277             compopt -o nospace
278             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
279             ;;
280         *)
281             _notmuch_search_terms
282             ;;
283     esac
284 }
285
286 _notmuch_tag()
287 {
288     local cur prev words cword split
289     # handle tags with colons and equal signs
290     _init_completion -n := || return
291
292     case "${cur}" in
293         +*)
294             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
295             ;;
296         -*)
297             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
298             ;;
299         *)
300             _notmuch_search_terms
301             return
302             ;;
303     esac
304     # handle tags with colons
305     __ltrim_colon_completions "${cur}"
306 }
307
308 _notmuch()
309 {
310     local _notmuch_commands="config count dump help new reply restore search setup show tag"
311     local arg cur prev words cword split
312     _init_completion || return
313
314     COMPREPLY=()
315
316     # subcommand
317     _get_first_arg
318
319     # complete --help option like the subcommand
320     if [ -z "${arg}" -a "${prev}" = "--help" ]; then
321         arg="help"
322     fi
323
324     if [ -z "${arg}" ]; then
325         # top level completion
326         local top_options="--help --version"
327         case "${cur}" in
328             -*) COMPREPLY=( $(compgen -W "${top_options}" -- ${cur}) ) ;;
329             *) COMPREPLY=( $(compgen -W "${_notmuch_commands}" -- ${cur}) ) ;;
330         esac
331     elif [ "${arg}" = "help" ]; then
332         # handle help command specially due to _notmuch_commands usage
333         local help_topics="$_notmuch_commands hooks search-terms"
334         COMPREPLY=( $(compgen -W "${help_topics}" -- ${cur}) )
335     else
336         # complete using _notmuch_subcommand if one exist
337         local completion_func="_notmuch_${arg//-/_}"
338         declare -f $completion_func >/dev/null && $completion_func
339     fi
340 } &&
341 complete -F _notmuch notmuch