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 B18EB431FC4
\r
6 for <notmuch@notmuchmail.org>; Tue, 10 Dec 2013 00:57:42 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\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 7ZLJaPDOnq7T for <notmuch@notmuchmail.org>;
\r
18 Tue, 10 Dec 2013 00:57:36 -0800 (PST)
\r
19 Received: from mail-wg0-f52.google.com (mail-wg0-f52.google.com
\r
20 [74.125.82.52]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (No client
\r
21 certificate requested) by olra.theworths.org (Postfix) with ESMTPS id
\r
22 AD208431FBC for <notmuch@notmuchmail.org>; Tue, 10 Dec 2013 00:57:35 -0800
\r
24 Received: by mail-wg0-f52.google.com with SMTP id x13so4617143wgg.19
\r
25 for <notmuch@notmuchmail.org>; Tue, 10 Dec 2013 00:57:33 -0800 (PST)
\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:in-reply-to:references;
\r
28 bh=Yq3g95MdqLBnfwuFclNeg5qDzuO6vzcQkLx6reuah2g=;
\r
29 b=r04bDIOLXtNeE7r5jrXTcfus/1i3p3xa2823AD2XOXwlGkve6SDP02Zoi6e3k7V8jS
\r
30 TT4lNp/PPqpbJx4zn4q19l91luDDislbkbZGLg0II2iQ48ihNpyWUvsPnRStSDalcTvl
\r
31 EeD7x63/YgPlViYpEpV12UgjP5prZBrFqd6ZsKCabehxIy0nvHAPiSkA1yI2UKDIhgIT
\r
32 Gqxj9tvEOF9+ZLJBp4VHd0cAABEEQGOFDYEEI+5SqoF3uAnk05geYBFLglH+pNPgE5KM
\r
33 vdC0JzdGFS44RSqZtnnje2oNtGSK0gEa8RTtTB4kp9WSIAQwsWREjBP+4enSNu71pIbk
\r
35 X-Received: by 10.180.183.72 with SMTP id ek8mr18156775wic.49.1386665853158;
\r
36 Tue, 10 Dec 2013 00:57:33 -0800 (PST)
\r
37 Received: from localhost (93-97-24-31.zone5.bethere.co.uk. [93.97.24.31])
\r
38 by mx.google.com with ESMTPSA id w20sm3180192wia.5.2013.12.10.00.57.31
\r
39 for <multiple recipients>
\r
40 (version=TLSv1.2 cipher=RC4-SHA bits=128/128);
\r
41 Tue, 10 Dec 2013 00:57:32 -0800 (PST)
\r
42 From: Mark Walters <markwalters1009@gmail.com>
\r
43 To: notmuch@notmuchmail.org
\r
44 Subject: [PATCH WIP v4 1/3] emacs: show: mark tags changed since buffer loaded
\r
45 Date: Tue, 10 Dec 2013 08:57:25 +0000
\r
46 Message-Id: <1386665847-6439-2-git-send-email-markwalters1009@gmail.com>
\r
47 X-Mailer: git-send-email 1.7.9.1
\r
48 In-Reply-To: <1386665847-6439-1-git-send-email-markwalters1009@gmail.com>
\r
49 References: <1386665847-6439-1-git-send-email-markwalters1009@gmail.com>
\r
50 X-BeenThere: notmuch@notmuchmail.org
\r
51 X-Mailman-Version: 2.1.13
\r
53 List-Id: "Use and development of the notmuch mail system."
\r
54 <notmuch.notmuchmail.org>
\r
55 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
56 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
57 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
58 List-Post: <mailto:notmuch@notmuchmail.org>
\r
59 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
60 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
61 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
62 X-List-Received-Date: Tue, 10 Dec 2013 08:57:43 -0000
\r
64 This shows any tags changed in the show buffer since it was loaded or
\r
65 refreshed. By default a removed tag is displayed with strike-through
\r
66 in red (if strike-through is not available, eg on a terminal, inverse
\r
67 video is used instead) and an added tag is displayed underlined in
\r
70 One nice feature is that this makes it clear when a message was unread
\r
71 when you first loaded the buffer (previously the unread tag could be
\r
72 removed before a user realised that it had been unread).
\r
74 The code adds into the existing tag formatting code. The user can
\r
75 specify exactly how a tag should be displayed normally, when deleted,
\r
76 or when added. For convenience an entry for the entry string in the
\r
77 notmuch-tag-formats (and the corresponding notmuch-tag-deleted-formats
\r
78 notmuch-tag-added-formats) is applied to all tags which do not have an
\r
81 This means that a user can tell notmuch not to show deleted tags at
\r
82 all by setting notmuch-tag-deleted-formats to
\r
84 or not to show any deleted tags except "unread" by setting it to
\r
86 ("unread" (propertize tag 'face '(strike-through "red"))))
\r
88 All the variables are customizable; however, more complicated cases
\r
89 like changing the face depending on the type of display will require
\r
92 emacs/notmuch-show.el | 22 ++++++++--
\r
93 emacs/notmuch-tag.el | 105 +++++++++++++++++++++++++++++++++++--------------
\r
94 2 files changed, 92 insertions(+), 35 deletions(-)
\r
96 diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
\r
97 index 1ac80ca..30e84b1 100644
\r
98 --- a/emacs/notmuch-show.el
\r
99 +++ b/emacs/notmuch-show.el
\r
100 @@ -341,11 +341,21 @@ operation on the contents of the current buffer."
\r
101 "Update the displayed tags of the current message."
\r
103 (goto-char (notmuch-show-message-top))
\r
104 - (if (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
\r
105 - (let ((inhibit-read-only t))
\r
106 - (replace-match (concat "("
\r
107 - (notmuch-tag-format-tags tags)
\r
109 + (let* ((orig-tags (notmuch-show-get-prop :orig-tags))
\r
110 + (all-tags (sort (delete-dups (append tags orig-tags)) #'string<))
\r
111 + (display-tags (mapcar (lambda (tag) (cond ((and (member tag tags) (member tag orig-tags))
\r
113 + ((not (member tag tags))
\r
114 + (cons tag 'deleted))
\r
115 + ((not (member tag orig-tags))
\r
116 + (cons tag 'added))))
\r
119 + (if (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
\r
120 + (let ((inhibit-read-only t))
\r
121 + (replace-match (concat "("
\r
122 + (notmuch-tag-format-tags display-tags)
\r
125 (defun notmuch-clean-address (address)
\r
126 "Try to clean a single email ADDRESS for display. Return a cons
\r
127 @@ -1167,6 +1177,8 @@ function is used."
\r
129 (jit-lock-register #'notmuch-show-buttonise-links)
\r
131 + (notmuch-show-mapc (lambda () (notmuch-show-set-prop :orig-tags (notmuch-show-get-tags))))
\r
133 ;; Set the header line to the subject of the first message.
\r
134 (setq header-line-format (notmuch-sanitize (notmuch-show-strip-re (notmuch-show-get-subject))))
\r
136 diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
\r
137 index b60f46c..81ce287 100644
\r
138 --- a/emacs/notmuch-tag.el
\r
139 +++ b/emacs/notmuch-tag.el
\r
142 (require 'notmuch-lib)
\r
144 -(defcustom notmuch-tag-formats
\r
145 - '(("unread" (propertize tag 'face '(:foreground "red")))
\r
146 - ("flagged" (propertize tag 'face '(:foreground "blue"))
\r
147 - (notmuch-tag-format-image-data tag (notmuch-tag-star-icon))))
\r
148 - "Custom formats for individual tags.
\r
150 -This gives a list that maps from tag names to lists of formatting
\r
151 -expressions. The car of each element gives a tag name and the
\r
152 -cdr gives a list of Elisp expressions that modify the tag. If
\r
153 -the list is empty, the tag will simply be hidden. Otherwise,
\r
154 -each expression will be evaluated in order: for the first
\r
155 -expression, the variable `tag' will be bound to the tag name; for
\r
156 -each later expression, the variable `tag' will be bound to the
\r
157 -result of the previous expression. In this way, each expression
\r
158 -can build on the formatting performed by the previous expression.
\r
159 -The result of the last expression will displayed in place of the
\r
162 -For example, to replace a tag with another string, simply use
\r
163 -that string as a formatting expression. To change the foreground
\r
164 -of a tag to red, use the expression
\r
165 - (propertize tag 'face '(:foreground \"red\"))
\r
167 -See also `notmuch-tag-format-image', which can help replace tags
\r
170 - :group 'notmuch-search
\r
171 - :group 'notmuch-show
\r
172 +(define-widget 'notmuch-tag-format-type 'lazy
\r
173 + "Customize widget for notmuch-tag-format and friends"
\r
174 :type '(alist :key-type (string :tag "Tag")
\r
177 @@ -82,6 +56,61 @@ with images."
\r
178 (string :tag "Custom")))
\r
179 (sexp :tag "Custom")))))
\r
181 +(defcustom notmuch-tag-formats
\r
182 + '(("unread" (propertize tag 'face '(:foreground "red")))
\r
183 + ("flagged" (propertize tag 'face '(:foreground "blue"))
\r
184 + (notmuch-tag-format-image-data tag (notmuch-tag-star-icon))))
\r
185 + "Custom formats for individual tags.
\r
187 +This gives a list that maps from tag names to lists of formatting
\r
188 +expressions. The car of each element gives a tag name and the
\r
189 +cdr gives a list of Elisp expressions that modify the tag. If the
\r
190 +car is an empty string it matches all tags that do not have an
\r
191 +explicit match. If the list is empty, the tag will simply be
\r
192 +hidden. Otherwise, each expression will be evaluated in order:
\r
193 +for the first expression, the variable `tag' will be bound to the
\r
194 +tag name; for each later expression, the variable `tag' will be
\r
195 +bound to the result of the previous expression. In this way,
\r
196 +each expression can build on the formatting performed by the
\r
197 +previous expression. The result of the last expression will
\r
198 +displayed in place of the tag.
\r
200 +For example, to replace a tag with another string, simply use
\r
201 +that string as a formatting expression. To change the foreground
\r
202 +of a tag to red, use the expression
\r
203 + (propertize tag 'face '(:foreground \"red\"))
\r
205 +See also `notmuch-tag-format-image', which can help replace tags
\r
207 + :group 'notmuch-search
\r
208 + :group 'notmuch-show
\r
209 + :type 'notmuch-tag-format-type)
\r
211 +(defcustom notmuch-tag-deleted-formats
\r
212 + '(("" (propertize tag 'face
\r
213 + (if (display-supports-face-attributes-p '(:strike-through "red"))
\r
214 + '(:strike-through "red")
\r
215 + '(:inverse-video t)))))
\r
216 + "Custom formats for tags when deleted.
\r
218 +By default this shows deleted tags with strike-through in red,
\r
219 +unless strike-through is not available (e.g., emacs is running in
\r
220 +a terminal) in which case it uses inverse video. To hide deleted
\r
221 +tags completely set this to
\r
224 +See `notmuch-tag-formats' for full documentation."
\r
225 + :group 'notmuch-show
\r
226 + :type 'notmuch-tag-format-type)
\r
228 +(defcustom notmuch-tag-added-formats
\r
229 + '(("" (propertize tag 'face '(:underline "green"))))
\r
230 + "Custom formats for tags when added.
\r
232 +See `notmuch-tag-formats' for full documentation."
\r
233 + :group 'notmuch-show
\r
234 + :type 'notmuch-tag-format-type)
\r
236 (defun notmuch-tag-format-image-data (tag data)
\r
237 "Replace TAG with image DATA, if available.
\r
239 @@ -136,8 +165,24 @@ This can be used with `notmuch-tag-format-image-data'."
\r
242 (defun notmuch-tag-format-tag (tag)
\r
243 - "Format TAG by looking into `notmuch-tag-formats'."
\r
244 - (let ((formats (assoc tag notmuch-tag-formats)))
\r
245 + "Format TAG by looking into `notmuch-tag-formats'.
\r
247 +TAG can either be a string for a tag or a cons cell. In the
\r
248 +latter case the car of the cons cell is the tag string, the cdr
\r
249 +should be 'deleted or 'added to indicate whether the tag has been
\r
250 +deleted or added. The format for tag is looked up in
\r
251 +`notmuch-tag-formats' or `notmuch-tag-deleted-formats' or
\r
252 +`notmuch-tag-added-formats' as appropriate."
\r
253 + (let* ((status (if (consp tag) (cdr tag)))
\r
254 + (tag (if (consp tag) (car tag) tag))
\r
255 + (status-formats (cond
\r
256 + ((eq status 'deleted)
\r
257 + notmuch-tag-deleted-formats)
\r
258 + ((eq status 'added)
\r
259 + notmuch-tag-added-formats)
\r
260 + (t notmuch-tag-formats)))
\r
261 + (formats (or (append (assoc tag status-formats))
\r
262 + (append (assoc "" status-formats)))))
\r
264 ((null formats) ;; - Tag not in `notmuch-tag-formats',
\r
265 tag) ;; the format is the tag itself.
\r