1 Return-Path: <m.walters@qmul.ac.uk>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 54A39431FBC
\r
6 for <notmuch@notmuchmail.org>; Thu, 13 Dec 2012 00:54:28 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-1.098 tagged_above=-999 required=5
\r
12 tests=[DKIM_ADSP_CUSTOM_MED=0.001, FREEMAIL_FROM=0.001,
\r
13 NML_ADSP_CUSTOM_MED=1.2, RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled
\r
14 Received: from olra.theworths.org ([127.0.0.1])
\r
15 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id GIl7sN6Oaec2 for <notmuch@notmuchmail.org>;
\r
17 Thu, 13 Dec 2012 00:54:26 -0800 (PST)
\r
18 Received: from mail2.qmul.ac.uk (mail2.qmul.ac.uk [138.37.6.6])
\r
19 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id DE126431FB6
\r
22 for <notmuch@notmuchmail.org>; Thu, 13 Dec 2012 00:54:25 -0800 (PST)
\r
23 Received: from smtp.qmul.ac.uk ([138.37.6.40])
\r
24 by mail2.qmul.ac.uk with esmtp (Exim 4.71)
\r
25 (envelope-from <m.walters@qmul.ac.uk>)
\r
26 id 1Tj4Yf-00083d-Bi; Thu, 13 Dec 2012 08:54:21 +0000
\r
27 Received: from 93-97-24-31.zone5.bethere.co.uk ([93.97.24.31] helo=localhost)
\r
28 by smtp.qmul.ac.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.69)
\r
29 (envelope-from <m.walters@qmul.ac.uk>)
\r
30 id 1Tj4Ye-0000j4-PC; Thu, 13 Dec 2012 08:54:21 +0000
\r
31 From: Mark Walters <markwalters1009@gmail.com>
\r
32 To: Austin Clements <aclements@csail.mit.edu>, notmuch@notmuchmail.org
\r
33 Subject: Re: [PATCH 2/3] emacs: show: add overlays for each part
\r
34 In-Reply-To: <87txrtnssb.fsf@awakening.csail.mit.edu>
\r
35 References: <1354663662-20524-1-git-send-email-markwalters1009@gmail.com>
\r
36 <1354663662-20524-3-git-send-email-markwalters1009@gmail.com>
\r
37 <87txrtnssb.fsf@awakening.csail.mit.edu>
\r
38 User-Agent: Notmuch/0.14+155~g7edfdc3 (http://notmuchmail.org) Emacs/23.4.1
\r
39 (x86_64-pc-linux-gnu)
\r
40 Date: Thu, 13 Dec 2012 08:54:22 +0000
\r
41 Message-ID: <87obhy72o1.fsf@qmul.ac.uk>
\r
43 Content-Type: text/plain; charset=us-ascii
\r
44 X-Sender-Host-Address: 93.97.24.31
\r
45 X-QM-SPAM-Info: Sender has good ham record. :)
\r
46 X-QM-Body-MD5: 187b337f0f41c1dc60bb4f5aa986515d (of first 20000 bytes)
\r
47 X-SpamAssassin-Score: -1.8
\r
48 X-SpamAssassin-SpamBar: -
\r
49 X-SpamAssassin-Report: The QM spam filters have analysed this message to
\r
51 spam. We require at least 5.0 points to mark a message as spam.
\r
52 This message scored -1.8 points.
\r
53 Summary of the scoring:
\r
54 * -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/,
\r
56 * [138.37.6.40 listed in list.dnswl.org]
\r
57 * 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail
\r
58 provider * (markwalters1009[at]gmail.com)
\r
59 * 0.5 AWL AWL: From: address is in the auto white-list
\r
60 X-QM-Scan-Virus: ClamAV says the message is clean
\r
61 X-BeenThere: notmuch@notmuchmail.org
\r
62 X-Mailman-Version: 2.1.13
\r
64 List-Id: "Use and development of the notmuch mail system."
\r
65 <notmuch.notmuchmail.org>
\r
66 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
67 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
68 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
69 List-Post: <mailto:notmuch@notmuchmail.org>
\r
70 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
71 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
72 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
73 X-List-Received-Date: Thu, 13 Dec 2012 08:54:28 -0000
\r
78 Many thanks for the review: I will post a new version shortly. Some
\r
79 comments inline below:
\r
81 On Tue, 11 Dec 2012, Austin Clements <aclements@csail.mit.edu> wrote:
\r
82 > On Tue, 04 Dec 2012, Mark Walters <markwalters1009@gmail.com> wrote:
\r
83 >> This make notmuch-show-insert-bodypart add an overlay for any
\r
87 >> non-trivial part with a button header (currently the first text/plain
\r
88 >> part does not have a button). At this point the overlay is available
\r
89 >> to the button but there is no action using it yet.
\r
91 >> In addition a not-shown variable which is used to request the part be
\r
93 > not-shown is really an argument (I found this confusing).
\r
95 >> hidden by default down to the overlay but this is not acted on yet.
\r
97 >> emacs/notmuch-show.el | 62 +++++++++++++++++++++++++++++++++++++-----------
\r
98 >> 1 files changed, 48 insertions(+), 14 deletions(-)
\r
100 >> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
\r
101 >> index f8ce037..3215ebc 100644
\r
102 >> --- a/emacs/notmuch-show.el
\r
103 >> +++ b/emacs/notmuch-show.el
\r
104 >> @@ -569,10 +569,9 @@ message at DEPTH in the current thread."
\r
105 >> ;; should be chosen if there are more than one that match?
\r
106 >> (mapc (lambda (inner-part)
\r
107 >> (let ((inner-type (plist-get inner-part :content-type)))
\r
108 >> - (if (or notmuch-show-all-multipart/alternative-parts
\r
109 >> - (string= chosen-type inner-type))
\r
110 >> - (notmuch-show-insert-bodypart msg inner-part depth)
\r
111 >> - (notmuch-show-insert-part-header (plist-get inner-part :id) inner-type inner-type nil " (not shown)"))))
\r
112 >> + (notmuch-show-insert-bodypart msg inner-part depth
\r
113 >> + (not (or notmuch-show-all-multipart/alternative-parts
\r
115 > Since notmuch-show-all-multipart/alternative-parts was basically a hack
\r
116 > around our poor multipart/alternative support, I think this series (or a
\r
117 > follow up patch) should change its default to nil or even eliminate it
\r
120 I have added a patch at the end setting this to nil by default.
\r
122 >> + (string= chosen-type inner-type))))))
\r
124 > You could let-bind the (not (or ..)) to some variable ("hide" perhaps)
\r
125 > in the let above to avoid this crazy line length.
\r
129 >> (when notmuch-show-indent-multipart
\r
130 >> @@ -840,17 +839,52 @@ message at DEPTH in the current thread."
\r
131 >> (setq handlers (cdr handlers))))
\r
134 >> -(defun notmuch-show-insert-bodypart (msg part depth)
\r
135 >> - "Insert the body part PART at depth DEPTH in the current thread."
\r
136 >> +(defun notmuch-show-insert-part-overlays (msg beg end not-shown)
\r
138 > s/not-shown/hide/? Or hidden?
\r
140 >> + "Add an overlay to the part between BEG and END"
\r
141 >> + (let* ((button (button-at beg))
\r
142 >> + (part-beg (and button (1+ (button-end button)))))
\r
144 >> + ;; If the part contains no text we do not make it toggleable.
\r
145 >> + (unless (or (not button) (eq part-beg end))
\r
147 > (when (and button (/= part-beg end)) ...) ?
\r
149 >> + (let ((base-label (button-get button :base-label))
\r
150 >> + (overlay (make-overlay part-beg end))
\r
151 >> + (message-invis-spec (plist-get msg :message-invis-spec))
\r
152 >> + (invis-spec (make-symbol "notmuch-part-region")))
\r
154 >> + (overlay-put overlay 'invisible (list invis-spec message-invis-spec))
\r
156 > Non-trivial buffer invisibility specs are really bad for performance
\r
157 > (Emacs' renderer does the obvious O(n^2) thing when rendering a buffer
\r
158 > with an invisibility spec). Unfortunately, because of notmuch-wash and
\r
159 > the way overlays with trivial 'invisible properties combine with
\r
160 > overlays with list-type 'invisible properties combine, I don't think it
\r
161 > can be avoided. But if we get rid of buffer invisibility specs from
\r
162 > notmuch-wash, this code can also get much simpler.
\r
164 How do you plan to get rid of the invisibility properties from notmuch
\r
167 >> + (overlay-put overlay 'isearch-open-invisible #'notmuch-wash-region-isearch-show)
\r
169 > This will leave the "(not shown)" in the part header if isearch unfolds
\r
172 > Do we even want isearch to unfold parts? It's not clear we do for
\r
173 > multipart/alternative. If we do, probably the right thing is something
\r
176 I don't think we want to search hidden bodyparts so I just deleted this
\r
180 > (overlay-put overlay 'notmuch-show-part-button button)
\r
181 > (overlay-put overlay 'isearch-open-invisible #'notmuch-show-part-isearch-open)
\r
183 > (defun notmuch-show-part-isearch-open (overlay)
\r
184 > (notmuch-show-toggle-invisible-part-action
\r
185 > (overlay-get overlay 'notmuch-show-part-button)))
\r
187 >> + (overlay-put overlay 'priority 10)
\r
188 >> + (overlay-put overlay 'type "part")
\r
189 >> + ;; Now we have to add invis-spec to every overlay this
\r
190 >> + ;; overlay contains, otherwise these inner overlays will
\r
191 >> + ;; override this one.
\r
193 > Interesting. In the simple case of using nil or t for 'invisible, the
\r
194 > specs do combine as one would expect, but you're right that, with a
\r
195 > non-trivial invisibility-spec, the highest priority overlay wins. It's
\r
196 > too bad we don't know the depth of the part or we could just set the
\r
197 > overlay priority. This is another thing that would go away if we didn't
\r
198 > use buffer invisibility-specs.
\r
200 I don't think priorities get it right. As far as I could tell if you
\r
201 have two overlays at different priorities both with invisibility
\r
202 properties then the higher priority overlay decides visibility by
\r
203 itself: that is if it says invisible then the text is invisible, and if
\r
204 it says visible then the text is visible.
\r
207 >> + (mapc (lambda (inner)
\r
209 > I would use a (dolist (inner (overlays-in part-beg end)) ...) here.
\r
210 > Seems a little more readable.
\r
212 >> + (when (and (>= (overlay-start inner) part-beg)
\r
213 >> + (<= (overlay-end inner) end))
\r
214 >> + (overlay-put inner 'invisible
\r
215 >> + (cons invis-spec (overlay-get inner 'invisible)))))
\r
216 >> + (overlays-in part-beg end))
\r
218 >> + (button-put button 'invisibility-spec invis-spec)
\r
219 >> + (button-put button 'overlay overlay))
\r
220 >> + (goto-char (point-max)))))
\r
222 > This goto-char seems oddly out of place, since it has nothing to do with
\r
223 > overlay creation. Was it supposed to be here instead of in
\r
224 > notmuch-show-insert-bodypart? Is it even necessary?
\r
226 It was suppose to be in notmuch-show-insert-body-part. It was necessary
\r
227 but I have wrapped the toggle-button call in the third patch and now it
\r
228 does not seem necessary.
\r
230 It is possible that the toggle-button function should not move point: if
\r
231 that got changed the save-excursion here could be removed. (I will
\r
232 discuss this in my reply to your comments on the next patch).
\r
240 >> +(defun notmuch-show-insert-bodypart (msg part depth &optional not-shown)
\r
242 > Same comment about not-shown. (Also in the commit message.)
\r
244 >> + "Insert the body part PART at depth DEPTH in the current thread.
\r
246 >> +If not-shown is TRUE then initially hide this part."
\r
248 > s/not-shown/NOT-SHOWN/ (or whatever) and s/TRUE/non-nil/
\r
250 >> (let ((content-type (downcase (plist-get part :content-type)))
\r
251 >> - (nth (plist-get part :id)))
\r
252 >> - (notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type))
\r
253 >> - ;; Some of the body part handlers leave point somewhere up in the
\r
254 >> - ;; part, so we make sure that we're down at the end.
\r
255 >> - (goto-char (point-max))
\r
256 >> - ;; Ensure that the part ends with a carriage return.
\r
257 >> - (unless (bolp)
\r
258 >> - (insert "\n")))
\r
259 >> + (nth (plist-get part :id))
\r
260 >> + (beg (point)))
\r
262 >> + (notmuch-show-insert-bodypart-internal msg part content-type nth depth content-type)
\r
263 >> + ;; Some of the body part handlers leave point somewhere up in the
\r
264 >> + ;; part, so we make sure that we're down at the end.
\r
265 >> + (goto-char (point-max))
\r
266 >> + ;; Ensure that the part ends with a carriage return.
\r
267 >> + (unless (bolp)
\r
268 >> + (insert "\n"))
\r
269 >> + (notmuch-show-insert-part-overlays msg beg (point) not-shown)))
\r
271 >> (defun notmuch-show-insert-body (msg body depth)
\r
272 >> "Insert the body BODY at depth DEPTH in the current thread."
\r