notmuch/completion/notmuch-completion.bash
Daniel Kahn Gillmor 6a833a6e83 Use https instead of http where possible
Many of the external links found in the notmuch source can be resolved
using https instead of http.  This changeset addresses as many as i
could find, without touching the e-mail corpus or expected outputs
found in tests.
2016-06-05 08:32:17 -03:00

507 lines
12 KiB
Bash

# bash completion for notmuch -*- shell-script -*-
#
# Copyright © 2013 Jani Nikula
#
# Based on the bash-completion package:
# https://github.com/scop/bash-completion
#
# 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 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see https://www.gnu.org/licenses/ .
#
# Author: Jani Nikula <jani@nikula.org>
#
#
# BUGS:
#
# Add space after an --option without parameter (e.g. reply --decrypt)
# on completion.
#
_notmuch_shared_options="--help --uuid= --version"
# $1: current input of the form prefix:partialinput, where prefix is
# to or from.
_notmuch_email()
{
local output prefix cur
prefix="${1%%:*}"
cur="${1#*:}"
# 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]*}"
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: lastmod:"
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}"
}
_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
}
_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
case "${cur}" in
-*)
# XXX: handle ${_notmuch_shared_options} and --config=
local options="--help --version"
COMPREPLY=( $(compgen -W "${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