X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=completion%2Fnotmuch-completion.bash;h=1356c4a40515ffb86ffd222ec8b13a723877a166;hp=8665268c789eda9b789849bf999d59f0a4f87aa3;hb=cd4814ecb35c63152aced04fcb82e5facf1463ca;hpb=7d9851e293fad762cd959e9be819e48a26087cdc diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index 8665268c..1356c4a4 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -1,10 +1,13 @@ -# Bash completion for notmuch +# bash completion for notmuch -*- shell-script -*- # -# Copyright © 2009 Carl Worth +# Copyright © 2013 Jani Nikula +# +# Based on the bash-completion package: +# http://bash-completion.alioth.debian.org/ # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or +# the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -15,57 +18,485 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ . # -# Author: Carl Worth -# -# Based on "notmuch help" as follows: -# -# Usage: notmuch [args...] -# -# Where and [args...] are as follows: -# -# setup -# -# new -# -# search [options] [...] +# Author: Jani Nikula # -# show # -# reply +# BUGS: # -# tag +|- [...] [--] [...] +# Add space after an --option without parameter (e.g. reply --decrypt) +# on completion. # -# dump [] -# -# restore -# -# help [] -_notmuch() +_notmuch_shared_options="--help --uuid= --version" + +# $1: current input of the form prefix:partialinput, where prefix is +# to or from. +_notmuch_email() { - local current previous commands help_options + local output prefix cur - previous=${COMP_WORDS[COMP_CWORD-1]} - current="${COMP_WORDS[COMP_CWORD]}" + prefix="${1%%:*}" + cur="${1#*:}" - commands="setup new search show reply tag dump restore help" - help_options="setup new search show reply tag dump restore search-terms" - search_options="--max-threads= --first= --sort=" + # Cut the input to be completed at punctuation because + # (apparently) Xapian does not support the trailing wildcard '*' + # operator for input with punctuation. We let compgen handle the + # extra filtering required. + cur="${cur%%[^a-zA-Z0-9]*}" - COMPREPLY=() + case "$prefix" in + # Note: It would be more accurate and less surprising to have + # output=recipients here for to: addresses, but as gathering + # the recipient addresses requires disk access for each + # matching message, this becomes prohibitively slow. + to|from) output=sender;; + *) return;; + esac + + # Only emit plain, lower case, unique addresses. + notmuch address --output=$output $prefix:"${cur}*" | \ + sed 's/[^<]*<\([^>]*\)>/\1/' | tr "[:upper:]" "[:lower:]" | sort -u +} + +_notmuch_search_terms() +{ + local cur prev words cword split + # handle search prefixes and tags with colons and equal signs + _init_completion -n := || return + + case "${cur}" in + tag:*) + COMPREPLY=( $(compgen -P "tag:" -W "`notmuch search --output=tags \*`" -- ${cur##tag:}) ) + ;; + to:*) + COMPREPLY=( $(compgen -P "to:" -W "`_notmuch_email ${cur}`" -- ${cur##to:}) ) + ;; + from:*) + COMPREPLY=( $(compgen -P "from:" -W "`_notmuch_email ${cur}`" -- ${cur##from:}) ) + ;; + path:*) + local path=`notmuch config get database.path` + compopt -o nospace + COMPREPLY=( $(compgen -d "$path/${cur##path:}" | sed "s|^$path/||" ) ) + ;; + folder:*) + local path=`notmuch config get database.path` + compopt -o nospace + COMPREPLY=( $(compgen -d "$path/${cur##folder:}" | \ + sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) ) + ;; + *) + local search_terms="from: to: subject: attachment: mimetype: tag: id: thread: folder: path: date:" + compopt -o nospace + COMPREPLY=( $(compgen -W "${search_terms}" -- ${cur}) ) + ;; + esac + # handle search prefixes and tags with colons + __ltrim_colon_completions "${cur}" +} + +_notmuch_compact() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --backup) + _filedir -d + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--backup= --quiet ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + esac +} + +_notmuch_config() +{ + local cur prev words cword split + _init_completion || return + + case "${prev}" in + config) + COMPREPLY=( $(compgen -W "get set list" -- ${cur}) ) + ;; + get|set) + COMPREPLY=( $(compgen -W "`notmuch config list | sed 's/=.*\$//'`" -- ${cur}) ) + ;; + # these will also complete on config get, but we don't care + database.path) + _filedir -d + ;; + maildir.synchronize_flags) + COMPREPLY=( $(compgen -W "true false" -- ${cur}) ) + ;; + esac +} + +_notmuch_count() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --output) + COMPREPLY=( $( compgen -W "messages threads files" -- "${cur}" ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) + return + ;; + --input) + _filedir + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--output= --exclude= --batch --input= --lastmod ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_dump() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --format) + COMPREPLY=( $( compgen -W "sup batch-tag" -- "${cur}" ) ) + return + ;; + --output) + _filedir + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--gzip --format= --output= ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_insert() +{ + local cur prev words cword split + # handle tags with colons and equal signs + _init_completion -s -n := || return + + $split && + case "${prev}" in + --folder) + local path=`notmuch config get database.path` + compopt -o nospace + COMPREPLY=( $(compgen -d "$path/${cur}" | \ + sed "s|^$path/||" | grep -v "\(^\|/\)\(cur\|new\|tmp\)$" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + --*) + local options="--create-folder --folder= --keep --no-hooks ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + return + ;; + +*) + COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) ) + ;; + -*) + COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) ) + ;; + esac + # handle tags with colons + __ltrim_colon_completions "${cur}" +} - case $COMP_CWORD in - 1) - COMPREPLY=( $(compgen -W "${commands}" -- ${current}) ) ;; - 2) - case $previous in - help) - COMPREPLY=( $(compgen -W "${help_options}" -- ${current}) ) ;; - search) - COMPREPLY=( $(compgen -W "${search_options}" -- ${current}) ) ;; - esac - ;; +_notmuch_new() +{ + local cur prev words cword split + _init_completion || return + + case "${cur}" in + -*) + local options="--no-hooks --quiet ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "${options}" -- ${cur}) ) + ;; + esac +} + +_notmuch_reply() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --format) + COMPREPLY=( $( compgen -W "default json sexp headers-only" -- "${cur}" ) ) + return + ;; + --reply-to) + COMPREPLY=( $( compgen -W "all sender" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--format= --format-version= --reply-to= --decrypt ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; esac } -complete -o default -o bashdefault -F _notmuch notmuch +_notmuch_restore() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --format) + COMPREPLY=( $( compgen -W "sup batch-tag auto" -- "${cur}" ) ) + return + ;; + --input) + _filedir + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--format= --accumulate --input= ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + esac +} + +_notmuch_search() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --format) + COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) ) + return + ;; + --output) + COMPREPLY=( $( compgen -W "summary threads messages files tags" -- "${cur}" ) ) + return + ;; + --sort) + COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--format= --output= --sort= --offset= --limit= --exclude= --duplicate= ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_address() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --format) + COMPREPLY=( $( compgen -W "json sexp text text0" -- "${cur}" ) ) + return + ;; + --output) + COMPREPLY=( $( compgen -W "sender recipients count" -- "${cur}" ) ) + return + ;; + --sort) + COMPREPLY=( $( compgen -W "newest-first oldest-first" -- "${cur}" ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W "true false flag all" -- "${cur}" ) ) + return + ;; + --deduplicate) + COMPREPLY=( $( compgen -W "no mailbox address" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--format= --output= --sort= --exclude= --deduplicate= ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_show() +{ + local cur prev words cword split + _init_completion -s || return + + $split && + case "${prev}" in + --entire-thread) + COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) + return + ;; + --format) + COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) ) + return + ;; + --exclude|--body) + COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--entire-thread= --format= --exclude= --body= --format-version= --part= --verify --decrypt --include-html ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_tag() +{ + local cur prev words cword split + # handle tags with colons and equal signs + _init_completion -s -n := || return + + $split && + case "${prev}" in + --input) + _filedir + return + ;; + esac + + ! $split && + case "${cur}" in + --*) + local options="--batch --input= --remove-all ${_notmuch_shared_options}" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + return + ;; + +*) + COMPREPLY=( $(compgen -P "+" -W "`notmuch search --output=tags \*`" -- ${cur##+}) ) + ;; + -*) + COMPREPLY=( $(compgen -P "-" -W "`notmuch search --output=tags \*`" -- ${cur##-}) ) + ;; + *) + _notmuch_search_terms + return + ;; + esac + # handle tags with colons + __ltrim_colon_completions "${cur}" +} + +_notmuch() +{ + local _notmuch_commands="compact config count dump help insert new reply restore search address setup show tag" + local arg cur prev words cword split + + # require bash-completion with _init_completion + type -t _init_completion >/dev/null 2>&1 || return + + _init_completion || return + + COMPREPLY=() + + # subcommand + _get_first_arg + + # complete --help option like the subcommand + if [ -z "${arg}" -a "${prev}" = "--help" ]; then + arg="help" + fi + + if [ -z "${arg}" ]; then + # top level completion + local top_options="--help --version" + case "${cur}" in + -*) COMPREPLY=( $(compgen -W "${top_options}" -- ${cur}) ) ;; + *) COMPREPLY=( $(compgen -W "${_notmuch_commands}" -- ${cur}) ) ;; + esac + elif [ "${arg}" = "help" ]; then + # handle help command specially due to _notmuch_commands usage + local help_topics="$_notmuch_commands hooks search-terms" + COMPREPLY=( $(compgen -W "${help_topics}" -- ${cur}) ) + else + # complete using _notmuch_subcommand if one exist + local completion_func="_notmuch_${arg//-/_}" + declare -f $completion_func >/dev/null && $completion_func + fi +} && +complete -F _notmuch notmuch