Re: [PATCH 2/3] emacs: show: add overlays for each part
authorAustin Clements <aclements@csail.mit.edu>
Tue, 11 Dec 2012 03:59:00 +0000 (22:59 +1900)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:52:01 +0000 (09:52 -0800)
d9/592aa40f974a2cc25369da93b9b8d3b5bba080 [new file with mode: 0644]

diff --git a/d9/592aa40f974a2cc25369da93b9b8d3b5bba080 b/d9/592aa40f974a2cc25369da93b9b8d3b5bba080
new file mode 100644 (file)
index 0000000..6bb03d9
--- /dev/null
@@ -0,0 +1,240 @@
+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 BAC9A431FAF\r
+       for <notmuch@notmuchmail.org>; Mon, 10 Dec 2012 19:59:06 -0800 (PST)\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 EX9kYbymSZNS for <notmuch@notmuchmail.org>;\r
+       Mon, 10 Dec 2012 19:59:05 -0800 (PST)\r
+Received: from dmz-mailsec-scanner-8.mit.edu (DMZ-MAILSEC-SCANNER-8.MIT.EDU\r
+       [18.7.68.37])\r
+       by olra.theworths.org (Postfix) with ESMTP id A00DC431FAE\r
+       for <notmuch@notmuchmail.org>; Mon, 10 Dec 2012 19:59:05 -0800 (PST)\r
+X-AuditID: 12074425-b7f606d0000008ea-0a-50c6af89f537\r
+Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
+       by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id 09.D7.02282.98FA6C05; Mon, 10 Dec 2012 22:59:05 -0500 (EST)\r
+Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
+       by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id qBB3x4jc023328; \r
+       Mon, 10 Dec 2012 22:59:04 -0500\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+       (authenticated bits=0)\r
+       (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+       by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id qBB3x0iC016515\r
+       (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+       Mon, 10 Dec 2012 22:59:03 -0500 (EST)\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+       (envelope-from <amdragon@mit.edu>)\r
+       id 1TiGzk-0003ZN-FD; Mon, 10 Dec 2012 22:59:00 -0500\r
+From: Austin Clements <aclements@csail.mit.edu>\r
+To: Mark Walters <markwalters1009@gmail.com>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH 2/3] emacs: show: add overlays for each part\r
+In-Reply-To: <1354663662-20524-3-git-send-email-markwalters1009@gmail.com>\r
+References: <1354663662-20524-1-git-send-email-markwalters1009@gmail.com>\r
+       <1354663662-20524-3-git-send-email-markwalters1009@gmail.com>\r
+User-Agent: Notmuch/0.14+159~g6895fee (http://notmuchmail.org) Emacs/23.4.1\r
+       (i486-pc-linux-gnu)\r
+Date: Mon, 10 Dec 2012 22:59:00 -0500\r
+Message-ID: <87txrtnssb.fsf@awakening.csail.mit.edu>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFrrPIsWRmVeSWpSXmKPExsUixCmqrNu5/liAwZo7rBar5/JYXL85k9mB\r
+       yWPnrLvsHs9W3WIOYIrisklJzcksSy3St0vgypgz9zFrwQHTiqX/pzI2MD7V6mLk5JAQMJE4\r
+       MX0KC4QtJnHh3nq2LkYuDiGBfYwSHet3MEI4Gxgl5v38wg7hXGSS2PBkLxOEs4RRYueCf2D9\r
+       bAL6EivWTmIFsUUEXCWefvvMDGILCzhIzJ+2kB3E5hTwkjj9di5YjZBAO6PE2X3aXYwcHKIC\r
+       8RKzz/mAmCwCqhK7r4NN5AW6bt2ZRYwQtqDEyZlPwOLMAloSN/69ZJrAKDALSWoWktQCRqZV\r
+       jLIpuVW6uYmZOcWpybrFyYl5ealFuhZ6uZkleqkppZsYQeHI7qK6g3HCIaVDjAIcjEo8vBWq\r
+       xwKEWBPLiitzDzFKcjApifL6LgcK8SXlp1RmJBZnxBeV5qQWH2KU4GBWEuEtzQXK8aYkVlal\r
+       FuXDpKQ5WJTEeW+k3PQXEkhPLEnNTk0tSC2CycpwcChJ8M5bB9QoWJSanlqRlplTgpBm4uAE\r
+       Gc4DNFwKpIa3uCAxtzgzHSJ/ilFRSpy3FSQhAJLIKM2D64Wli1eM4kCvCPPmglTxAFMNXPcr\r
+       oMFMQINPCh4GGVySiJCSamD0PpP0WG2Fb5lhgLnCHr2qJ8n8VRdWcHFM0OkL8X/nFyswu7T9\r
+       q4vnMnkrxqTin9LV5V0CAe/11torC5s0Fiuy5Iez3pbdYVoTXut70GO2TRv7vkupEdNt3vZM\r
+       rDuffr05Srhx1rp164tkPa4mKdz36A1ROKu/ReXW/xkbWF717ZW0d8voU2Ipzkg01GIuKk4E\r
+       AGrJA9TyAgAA\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: Tue, 11 Dec 2012 03:59:06 -0000\r
+\r
+On Tue, 04 Dec 2012, Mark Walters <markwalters1009@gmail.com> wrote:\r
+> This make notmuch-show-insert-bodypart add an overlay for any\r
+\r
+s/make/makes/\r
+\r
+> non-trivial part with a button header (currently the first text/plain\r
+> part does not have a button). At this point the overlay is available\r
+> to the button but there is no action using it yet.\r
+>\r
+> In addition a not-shown variable which is used to request the part be\r
+\r
+not-shown is really an argument (I found this confusing).\r
+\r
+> hidden by default down to the overlay but this is not acted on yet.\r
+> ---\r
+>  emacs/notmuch-show.el |   62 +++++++++++++++++++++++++++++++++++++-----------\r
+>  1 files changed, 48 insertions(+), 14 deletions(-)\r
+>\r
+> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el\r
+> index f8ce037..3215ebc 100644\r
+> --- a/emacs/notmuch-show.el\r
+> +++ b/emacs/notmuch-show.el\r
+> @@ -569,10 +569,9 @@ message at DEPTH in the current thread."\r
+>      ;; should be chosen if there are more than one that match?\r
+>      (mapc (lambda (inner-part)\r
+>          (let ((inner-type (plist-get inner-part :content-type)))\r
+> -          (if (or notmuch-show-all-multipart/alternative-parts\r
+> -                  (string= chosen-type inner-type))\r
+> -              (notmuch-show-insert-bodypart msg inner-part depth)\r
+> -            (notmuch-show-insert-part-header (plist-get inner-part :id) inner-type inner-type nil " (not shown)"))))\r
+> +          (notmuch-show-insert-bodypart msg inner-part depth\r
+> +                                        (not (or notmuch-show-all-multipart/alternative-parts\r
+\r
+Since notmuch-show-all-multipart/alternative-parts was basically a hack\r
+around our poor multipart/alternative support, I think this series (or a\r
+follow up patch) should change its default to nil or even eliminate it\r
+entirely.\r
+\r
+> +                                                 (string= chosen-type inner-type))))))\r
+\r
+You could let-bind the (not (or ..)) to some variable ("hide" perhaps)\r
+in the let above to avoid this crazy line length.\r
+\r
+>        inner-parts)\r
+>  \r
+>      (when notmuch-show-indent-multipart\r
+> @@ -840,17 +839,52 @@ message at DEPTH in the current thread."\r
+>        (setq handlers (cdr handlers))))\r
+>    t)\r
+>  \r
+> -(defun notmuch-show-insert-bodypart (msg part depth)\r
+> -  "Insert the body part PART at depth DEPTH in the current thread."\r
+> +(defun notmuch-show-insert-part-overlays (msg beg end not-shown)\r
+\r
+s/not-shown/hide/?  Or hidden?\r
+\r
+> +  "Add an overlay to the part between BEG and END"\r
+> +  (let* ((button (button-at beg))\r
+> +     (part-beg (and button (1+ (button-end button)))))\r
+> +\r
+> +    ;; If the part contains no text we do not make it toggleable.\r
+> +    (unless (or (not button) (eq part-beg end))\r
+\r
+(when (and button (/= part-beg end)) ...) ?\r
+\r
+> +      (let ((base-label (button-get button :base-label))\r
+> +        (overlay (make-overlay part-beg end))\r
+> +        (message-invis-spec (plist-get msg :message-invis-spec))\r
+> +        (invis-spec (make-symbol "notmuch-part-region")))\r
+> +\r
+> +    (overlay-put overlay 'invisible (list invis-spec message-invis-spec))\r
+\r
+Non-trivial buffer invisibility specs are really bad for performance\r
+(Emacs' renderer does the obvious O(n^2) thing when rendering a buffer\r
+with an invisibility spec).  Unfortunately, because of notmuch-wash and\r
+the way overlays with trivial 'invisible properties combine with\r
+overlays with list-type 'invisible properties combine, I don't think it\r
+can be avoided.  But if we get rid of buffer invisibility specs from\r
+notmuch-wash, this code can also get much simpler.\r
+\r
+> +    (overlay-put overlay 'isearch-open-invisible #'notmuch-wash-region-isearch-show)\r
+\r
+This will leave the "(not shown)" in the part header if isearch unfolds\r
+the part.\r
+\r
+Do we even want isearch to unfold parts?  It's not clear we do for\r
+multipart/alternative.  If we do, probably the right thing is something\r
+like\r
+\r
+(overlay-put overlay 'notmuch-show-part-button button)\r
+(overlay-put overlay 'isearch-open-invisible #'notmuch-show-part-isearch-open)\r
+\r
+(defun notmuch-show-part-isearch-open (overlay)\r
+  (notmuch-show-toggle-invisible-part-action\r
+   (overlay-get overlay 'notmuch-show-part-button)))\r
+\r
+> +    (overlay-put overlay 'priority 10)\r
+> +    (overlay-put overlay 'type "part")\r
+> +    ;; Now we have to add invis-spec to every overlay this\r
+> +    ;; overlay contains, otherwise these inner overlays will\r
+> +    ;; override this one.\r
+\r
+Interesting.  In the simple case of using nil or t for 'invisible, the\r
+specs do combine as one would expect, but you're right that, with a\r
+non-trivial invisibility-spec, the highest priority overlay wins.  It's\r
+too bad we don't know the depth of the part or we could just set the\r
+overlay priority.  This is another thing that would go away if we didn't\r
+use buffer invisibility-specs.\r
+\r
+> +    (mapc (lambda (inner)\r
+\r
+I would use a (dolist (inner (overlays-in part-beg end)) ...) here.\r
+Seems a little more readable.\r
+\r
+> +            (when (and (>= (overlay-start inner) part-beg)\r
+> +                       (<= (overlay-end inner) end))\r
+> +              (overlay-put inner 'invisible\r
+> +                           (cons invis-spec (overlay-get inner 'invisible)))))\r
+> +          (overlays-in part-beg end))\r
+> +\r
+> +    (button-put button 'invisibility-spec invis-spec)\r
+> +    (button-put button 'overlay overlay))\r
+> +      (goto-char (point-max)))))\r
+\r
+This goto-char seems oddly out of place, since it has nothing to do with\r
+overlay creation.  Was it supposed to be here instead of in\r
+notmuch-show-insert-bodypart?  Is it even necessary?\r
+\r
+> +\r
+> +(defun notmuch-show-insert-bodypart (msg part depth &optional not-shown)\r
+\r
+Same comment about not-shown.  (Also in the commit message.)\r
+\r
+> +  "Insert the body part PART at depth DEPTH in the current thread.\r
+> +\r
+> +If not-shown is TRUE then initially hide this part."\r
+\r
+s/not-shown/NOT-SHOWN/ (or whatever) and s/TRUE/non-nil/\r
+\r
+>    (let ((content-type (downcase (plist-get part :content-type)))\r
+> -    (nth (plist-get part :id)))\r
+> -    (notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type))\r
+> -  ;; Some of the body part handlers leave point somewhere up in the\r
+> -  ;; part, so we make sure that we're down at the end.\r
+> -  (goto-char (point-max))\r
+> -  ;; Ensure that the part ends with a carriage return.\r
+> -  (unless (bolp)\r
+> -    (insert "\n")))\r
+> +    (nth (plist-get part :id))\r
+> +    (beg (point)))\r
+> +\r
+> +    (notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type)\r
+> +    ;; Some of the body part handlers leave point somewhere up in the\r
+> +    ;; part, so we make sure that we're down at the end.\r
+> +    (goto-char (point-max))\r
+> +    ;; Ensure that the part ends with a carriage return.\r
+> +    (unless (bolp)\r
+> +      (insert "\n"))\r
+> +    (notmuch-show-insert-part-overlays msg beg (point) not-shown)))\r
+>  \r
+>  (defun notmuch-show-insert-body (msg body depth)\r
+>    "Insert the body BODY at depth DEPTH in the current thread."\r
+> -- \r
+> 1.7.9.1\r