notmuch.el: controlling what does and doesn't get expanded in searches
[notmuch-archives.git] / 5f / d67f39055e7501495c7e8d9cb8bcac268d84c8
1 Return-Path: <markwalters1009@gmail.com>\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 E9EC342116D\r
6         for <notmuch@notmuchmail.org>; Sat,  1 Jun 2013 01:16:53 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0.201\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0.201 tagged_above=-999 required=5\r
12         tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
13         FREEMAIL_ENVFROM_END_DIGIT=1, FREEMAIL_FROM=0.001,\r
14         RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
15 Received: from olra.theworths.org ([127.0.0.1])\r
16         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
17         with ESMTP id NWBljEH5EoLP for <notmuch@notmuchmail.org>;\r
18         Sat,  1 Jun 2013 01:16:49 -0700 (PDT)\r
19 Received: from mail-wi0-f181.google.com (mail-wi0-f181.google.com\r
20         [209.85.212.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
21         (No client certificate requested)\r
22         by olra.theworths.org (Postfix) with ESMTPS id 15AD4429E5E\r
23         for <notmuch@notmuchmail.org>; Sat,  1 Jun 2013 01:16:33 -0700 (PDT)\r
24 Received: by mail-wi0-f181.google.com with SMTP id hi5so1312198wib.2\r
25         for <notmuch@notmuchmail.org>; Sat, 01 Jun 2013 01:16:32 -0700 (PDT)\r
26 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
27         h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;\r
28         bh=Rq5NklWAD0VVhzpV/+U8P4T4nd4wtNuNte8P76DGJH8=;\r
29         b=GhAQT/nRH70leGopmj8htAOztMB/K5pj3u51q8qTLYCKdW0CHFFnAZgvlUF+dH78EO\r
30         lKUP4m+aAsNKQzHeHfH8dZWL0LvBpcRSmKvpbhY0r7QV9Qo1oiV+ruaV2s457uKoCUcH\r
31         +ycNCXeVPAJlLXwAzKw4Sh67/MDHlOICLBxggeNRNvgo26xeP0/wF36ufnzBgakS5lE5\r
32         xLcRLCImQd8gP5E+N/6WT7fQc1+WmK/3U3brfJn3xwxuLfIOzFBp2yq+ebb1dewGtCrJ\r
33         CBYwDIRBS2nmzdk8hBnHp3TkKjk+e7Qx2sWI8nZATJvvLA4rcT/vdTDwckngs9UJKvcN\r
34         S2wA==\r
35 X-Received: by 10.180.149.171 with SMTP id ub11mr6103987wib.40.1370074592887; \r
36         Sat, 01 Jun 2013 01:16:32 -0700 (PDT)\r
37 Received: from localhost (94.197.247.227.threembb.co.uk. [94.197.247.227])\r
38         by mx.google.com with ESMTPSA id m3sm8618664wij.5.2013.06.01.01.16.29\r
39         for <multiple recipients>\r
40         (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
41         Sat, 01 Jun 2013 01:16:32 -0700 (PDT)\r
42 From: Mark Walters <markwalters1009@gmail.com>\r
43 To: notmuch@notmuchmail.org, Austin Clements <aclements@csail.mit.edu>,\r
44         Adam Wolfe Gordon <awg+notmuch@xvx.ca>\r
45 Subject: [PATCH v4 5/5] emacs: show: implement lazy hidden part handling\r
46 Date: Sat,  1 Jun 2013 09:15:47 +0100\r
47 Message-Id: <1370074547-24677-6-git-send-email-markwalters1009@gmail.com>\r
48 X-Mailer: git-send-email 1.7.10.4\r
49 In-Reply-To: <1370074547-24677-1-git-send-email-markwalters1009@gmail.com>\r
50 References: <1370074547-24677-1-git-send-email-markwalters1009@gmail.com>\r
51 X-BeenThere: notmuch@notmuchmail.org\r
52 X-Mailman-Version: 2.1.13\r
53 Precedence: list\r
54 List-Id: "Use and development of the notmuch mail system."\r
55         <notmuch.notmuchmail.org>\r
56 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
57         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
58 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
59 List-Post: <mailto:notmuch@notmuchmail.org>\r
60 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
61 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
62         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
63 X-List-Received-Date: Sat, 01 Jun 2013 08:16:54 -0000\r
64 \r
65 This adds the actual code to do the lazy insertion of hidden parts.\r
66 \r
67 We use a memory inefficient but simple method: when we come to insert\r
68 the part if it is hidden we just store all of the arguments to the\r
69 part insertion function as a button property. This means when we want\r
70 to show the part we can just resume where we left off.\r
71 \r
72 One thing is that we can't tell if a lazy part will produce text until\r
73 we try to render it so when unhiding a part we check to see if it\r
74 rendered; if not we invoke the default part handler (e.g. an external\r
75 viewer).\r
76 ---\r
77  emacs/notmuch-show.el |   52 ++++++++++++++++++++++++++++++++++++++++++-------\r
78  1 file changed, 45 insertions(+), 7 deletions(-)\r
79 \r
80 diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el\r
81 index 49f85ba..92f481b 100644\r
82 --- a/emacs/notmuch-show.el\r
83 +++ b/emacs/notmuch-show.el\r
84 @@ -488,12 +488,14 @@ message at DEPTH in the current thread."\r
85      ;; return button\r
86      button))\r
87  \r
88 -;; This is taken from notmuch-wash: maybe it should be unified?\r
89  (defun notmuch-show-toggle-part-invisibility (&optional button)\r
90    (interactive)\r
91    (let* ((button (or button (button-at (point))))\r
92 -        (overlay (button-get button 'overlay)))\r
93 -    (when overlay\r
94 +        (overlay (button-get button 'overlay))\r
95 +        (lazy-part (button-get button :notmuch-lazy-part)))\r
96 +    ;; We have a part to toggle if there is an overlay or if there is a lazy part.\r
97 +    ;; If neither is present we cannot toggle the part so we just return nil.\r
98 +    (when (or overlay lazy-part)\r
99        (let* ((show (button-get button :notmuch-part-hidden))\r
100              (new-start (button-start button))\r
101              (button-label (button-get button :base-label))\r
102 @@ -509,7 +511,15 @@ message at DEPTH in the current thread."\r
103           (move-overlay button new-start (point))\r
104           (delete-region (point) old-end))\r
105         (goto-char (min old-point (1- (button-end button))))\r
106 -       (overlay-put overlay 'invisible (not show))))))\r
107 +       ;; Return nil if there is a lazy-part, it is empty, and we are\r
108 +       ;; trying to show it.  In all other cases return t.\r
109 +       (if lazy-part\r
110 +           (when show\r
111 +             (button-put button :notmuch-lazy-part nil)\r
112 +             (notmuch-show-lazy-part lazy-part button))\r
113 +         ;; else there must be an overlay.\r
114 +         (overlay-put overlay 'invisible (not show))\r
115 +         t)))))\r
116  \r
117  ;; MIME part renderers\r
118  \r
119 @@ -807,6 +817,28 @@ message at DEPTH in the current thread."\r
120      ;; Return true if we created an overlay.\r
121      t))\r
122  \r
123 +(defun notmuch-show-lazy-part (part-args button)\r
124 +  ;; Insert the lazy part after the button for the part.\r
125 +  (save-excursion\r
126 +    (goto-char (1+ (button-end button)))\r
127 +    (let* ((inhibit-read-only t)\r
128 +          ;; We need to use markers for the start and end of the part\r
129 +          ;; because the part insertion functions do not guarantee\r
130 +          ;; to leave point at the end of the part.\r
131 +          (part-beg (copy-marker (point) nil))\r
132 +          (part-end (copy-marker (point) t))\r
133 +          ;; We have to save the depth as we can't find the depth\r
134 +          ;; when narrowed.\r
135 +          (depth (notmuch-show-get-depth)))\r
136 +      (save-restriction\r
137 +       (narrow-to-region part-beg part-end)\r
138 +       (delete-region part-beg part-end)\r
139 +       (apply #'notmuch-show-insert-bodypart-internal part-args)\r
140 +       (indent-rigidly part-beg part-end depth))\r
141 +      ;; Create the overlay. If the lazy-part turned out to be empty/not\r
142 +      ;; showable this returns nil.\r
143 +      (notmuch-show-create-part-overlays button part-beg part-end))))\r
144 +\r
145  (defun notmuch-show-insert-bodypart (msg part depth &optional hide)\r
146    "Insert the body part PART at depth DEPTH in the current thread.\r
147  \r
148 @@ -825,7 +857,11 @@ If HIDE is non-nil then initially hide this part."\r
149                    (notmuch-show-insert-part-header nth mime-type content-type (plist-get part :filename))))\r
150          (content-beg (point)))\r
151  \r
152 -    (notmuch-show-insert-bodypart-internal msg part mime-type nth depth button)\r
153 +    (if (not hide)\r
154 +        (notmuch-show-insert-bodypart-internal msg part mime-type nth depth button)\r
155 +      (button-put button :notmuch-lazy-part\r
156 +                  (list msg part mime-type nth depth button)))\r
157 +\r
158      ;; Some of the body part handlers leave point somewhere up in the\r
159      ;; part, so we make sure that we're down at the end.\r
160      (goto-char (point-max))\r
161 @@ -2009,8 +2045,10 @@ is destroyed when FN returns."\r
162  (defun notmuch-show-part-button-default (&optional button)\r
163    (interactive)\r
164    (let ((button (or button (button-at (point)))))\r
165 -    (if (button-get button 'overlay)\r
166 -       (notmuch-show-toggle-part-invisibility button)\r
167 +    ;; Try to toggle the part, if that fails then call the default\r
168 +    ;; action. The toggle fails if the part has no emacs renderable\r
169 +    ;; content.\r
170 +    (unless (notmuch-show-toggle-part-invisibility button)\r
171        (call-interactively notmuch-show-part-button-default-action))))\r
172  \r
173  (defun notmuch-show-save-part ()\r
174 -- \r
175 1.7.10.4\r
176 \r