39320f8d8107681e6be8d644c1f0fe3309da16ca
[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: mimetype: 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             local path=`notmuch config get database.path`
192             compopt -o nospace
193             COMPREPLY=( $(compgen -d "$path/${cur}" | \
194                 sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) )
195             return
196             ;;
197     esac
198
199     ! $split &&
200     case "${cur}" in
201         --*)
202             local options="--create-folder --folder= --keep --no-hooks"
203             compopt -o nospace
204             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
205             return
206             ;;
207         +*)
208             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
209             ;;
210         -*)
211             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
212             ;;
213     esac
214     # handle tags with colons
215     __ltrim_colon_completions "${cur}"
216 }
217
218 _notmuch_new()
219 {
220     local cur prev words cword split
221     _init_completion || return
222
223     case "${cur}" in
224         -*)
225             local options="--no-hooks --quiet"
226             COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
227             ;;
228     esac
229 }
230
231 _notmuch_reply()
232 {
233     local cur prev words cword split
234     _init_completion -s || return
235
236     $split &&
237     case "${prev}" in
238         --format)
239             COMPREPLY=( $( compgen -W "default json sexp headers-only" -- "${cur}" ) )
240             return
241             ;;
242         --reply-to)
243             COMPREPLY=( $( compgen -W "all sender" -- "${cur}" ) )
244             return
245             ;;
246     esac
247
248     ! $split &&
249     case "${cur}" in
250         -*)
251             local options="--format= --format-version= --reply-to= --decrypt"
252             compopt -o nospace
253             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
254             ;;
255         *)
256             _notmuch_search_terms
257             ;;
258     esac
259 }
260
261 _notmuch_restore()
262 {
263     local cur prev words cword split
264     _init_completion -s || return
265
266     $split &&
267     case "${prev}" in
268         --format)
269             COMPREPLY=( $( compgen -W "sup batch-tag auto" -- "${cur}" ) )
270             return
271             ;;
272         --input)
273             _filedir
274             return
275             ;;
276     esac
277
278     ! $split &&
279     case "${cur}" in
280         -*)
281             local options="--format= --accumulate --input="
282             compopt -o nospace
283             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
284             ;;
285     esac
286 }
287
288 _notmuch_search()
289 {
290     local cur prev words cword split
291     _init_completion -s || return
292
293     $split &&
294     case "${prev}" in
295         --format)
296             COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) )
297             return
298             ;;
299         --output)
300             COMPREPLY=( $( compgen -W "summary threads messages files tags" -- "${cur}" ) )
301             return
302             ;;
303         --sort)
304             COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) )
305             return
306             ;;
307         --exclude)
308             COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) )
309             return
310             ;;
311     esac
312
313     ! $split &&
314     case "${cur}" in
315         -*)
316             local options="--format= --output= --sort= --offset= --limit= --exclude= --duplicate="
317             compopt -o nospace
318             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
319             ;;
320         *)
321             _notmuch_search_terms
322             ;;
323     esac
324 }
325
326 _notmuch_address()
327 {
328     local cur prev words cword split
329     _init_completion -s || return
330
331     $split &&
332     case "${prev}" in
333         --format)
334             COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) )
335             return
336             ;;
337         --output)
338             COMPREPLY=( $( compgen -W "sender recipients count" -- "${cur}" ) )
339             return
340             ;;
341         --sort)
342             COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) )
343             return
344             ;;
345         --exclude)
346             COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) )
347             return
348             ;;
349     esac
350
351     ! $split &&
352     case "${cur}" in
353         -*)
354             local options="--format= --output= --sort= --exclude="
355             compopt -o nospace
356             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
357             ;;
358         *)
359             _notmuch_search_terms
360             ;;
361     esac
362 }
363
364 _notmuch_show()
365 {
366     local cur prev words cword split
367     _init_completion -s || return
368
369     $split &&
370     case "${prev}" in
371         --entire-thread)
372             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
373             return
374             ;;
375         --format)
376             COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
377             return
378             ;;
379         --exclude|--body)
380             COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
381             return
382             ;;
383     esac
384
385     ! $split &&
386     case "${cur}" in
387         -*)
388             local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt --include-html"
389             compopt -o nospace
390             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
391             ;;
392         *)
393             _notmuch_search_terms
394             ;;
395     esac
396 }
397
398 _notmuch_tag()
399 {
400     local cur prev words cword split
401     # handle tags with colons and equal signs
402     _init_completion -s -n := || return
403
404     $split &&
405     case "${prev}" in
406         --input)
407             _filedir
408             return
409             ;;
410     esac
411
412     ! $split &&
413     case "${cur}" in
414         --*)
415             local options="--batch --input= --remove-all"
416             compopt -o nospace
417             COMPREPLY=( $(compgen -W "$options" -- ${cur}) )
418             return
419             ;;
420         +*)
421             COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) )
422             ;;
423         -*)
424             COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) )
425             ;;
426         *)
427             _notmuch_search_terms
428             return
429             ;;
430     esac
431     # handle tags with colons
432     __ltrim_colon_completions "${cur}"
433 }
434
435 _notmuch()
436 {
437     local _notmuch_commands="compact config count dump help insert new reply restore search address setup show tag"
438     local arg cur prev words cword split
439
440     # require bash-completion with _init_completion
441     type -t _init_completion >/dev/null 2>&1 || return
442
443     _init_completion || return
444
445     COMPREPLY=()
446
447     # subcommand
448     _get_first_arg
449
450     # complete --help option like the subcommand
451     if [ -z "${arg}" -a "${prev}" = "--help" ]; then
452         arg="help"
453     fi
454
455     if [ -z "${arg}" ]; then
456         # top level completion
457         local top_options="--help --version"
458         case "${cur}" in
459             -*) COMPREPLY=( $(compgen -W "${top_options}" -- ${cur}) ) ;;
460             *) COMPREPLY=( $(compgen -W "${_notmuch_commands}" -- ${cur}) ) ;;
461         esac
462     elif [ "${arg}" = "help" ]; then
463         # handle help command specially due to _notmuch_commands usage
464         local help_topics="$_notmuch_commands hooks search-terms"
465         COMPREPLY=( $(compgen -W "${help_topics}" -- ${cur}) )
466     else
467         # complete using _notmuch_subcommand if one exist
468         local completion_func="_notmuch_${arg//-/_}"
469         declare -f $completion_func >/dev/null && $completion_func
470     fi
471 } &&
472 complete -F _notmuch notmuch