--- /dev/null
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 3F0FB431FAE\r
+ for <notmuch@notmuchmail.org>; Thu, 29 Aug 2013 09:26:20 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id 7ANK1-Ini9Ul for <notmuch@notmuchmail.org>;\r
+ Thu, 29 Aug 2013 09:26:16 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-1.mit.edu (dmz-mailsec-scanner-1.mit.edu\r
+ [18.9.25.12])\r
+ by olra.theworths.org (Postfix) with ESMTP id EC5EF431FCB\r
+ for <notmuch@notmuchmail.org>; Thu, 29 Aug 2013 09:26:05 -0700 (PDT)\r
+X-AuditID: 1209190c-b7fac8e000006335-33-521f761d1598\r
+Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
+ by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id 89.CE.25397.D167F125; Thu, 29 Aug 2013 12:26:05 -0400 (EDT)\r
+Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
+ by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id r7TGQ4xt023053; \r
+ Thu, 29 Aug 2013 12:26:04 -0400\r
+Received: from drake.dyndns.org\r
+ (216-15-114-40.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com\r
+ [216.15.114.40]) (authenticated bits=0)\r
+ (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+ by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id r7TGQ1Cl015001\r
+ (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
+ Thu, 29 Aug 2013 12:26:02 -0400\r
+Received: from amthrax by drake.dyndns.org with local (Exim 4.77)\r
+ (envelope-from <amdragon@mit.edu>)\r
+ id 1VF52n-0007Wz-4n; Thu, 29 Aug 2013 12:26:01 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 7/9] emacs: Make notmuch-help work with arbitrary keymaps\r
+Date: Thu, 29 Aug 2013 12:25:55 -0400\r
+Message-Id: <1377793557-28878-8-git-send-email-amdragon@mit.edu>\r
+X-Mailer: git-send-email 1.7.10.4\r
+In-Reply-To: <1377793557-28878-1-git-send-email-amdragon@mit.edu>\r
+References: <1377793557-28878-1-git-send-email-amdragon@mit.edu>\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFtrEIsWRmVeSWpSXmKPExsUixCmqrCtbJh9ksPCjlsX1mzOZHRg9nq26\r
+ xRzAGMVlk5Kak1mWWqRvl8CVcWU1X8F9qYoNk26xNTBuE+1i5OSQEDCROPtoDhuELSZx4d56\r
+ IJuLQ0hgH6PEvjcXmCCcjYwSazrnsUM4d5gkZv49ygjhzGWUeH29kx2kn01AQ2Lb/uWMILaI\r
+ gLTEzruzWbsYOTiYBdQk/nSpgISFBTwlLv59AlbOIqAq8f3VfzCbV8BBYu38ucwQZyhKdD+b\r
+ AHYSp4CjRP/dtywgthBQzZ+LT9knMPIvYGRYxSibklulm5uYmVOcmqxbnJyYl5dapGuol5tZ\r
+ opeaUrqJERw0kjw7GN8cVDrEKMDBqMTD2xEoHyTEmlhWXJl7iFGSg0lJlDewBCjEl5SfUpmR\r
+ WJwRX1Sak1p8iFGCg1lJhPctJ1CONyWxsiq1KB8mJc3BoiTO+/Tp2UAhgfTEktTs1NSC1CKY\r
+ rAwHh5IEb3wpUKNgUWp6akVaZk4JQpqJgxNkOA/Q8HKQGt7igsTc4sx0iPwpRkUpcd48kIQA\r
+ SCKjNA+uFxbVrxjFgV4R5pUEqeIBJgS47ldAg5mABk/IlwMZXJKIkJJqYGwzDFXZVVfg8LHl\r
+ 0tEn/ca1KYwCzd8vTb3UmJHnuWNL1jsP9Yurar8xp1rYRmbPe1Zv6rUlcyvbkoYeFf7S3qCT\r
+ vnpOW3Yet3PRrGTf9+74ki8cNU5S01d5rL30qKxu9un9oeuZrHYsPtC3vaTsRt7PGSG1k4vv\r
+ TNCIr3rRqPE0wJAr76xgmRJLcUaioRZzUXEiADIvnLHFAgAA\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Thu, 29 Aug 2013 16:26:20 -0000\r
+\r
+This converts notmuch-help to use map-keymap for all keymap traversal.\r
+This generally cleans up and simplifies construction of keymap\r
+documentation, and also makes notmuch-help support anything that can\r
+be in a keymap, including more esoteric stuff like multiple\r
+inheritance.\r
+---\r
+ emacs/notmuch.el | 58 +++++++++++++++++++++---------------------------------\r
+ 1 file changed, 22 insertions(+), 36 deletions(-)\r
+\r
+diff --git a/emacs/notmuch.el b/emacs/notmuch.el\r
+index 80446be..0304096 100644\r
+--- a/emacs/notmuch.el\r
++++ b/emacs/notmuch.el\r
+@@ -140,48 +140,34 @@ This is basically just `format-kbd-macro' but we also convert ESC to M-."\r
+ "M-"\r
+ (concat desc " "))))\r
+ \r
+-;; I would think that emacs would have code handy for walking a keymap\r
+-;; and generating strings for each key, and I would prefer to just call\r
+-;; that. But I couldn't find any (could be all implemented in C I\r
+-;; suppose), so I wrote my own here.\r
+-(defun notmuch-substitute-one-command-key-with-prefix (prefix binding)\r
+- "For a key binding, return a string showing a human-readable\r
+-representation of the prefixed key as well as the first line of\r
+-documentation from the bound function.\r
+-\r
+-For a mouse binding, return nil."\r
+- (let ((key (car binding))\r
+- (action (cdr binding)))\r
+- (if (mouse-event-p key)\r
+- nil\r
+- (if (keymapp action)\r
+- (let ((substitute (apply-partially 'notmuch-substitute-one-command-key-with-prefix (notmuch-prefix-key-description key)))\r
+- (as-list))\r
+- (map-keymap (lambda (a b)\r
+- (push (cons a b) as-list))\r
+- action)\r
+- (mapconcat substitute as-list "\n"))\r
+- (concat prefix (format-kbd-macro (vector key))\r
+- "\t"\r
+- (notmuch-documentation-first-line action))))))\r
+-\r
+-(defun notmuch-substitute-command-keys-one (key)\r
+- ;; A `keymap' key indicates inheritance from a parent keymap - the\r
+- ;; inherited mappings follow, so there is nothing to print for\r
+- ;; `keymap' itself.\r
+- (when (not (eq key 'keymap))\r
+- (notmuch-substitute-one-command-key-with-prefix nil key)))\r
++(defun notmuch-describe-keymap (keymap &optional prefix tail)\r
++ "Return a list of strings, each describing one key in KEYMAP.\r
++\r
++Each string gives a human-readable description of the key and the\r
++first line of documentation for the bound function."\r
++ (map-keymap\r
++ (lambda (key binding)\r
++ (cond ((mouse-event-p key) nil)\r
++ ((keymapp binding)\r
++ (setq tail\r
++ (notmuch-describe-keymap\r
++ binding (notmuch-prefix-key-description key) tail)))\r
++ (t\r
++ (push (concat prefix (format-kbd-macro (vector key)) "\t"\r
++ (notmuch-documentation-first-line binding))\r
++ tail))))\r
++ keymap)\r
++ tail)\r
+ \r
+ (defun notmuch-substitute-command-keys (doc)\r
+ "Like `substitute-command-keys' but with documentation, not function names."\r
+ (let ((beg 0))\r
+ (while (string-match "\\\\{\\([^}[:space:]]*\\)}" doc beg)\r
+ (let* ((keymap-name (substring doc (match-beginning 1) (match-end 1)))\r
+- (keymap (symbol-value (intern keymap-name))))\r
+- (setq doc (replace-match\r
+- (mapconcat #'notmuch-substitute-command-keys-one\r
+- (cdr keymap) "\n")\r
+- 1 1 doc)))\r
++ (keymap (symbol-value (intern keymap-name)))\r
++ (desc-list (notmuch-describe-keymap keymap))\r
++ (desc (mapconcat #'identity desc-list "\n")))\r
++ (setq doc (replace-match desc 1 1 doc)))\r
+ (setq beg (match-end 0)))\r
+ doc))\r
+ \r
+-- \r
+1.7.10.4\r
+\r