db152f358bc3bebc7a6a659332255b5b6c09f42e
[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_address()
324 {
325     local cur prev words cword split
326     _init_completion -s || return
327
328     $split &&
329     case "${prev}" in
330         --format)
331             COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) )
332             return
333             ;;
334         --output)
335             COMPREPLY=( $( compgen -W "sender recipients count" -- "${cur}" ) )
336             return
337             ;;
338         --sort)
339             COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) )
340             return
341             ;;
342         --exclude)
343             COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) )
344             return
345             ;;
346     esac
347
348     ! $split &&
349     case "${cur}" in
350         -*)
351             local options="--format= --output= --sort= --exclude="
352             compopt -o nospace
353             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
354             ;;
355         *)
356             _notmuch_search_terms
357             ;;
358     esac
359 }
360
361 _notmuch_show()
362 {
363     local cur prev words cword split
364     _init_completion -s || return
365
366     $split &&
367     case "${prev}" in
368         --entire-thread)
369             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
370             return
371             ;;
372         --format)
373             COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
374             return
375             ;;
376         --exclude|--body)
377             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
378             return
379             ;;
380     esac
381
382     ! $split &&
383     case "${cur}" in
384         -*)
385             local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt --include-html"
386             compopt -o nospace
387             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
388             ;;
389         *)
390             _notmuch_search_terms
391             ;;
392     esac
393 }
394
395 _notmuch_tag()
396 {
397     local cur prev words cword split
398     # handle tags with colons and equal signs
399     _init_completion -s -n := || return
400
401     $split &&
402     case "${prev}" in
403         --input)
404             _filedir
405             return
406             ;;
407     esac
408
409     ! $split &&
410     case "${cur}" in
411         --*)
412             local options="--batch --input= --remove-all"
413             compopt -o nospace
414             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
415             return
416             ;;
417         +*)
418             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
419             ;;
420         -*)
421             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
422             ;;
423         *)
424             _notmuch_search_terms
425             return
426             ;;
427     esac
428     # handle tags with colons
429     __ltrim_colon_completions "${cur}"
430 }
431
432 _notmuch()
433 {
434     local _notmuch_commands="compact config count dump help insert new reply restore search address setup show tag"
435     local arg cur prev words cword split
436
437     # require bash-completion with _init_completion
438     type -t _init_completion >/dev/null 2>&1 || return
439
440     _init_completion || return
441
442     COMPREPLY=()
443
444     # subcommand
445     _get_first_arg
446
447     # complete --help option like the subcommand
448     if [ -z "${arg}" -a "${prev}" = "--help" ]; then
449         arg="help"
450     fi
451
452     if [ -z "${arg}" ]; then
453         # top level completion
454         local top_options="--help --version"
455         case "${cur}" in
456             -*) COMPREPLY=( $(compgen -W "${top_options}" -- ${cur}) ) ;;
457             *) COMPREPLY=( $(compgen -W "${_notmuch_commands}" -- ${cur}) ) ;;
458         esac
459     elif [ "${arg}" = "help" ]; then
460         # handle help command specially due to _notmuch_commands usage
461         local help_topics="$_notmuch_commands hooks search-terms"
462         COMPREPLY=( $(compgen -W "${help_topics}" -- ${cur}) )
463     else
464         # complete using _notmuch_subcommand if one exist
465         local completion_func="_notmuch_${arg//-/_}"
466         declare -f $completion_func >/dev/null && $completion_func
467     fi
468 } &&
469 complete -F _notmuch notmuch