From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <markwalters1009@gmail.com>
Received: from localhost (localhost [127.0.0.1])
 by arlo.cworth.org (Postfix) with ESMTP id 3A6656DE0FD2
 for <notmuch@notmuchmail.org>; Sun, 18 Sep 2016 10:04:40 -0700 (PDT)
X-Virus-Scanned: Debian amavisd-new at cworth.org
X-Spam-Flag: NO
X-Spam-Score: -0.368
X-Spam-Level: 
X-Spam-Status: No, score=-0.368 tagged_above=-999 required=5 tests=[AWL=0.202, 
 DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,
 FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001,
 RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01,
 RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=disabled
Received: from arlo.cworth.org ([127.0.0.1])
 by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id RnphPJleBdDM for <notmuch@notmuchmail.org>;
 Sun, 18 Sep 2016 10:04:39 -0700 (PDT)
Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68])
 by arlo.cworth.org (Postfix) with ESMTPS id 5D6D06DE0FB6
 for <notmuch@notmuchmail.org>; Sun, 18 Sep 2016 10:04:39 -0700 (PDT)
Received: by mail-wm0-f68.google.com with SMTP id l132so10200617wmf.1
 for <notmuch@notmuchmail.org>; Sun, 18 Sep 2016 10:04:39 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;
 h=from:to:cc:subject:date:message-id:in-reply-to:references;
 bh=0zWJKoj317VgZkrNVQ1QesOfayLyF22xe8pjz57KH/o=;
 b=imNdSIJLrYU79t7CSDM4gtcDq4idB1k8eOnyFmolSOSN3qeFm9GgV4cHuXSQMnxT/+
 JzOWbKIbfCmGPOPKXfR3rO0nVgtsFc8fNqP/95Jwv3TyZOAV/mayhUkVTGieSp3FdXIb
 QGVRnUbc4wW/uDZrUXgsB3ZYfO1VESN+4CluNYKRGZFFoxb0EIiUd7Q71OUCMwuMUKSD
 FntHp1ceGknzhVhHxdyJcitu6j29qFTQSBmKESYV1IKy8AOVCkscxO5KvDu465pEiHcC
 2+I0Tqs9O6MlA/BcBL+Iw+7nI85Tl9MTTNN0g9ruB3933ZJ8q3PEzt5+EAkcn3oNiKFf
 gEGw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
 :references;
 bh=0zWJKoj317VgZkrNVQ1QesOfayLyF22xe8pjz57KH/o=;
 b=XZ8sOd6R+Qqyw3IjTKBv8DALVObjzloc9iwd9dtBzDGGd8iitUIQOa78SPJp89QUZi
 uCfX9FsHM65E1Qrrr+WtP5MGi6EIM8xpZENlVY9nQaD8ldCyWnqQ33IC2l6vmcXheG2Y
 08642owSRlpJu9yiVn15l6YarY6kC0kZCvHXf0FXH7D4T0PnkoVSPwQf7+eXCEoRySfk
 SrezyQ/hpvUc0UmsPzmCJWyYoc89R7rfn2IMuFLxC7wklUdPNl+Z4RAanABuMK1zaFF5
 CPhlhbOhUGYLK8pmOdh33Swuzrsi1X3FlDfv4sigXwBnKUurwzB166Tc6BTaSg6ReYXi
 XMwA==
X-Gm-Message-State: AE9vXwOnp5iMK5VlWR9Y6ohmTNB8bpSY6JO7MTVwk6u/wh5u41YNvWa/KvhTqmGK8rVTBw==
X-Received: by 10.28.39.133 with SMTP id n127mr6660330wmn.6.1474218277774;
 Sun, 18 Sep 2016 10:04:37 -0700 (PDT)
Received: from localhost (5751dfa2.skybroadband.com. [87.81.223.162])
 by smtp.gmail.com with ESMTPSA id vh6sm18786842wjb.0.2016.09.18.10.04.37
 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
 Sun, 18 Sep 2016 10:04:37 -0700 (PDT)
From: Mark Walters <markwalters1009@gmail.com>
To: notmuch@notmuchmail.org
Subject: [PATCH v2 1/2] emacs: add tag jump menu
Date: Sun, 18 Sep 2016 18:04:30 +0100
Message-Id: <1474218271-8312-2-git-send-email-markwalters1009@gmail.com>
X-Mailer: git-send-email 2.1.4
In-Reply-To: <1474218271-8312-1-git-send-email-markwalters1009@gmail.com>
References: <1474218271-8312-1-git-send-email-markwalters1009@gmail.com>
X-BeenThere: notmuch@notmuchmail.org
X-Mailman-Version: 2.1.22
Precedence: list
List-Id: "Use and development of the notmuch mail system."
 <notmuch.notmuchmail.org>
List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,
 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
List-Archive: <http://notmuchmail.org/pipermail/notmuch/>
List-Post: <mailto:notmuch@notmuchmail.org>
List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,
 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
X-List-Received-Date: Sun, 18 Sep 2016 17:04:40 -0000

Add a "jump" style menu for doing tagging operations.
---
 emacs/notmuch-lib.el  |  4 +++
 emacs/notmuch-show.el |  1 +
 emacs/notmuch-tag.el  | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 emacs/notmuch-tree.el |  1 +
 emacs/notmuch.el      |  1 +
 5 files changed, 75 insertions(+)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 2f015b0..b2cdace 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -57,6 +57,10 @@
 
 (custom-add-to-group 'notmuch-send 'message 'custom-group)
 
+(defgroup notmuch-tag nil
+  "Tags and tagging in Notmuch."
+  :group 'notmuch)
+
 (defgroup notmuch-crypto nil
   "Processing and display of cryptographic MIME parts."
   :group 'notmuch)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5a585f3..756c7dd 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1428,6 +1428,7 @@ reset based on the original query."
     (define-key map "V" 'notmuch-show-view-raw-message)
     (define-key map "c" 'notmuch-show-stash-map)
     (define-key map "h" 'notmuch-show-toggle-visibility-headers)
+    (define-key map "k" 'notmuch-tag-jump)
     (define-key map "*" 'notmuch-show-tag-all)
     (define-key map "-" 'notmuch-show-remove-tag)
     (define-key map "+" 'notmuch-show-add-tag)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 6c8b6a7..2fdccb6 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -28,6 +28,41 @@
 (require 'crm)
 (require 'notmuch-lib)
 
+(declare-function notmuch-search-tag "notmuch" tag-changes)
+(declare-function notmuch-show-tag "notmuch-show" tag-changes)
+(declare-function notmuch-tree-tag "notmuch-tree" tag-changes)
+
+(autoload 'notmuch-jump "notmuch-jump")
+
+
+(define-widget 'notmuch-tag-key-type 'list
+  "A single key tagging binding"
+  :format "%v"
+  :args '((list :inline t
+		:format "%v"
+		(key-sequence :tag "Key")
+		(radio :tag "Tag operations" (repeat :tag "Tag list" (string :format "%v" :tag "change"))
+		       (variable :tag "Tag variable"))
+		(string :tag "Name"))))
+
+(defcustom notmuch-tagging-keys
+  `((,(kbd "a") notmuch-archive-tags "Archive")
+    (,(kbd "u") notmuch-show-mark-read-tags "Mark read")
+    (,(kbd "f") ("+flagged") "Flag")
+    (,(kbd "s") ("+spam" "-inbox") "Mark as spam")
+    (,(kbd "d") ("+deleted" "-inbox") "Delete"))
+  "A list of keys and corresponding tagging operations
+
+For each key (or key sequence) you can specify a sequence of
+tagging operations to apply, or a variable which contains a list
+of tagging operations such as `notmuch-archive-tags'. The final
+element is name for the this tagging operation. If it is omitted
+or empty then the list of tag changes, or the variable name is
+used as the name."
+  :tag "List of tagging bindings"
+  :type '(repeat notmuch-tag-key-type)
+  :group 'notmuch-tag)
+
 (define-widget 'notmuch-tag-format-type 'lazy
   "Customize widget for notmuch-tag-format and friends"
   :type '(alist :key-type (regexp :tag "Tag")
@@ -437,6 +472,39 @@ begin with a \"+\" or a \"-\". If REVERSE is non-nil, replace all
 		s)))
 	  tags))
 
+(defun notmuch-tag-jump (reverse)
+  (interactive "P")
+  (let (action-map)
+    (dolist (binding notmuch-tagging-keys)
+      (let* ((tag-function (case major-mode
+			     (notmuch-search-mode #'notmuch-search-tag)
+			     (notmuch-show-mode #'notmuch-show-tag)
+			     (notmuch-tree-mode #'notmuch-tree-tag)))
+	     (key (first binding))
+	     (forward-tag-change (if (symbolp (second binding))
+				     (symbol-value (second binding))
+				   (second binding)))
+	     (tag-change (if reverse
+			     (notmuch-tag-change-list forward-tag-change 't)
+			   forward-tag-change))
+	     (name (or (and (not (string= (third binding) ""))
+			    (third binding))
+		       (and (symbolp (second binding))
+			    (symbol-name (second binding)))))
+	     (name-string (if name
+			      (if reverse (concat "Reverse " name)
+				name)
+			    (mapconcat #'identity tag-change " "))))
+	(push (list key name-string
+		     `(lambda () (,tag-function ',tag-change)))
+	      action-map)))
+    (push (list "r" (if reverse
+			"Forward tag changes "
+		      "Reverse tag changes")
+		(apply-partially 'notmuch-tag-jump (not reverse)))
+	  action-map)
+    (setq action-map (nreverse action-map))
+    (notmuch-jump action-map "Tag: ")))
 
 ;;
 
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index d864e6d..5431384 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -276,6 +276,7 @@ FUNC."
     (define-key map "P" 'notmuch-tree-prev-message)
     (define-key map (kbd "M-p") 'notmuch-tree-prev-thread)
     (define-key map (kbd "M-n") 'notmuch-tree-next-thread)
+    (define-key map "k" 'notmuch-tag-jump)
     (define-key map "-" 'notmuch-tree-remove-tag)
     (define-key map "+" 'notmuch-tree-add-tag)
     (define-key map "*" 'notmuch-tree-tag-thread)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 8e14692..888672b 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -169,6 +169,7 @@ there will be called at other points of notmuch execution."
     (define-key map "t" 'notmuch-search-filter-by-tag)
     (define-key map "l" 'notmuch-search-filter)
     (define-key map [mouse-1] 'notmuch-search-show-thread)
+    (define-key map "k" 'notmuch-tag-jump)
     (define-key map "*" 'notmuch-search-tag-all)
     (define-key map "a" 'notmuch-search-archive-thread)
     (define-key map "-" 'notmuch-search-remove-tag)
-- 
2.1.4