completion: fail silently if _init_completion is not found
[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         path:*)
53             local path=`notmuch config get database.path`
54             compopt -o nospace
55             COMPREPLY=( $(compgen -d "$path/${cur##path:}" | sed "s|^$path/||" ) )
56             ;;
57         folder:*)
58             local path=`notmuch config get database.path`
59             compopt -o nospace
60             COMPREPLY=( $(compgen -d "$path/${cur##folder:}" | \
61                 sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) )
62             ;;
63         *)
64             local search_terms="from: to: subject: attachment: tag: id: thread: folder: path: date:"
65             compopt -o nospace
66             COMPREPLY=( $(compgen -W "${search_terms}" -- ${cur}) )
67             ;;
68     esac
69     # handle search prefixes and tags with colons
70     __ltrim_colon_completions "${cur}"
71 }
72
73 _notmuch_compact()
74 {
75     local cur prev words cword split
76     _init_completion -s || return
77
78     $split &&
79     case "${prev}" in
80         --backup)
81             _filedir -d
82             return
83             ;;
84     esac
85
86     ! $split &&
87     case "${cur}" in
88         -*)
89             local options="--backup= --quiet"
90             compopt -o nospace
91             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
92             ;;
93     esac
94 }
95
96 _notmuch_config()
97 {
98     local cur prev words cword split
99     _init_completion || return
100
101     case "${prev}" in
102         config)
103             COMPREPLY=( $(compgen -W "get set list" -- ${cur}) )
104             ;;
105         get|set)
106             COMPREPLY=( $(compgen -W "`notmuch config list | sed 's/=.*\$//'`" -- ${cur}) )
107             ;;
108         # these will also complete on config get, but we don't care
109         database.path)
110             _filedir -d
111             ;;
112         maildir.synchronize_flags)
113             COMPREPLY=( $(compgen -W "true false" -- ${cur}) )
114             ;;
115     esac
116 }
117
118 _notmuch_count()
119 {
120     local cur prev words cword split
121     _init_completion -s || return
122
123     $split &&
124     case "${prev}" in
125         --output)
126             COMPREPLY=( $( compgen -W "messages threads files" -- "${cur}" ) )
127             return
128             ;;
129         --exclude)
130             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
131             return
132             ;;
133         --input)
134             _filedir
135             return
136             ;;
137     esac
138
139     ! $split &&
140     case "${cur}" in
141         -*)
142             local options="--output= --exclude= --batch --input="
143             compopt -o nospace
144             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
145             ;;
146         *)
147             _notmuch_search_terms
148             ;;
149     esac
150 }
151
152 _notmuch_dump()
153 {
154     local cur prev words cword split
155     _init_completion -s || return
156
157     $split &&
158     case "${prev}" in
159         --format)
160             COMPREPLY=( $( compgen -W "sup batch-tag" -- "${cur}" ) )
161             return
162             ;;
163         --output)
164             _filedir
165             return
166             ;;
167     esac
168
169     ! $split &&
170     case "${cur}" in
171         -*)
172             local options="--format= --output="
173             compopt -o nospace
174             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
175             ;;
176         *)
177             _notmuch_search_terms
178             ;;
179     esac
180 }
181
182 _notmuch_insert()
183 {
184     local cur prev words cword split
185     # handle tags with colons and equal signs
186     _init_completion -s -n := || return
187
188     $split &&
189     case "${prev}" in
190         --folder)
191             _filedir
192             return
193             ;;
194     esac
195
196     ! $split &&
197     case "${cur}" in
198         --*)
199             local options="--create-folder --folder="
200             compopt -o nospace
201             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
202             return
203             ;;
204         +*)
205             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
206             ;;
207         -*)
208             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
209             ;;
210     esac
211     # handle tags with colons
212     __ltrim_colon_completions "${cur}"
213 }
214
215 _notmuch_new()
216 {
217     local cur prev words cword split
218     _init_completion || return
219
220     case "${cur}" in
221         -*)
222             local options="--no-hooks --quiet"
223             COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
224             ;;
225     esac
226 }
227
228 _notmuch_reply()
229 {
230     local cur prev words cword split
231     _init_completion -s || return
232
233     $split &&
234     case "${prev}" in
235         --format)
236             COMPREPLY=( $( compgen -W "default json sexp headers-only" -- "${cur}" ) )
237             return
238             ;;
239         --reply-to)
240             COMPREPLY=( $( compgen -W "all sender" -- "${cur}" ) )
241             return
242             ;;
243     esac
244
245     ! $split &&
246     case "${cur}" in
247         -*)
248             local options="--format= --format-version= --reply-to= --decrypt"
249             compopt -o nospace
250             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
251             ;;
252         *)
253             _notmuch_search_terms
254             ;;
255     esac
256 }
257
258 _notmuch_restore()
259 {
260     local cur prev words cword split
261     _init_completion -s || return
262
263     $split &&
264     case "${prev}" in
265         --format)
266             COMPREPLY=( $( compgen -W "sup batch-tag auto" -- "${cur}" ) )
267             return
268             ;;
269         --input)
270             _filedir
271             return
272             ;;
273     esac
274
275     ! $split &&
276     case "${cur}" in
277         -*)
278             local options="--format= --accumulate --input="
279             compopt -o nospace
280             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
281             ;;
282     esac
283 }
284
285 _notmuch_search()
286 {
287     local cur prev words cword split
288     _init_completion -s || return
289
290     $split &&
291     case "${prev}" in
292         --format)
293             COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) )
294             return
295             ;;
296         --output)
297             COMPREPLY=( $( compgen -W "summary threads messages files tags" -- "${cur}" ) )
298             return
299             ;;
300         --sort)
301             COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) )
302             return
303             ;;
304         --exclude)
305             COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) )
306             return
307             ;;
308     esac
309
310     ! $split &&
311     case "${cur}" in
312         -*)
313             local options="--format= --output= --sort= --offset= --limit= --exclude= --duplicate="
314             compopt -o nospace
315             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
316             ;;
317         *)
318             _notmuch_search_terms
319             ;;
320     esac
321 }
322
323 _notmuch_show()
324 {
325     local cur prev words cword split
326     _init_completion -s || return
327
328     $split &&
329     case "${prev}" in
330         --entire-thread)
331             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
332             return
333             ;;
334         --format)
335             COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
336             return
337             ;;
338         --exclude|--body)
339             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
340             return
341             ;;
342     esac
343
344     ! $split &&
345     case "${cur}" in
346         -*)
347             local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt --include-html"
348             compopt -o nospace
349             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
350             ;;
351         *)
352             _notmuch_search_terms
353             ;;
354     esac
355 }
356
357 _notmuch_tag()
358 {
359     local cur prev words cword split
360     # handle tags with colons and equal signs
361     _init_completion -s -n := || return
362
363     $split &&
364     case "${prev}" in
365         --input)
366             _filedir
367             return
368             ;;
369     esac
370
371     ! $split &&
372     case "${cur}" in
373         --*)
374             local options="--batch --input= --remove-all"
375             compopt -o nospace
376             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
377             return
378             ;;
379         +*)
380             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
381             ;;
382         -*)
383             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
384             ;;
385         *)
386             _notmuch_search_terms
387             return
388             ;;
389     esac
390     # handle tags with colons
391     __ltrim_colon_completions "${cur}"
392 }
393
394 _notmuch()
395 {
396     local _notmuch_commands="compact config count dump help insert new reply restore search setup show tag"
397     local arg cur prev words cword split
398
399     # require bash-completion with _init_completion
400     type -t _init_completion >/dev/null 2>&1 || return
401
402     _init_completion || return
403
404     COMPREPLY=()
405
406     # subcommand
407     _get_first_arg
408
409     # complete --help option like the subcommand
410     if [ -z "${arg}" -a "${prev}" = "--help" ]; then
411         arg="help"
412     fi
413
414     if [ -z "${arg}" ]; then
415         # top level completion
416         local top_options="--help --version"
417         case "${cur}" in
418             -*) COMPREPLY=( $(compgen -W "${top_options}" -- ${cur}) ) ;;
419             *) COMPREPLY=( $(compgen -W "${_notmuch_commands}" -- ${cur}) ) ;;
420         esac
421     elif [ "${arg}" = "help" ]; then
422         # handle help command specially due to _notmuch_commands usage
423         local help_topics="$_notmuch_commands hooks search-terms"
424         COMPREPLY=( $(compgen -W "${help_topics}" -- ${cur}) )
425     else
426         # complete using _notmuch_subcommand if one exist
427         local completion_func="_notmuch_${arg//-/_}"
428         declare -f $completion_func >/dev/null && $completion_func
429     fi
430 } &&
431 complete -F _notmuch notmuch