Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 0AC6C431FAF for ; Sun, 3 Mar 2013 12:59:40 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pkjq2JgMz3G0 for ; Sun, 3 Mar 2013 12:59:38 -0800 (PST) Received: from mail-lb0-f170.google.com (mail-lb0-f170.google.com [209.85.217.170]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 59E01431FAE for ; Sun, 3 Mar 2013 12:59:38 -0800 (PST) Received: by mail-lb0-f170.google.com with SMTP id ge1so3485101lbb.29 for ; Sun, 03 Mar 2013 12:59:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references:mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=Dl3ZSDg0d/O6nzFGYLdHp/xm1tlWBXnW48bI8TMvbFo=; b=Xm6N8ghAvdgnT4vvokgkaKDR89CLc8b3GDHrkac8okK1OwwyC1eG1iuP5RAdW0g0GJ 1nfzEffknAsoatW3Kmqo7qzfieTUdfDsX6PaAeiy3xKYNHIpZmc75fRsRXuu36gPFocw 7YRq1sKwGJKhTCmHxY31HcEms4QzMD9Leh+PcpdgHRxtIkm2s8qfY3PqRfYn83P/KZq3 +A9mB/RHzFFKEm+wAwnM39+u9PGfLnLaxqztUU52h/bz5jnew5Ydk8fbDgcU4ntq/7LB A8bLTEi5RjPqFPYeW2e8dBVj12RHq1zuISNxEhzdq63Am0V1IKaTCPq4hVivQwyiLjQ3 o/Ug== X-Received: by 10.152.105.17 with SMTP id gi17mr5850556lab.46.1362344376699; Sun, 03 Mar 2013 12:59:36 -0800 (PST) Received: from localhost (dsl-hkibrasgw4-50df51-27.dhcp.inet.fi. [80.223.81.27]) by mx.google.com with ESMTPS id fz16sm10670977lab.5.2013.03.03.12.59.34 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 03 Mar 2013 12:59:35 -0800 (PST) From: Jani Nikula To: notmuch@notmuchmail.org Subject: [PATCH v2] completion: complete bash completion rewrite Date: Sun, 3 Mar 2013 22:59:28 +0200 Message-Id: <1362344368-27623-1-git-send-email-jani@nikula.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1362232751-9571-1-git-send-email-jani@nikula.org> References: <1362232751-9571-1-git-send-email-jani@nikula.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Gm-Message-State: ALoCoQlqwy4HiHu7i84ZgJ7R62329lFLIXjPihe/XF+yxSW86YNNBiv4S7VFDXLqbZtOf0vZ9WYt X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Mar 2013 20:59:40 -0000 Rewrite the bash completion script to actually do something useful. Supported completions: * All the notmuch commands, command line arguments, and values for keyword arguments. * Tags after + and - in 'notmuch tag'. * Config options in 'notmuch config', and some config option values. * Search prefixes in all commands that use search terms. * Tags after tag: prefix in search terms. * User's email addresses after from: and to: in search terms. This is all based on the bash-completion package [1], and will not work without it. [1] http://bash-completion.alioth.debian.org/ --- CAVEATS: There may be dependencies on the version of the bash-completion package. I do not know, and I don't have a huge interest in finding out. That way lay dragons. Regardless, I think this is a *huge* improvement on the status quo for anyone this works for. And if it doesn't, the loss is roughly equivalent to the usefulness of the old completion script, i.e. "not much". It's also a *much* more interesting starting point for anyone wishing to improve upon. --- completion/notmuch-completion.bash | 412 +++++++++++++++++++++++++++++------- 1 file changed, 341 insertions(+), 71 deletions(-) rewrite completion/notmuch-completion.bash (66%) diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash dissimilarity index 66% index 8665268..7bd7745 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -1,71 +1,341 @@ -# Bash completion for notmuch -# -# Copyright © 2009 Carl Worth -# -# 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 -# (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 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] [...] -# -# show -# -# reply -# -# tag +|- [...] [--] [...] -# -# dump [] -# -# restore -# -# help [] - -_notmuch() -{ - local current previous commands help_options - - previous=${COMP_WORDS[COMP_CWORD-1]} - current="${COMP_WORDS[COMP_CWORD]}" - - 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=" - - COMPREPLY=() - - 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 - ;; - esac -} - -complete -o default -o bashdefault -F _notmuch notmuch +# bash completion for notmuch -*- shell-script -*- +# +# 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 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 http://www.gnu.org/licenses/ . +# +# Author: Jani Nikula +# +# +# BUGS: +# +# Add space after an --option without parameter (e.g. reply --decrypt) +# on completion. +# + +_notmuch_user_emails() +{ + notmuch config get user.primary_email + notmuch config get user.other_email +} + +_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_user_emails`" -- ${cur##to:}) ) + ;; + from:*) + COMPREPLY=( $(compgen -P "from:" -W "`_notmuch_user_emails`" -- ${cur##from:}) ) + ;; + *) + local search_terms="from: to: subject: attachment: tag: id: thread: folder: date:" + compopt -o nospace + COMPREPLY=( $(compgen -W "${search_terms}" -- ${cur}) ) + ;; + esac + # handle search prefixes and tags with colons + __ltrim_colon_completions "${cur}" +} + +_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 + ;; + 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" -- "${cur}" ) ) + return + ;; + --exclude) + COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--output= --exclude=" + 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="--format= --output=" + compopt -o nospace + COMPREPLY=( $(compgen -W "$options" -- ${cur}) ) + ;; + *) + _notmuch_search_terms + ;; + esac +} + +_notmuch_new() +{ + local cur prev words cword split + _init_completion || return + + case "${cur}" in + -*) + local options="--no-hooks" + 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" + 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=" + 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" -- "${cur}" ) ) + return + ;; + esac + + ! $split && + case "${cur}" in + -*) + local options="--format= --output= --sort= --offset= --limit= --exclude=" + 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" + 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 -n := || return + + case "${cur}" in + +*) + 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="config count dump help new reply restore search setup show tag" + local arg cur prev words cword split + _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 -- 1.7.10.4