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 A9D62431FD7
\r
6 for <notmuch@notmuchmail.org>; Wed, 19 Feb 2014 12:20:44 -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 znDtdC0MIKF7 for <notmuch@notmuchmail.org>;
\r
18 Wed, 19 Feb 2014 12:20:39 -0800 (PST)
\r
19 Received: from mail-wg0-f47.google.com (mail-wg0-f47.google.com
\r
20 [74.125.82.47]) (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 B58FB431FBD for <notmuch@notmuchmail.org>; Wed, 19 Feb 2014 12:20:33 -0800
\r
24 Received: by mail-wg0-f47.google.com with SMTP id k14so745581wgh.2
\r
25 for <notmuch@notmuchmail.org>; Wed, 19 Feb 2014 12:20:31 -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=400vgAVsKSjcDn7RluxqJMmbNbKI+Wu6OskJ/JDeyWU=;
\r
29 b=qdbWOFe1ErxnSCGe95XI91SIl9e1xO/tgttvBO38CZ3fiOaUDDL2ohy9tpOgSKhjL7
\r
30 J5Kcaw0S1Wt54w2yMpPI5DvmWWQOgw9SFuBr2CmJ4YWWbGz7Qjz671GiPSHw/RRjtbXj
\r
31 +wP81HCu1U8x8TjtXBcHaMNw2kHDKbCOZyUHVp3feO+FA1ktnygvs+oty5yhu1zLECE2
\r
32 hBF/C7nEvAzfQC2k0sjGuvkUI8Hrr6Ipkybit51fPl91cZCXaEYUiDVPBfibrbXajfpH
\r
33 S5xv8mGCEIeYpjjMyejOB0I+x1vzPZc+FcO8oyOEY/tUaTDAeAeIP1/D7NfpC4wBETQW
\r
35 X-Received: by 10.194.110.41 with SMTP id hx9mr30734009wjb.28.1392841230963;
\r
36 Wed, 19 Feb 2014 12:20:30 -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 fo6sm4686478wib.7.2014.02.19.12.20.29
\r
39 for <multiple recipients>
\r
40 (version=TLSv1.2 cipher=RC4-SHA bits=128/128);
\r
41 Wed, 19 Feb 2014 12:20:30 -0800 (PST)
\r
42 From: Mark Walters <markwalters1009@gmail.com>
\r
43 To: notmuch@notmuchmail.org
\r
44 Subject: [PATCH v2 1/7] Make keys of notmuch-tag-formats regexps and use
\r
46 Date: Wed, 19 Feb 2014 20:20:06 +0000
\r
47 Message-Id: <1392841212-8494-2-git-send-email-markwalters1009@gmail.com>
\r
48 X-Mailer: git-send-email 1.7.9.1
\r
49 In-Reply-To: <1392841212-8494-1-git-send-email-markwalters1009@gmail.com>
\r
50 References: <1392841212-8494-1-git-send-email-markwalters1009@gmail.com>
\r
51 X-BeenThere: notmuch@notmuchmail.org
\r
52 X-Mailman-Version: 2.1.13
\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: Wed, 19 Feb 2014 20:20:44 -0000
\r
65 From: Austin Clements <amdragon@MIT.EDU>
\r
67 This patch switches notmuch-tag-formats to use regexps with caching
\r
70 We have to clear the cache somehow on changes to notmuch-tag-formats.
\r
71 This version takes the simplest approach: search/show/tree all clear
\r
72 the cache whenever they start loading.
\r
74 We cannot use assoc-default since there's no way to distinguish a
\r
75 missing key from a present key with a null cdr: thus, we use assoc*
\r
78 Performance-wise, the caching of regexp lookup makes this at least as
\r
79 fast as the previous code using assoc (see
\r
80 id:1392226351-31440-1-git-send-email-amdragon@mit.edu for timing
\r
83 emacs/notmuch-show.el | 1 +
\r
84 emacs/notmuch-tag.el | 70 +++++++++++++++++++++++++++++++++---------------
\r
85 emacs/notmuch-tree.el | 1 +
\r
86 emacs/notmuch.el | 1 +
\r
87 4 files changed, 51 insertions(+), 22 deletions(-)
\r
89 diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
\r
90 index 1ac80ca..4bddf6c 100644
\r
91 --- a/emacs/notmuch-show.el
\r
92 +++ b/emacs/notmuch-show.el
\r
93 @@ -1145,6 +1145,7 @@ function is used."
\r
94 ;; Don't track undo information for this buffer
\r
95 (set 'buffer-undo-list t)
\r
97 + (notmuch-tag-clear-cache)
\r
99 (goto-char (point-min))
\r
101 diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
\r
102 index 908e7ad..47e0205 100644
\r
103 --- a/emacs/notmuch-tag.el
\r
104 +++ b/emacs/notmuch-tag.el
\r
105 @@ -28,23 +28,39 @@
\r
107 (require 'notmuch-lib)
\r
109 +;; (notmuch-tag-clear-cache will be called by the defcustom
\r
110 +;; notmuch-tag-formats, so it has to be defined first.)
\r
112 +(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
\r
113 + "Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
\r
115 +(defun notmuch-tag-clear-cache ()
\r
116 + "Clear the internal cache of tag formats.
\r
118 +This must be called after changes to `notmuch-tag-formats'."
\r
119 + (clrhash notmuch-tag--format-cache))
\r
121 (defcustom notmuch-tag-formats
\r
122 '(("unread" (propertize tag 'face '(:foreground "red")))
\r
123 ("flagged" (propertize tag 'face '(:foreground "blue"))
\r
124 (notmuch-tag-format-image-data tag (notmuch-tag-star-icon))))
\r
125 "Custom formats for individual tags.
\r
127 -This gives a list that maps from tag names to lists of formatting
\r
128 -expressions. The car of each element gives a tag name and the
\r
129 -cdr gives a list of Elisp expressions that modify the tag. If
\r
130 -the list is empty, the tag will simply be hidden. Otherwise,
\r
131 -each expression will be evaluated in order: for the first
\r
132 -expression, the variable `tag' will be bound to the tag name; for
\r
133 -each later expression, the variable `tag' will be bound to the
\r
134 -result of the previous expression. In this way, each expression
\r
135 -can build on the formatting performed by the previous expression.
\r
136 -The result of the last expression will displayed in place of the
\r
138 +This is an association list that maps from tag name regexps to
\r
139 +lists of formatting expressions. The first entry whose car
\r
140 +regexp-matches a tag will be used to format that tag. The regexp
\r
141 +is implicitly anchored, so to match a literal tag name, just use
\r
142 +that tag name (if it contains special regexp characters like
\r
143 +\".\" or \"*\", these have to be escaped). The cdr of the
\r
144 +matching entry gives a list of Elisp expressions that modify the
\r
145 +tag. If the list is empty, the tag will simply be hidden.
\r
146 +Otherwise, each expression will be evaluated in order: for the
\r
147 +first expression, the variable `tag' will be bound to the tag
\r
148 +name; for each later expression, the variable `tag' will be bound
\r
149 +to the result of the previous expression. In this way, each
\r
150 +expression can build on the formatting performed by the previous
\r
151 +expression. The result of the last expression will displayed in
\r
154 For example, to replace a tag with another string, simply use
\r
155 that string as a formatting expression. To change the foreground
\r
156 @@ -56,7 +72,7 @@ with images."
\r
158 :group 'notmuch-search
\r
159 :group 'notmuch-show
\r
160 - :type '(alist :key-type (string :tag "Tag")
\r
161 + :type '(alist :key-type (regexp :tag "Tag")
\r
164 (radio :format "%v"
\r
165 @@ -137,16 +153,26 @@ This can be used with `notmuch-tag-format-image-data'."
\r
167 (defun notmuch-tag-format-tag (tag)
\r
168 "Format TAG by looking into `notmuch-tag-formats'."
\r
169 - (let ((formats (assoc tag notmuch-tag-formats)))
\r
171 - ((null formats) ;; - Tag not in `notmuch-tag-formats',
\r
172 - tag) ;; the format is the tag itself.
\r
173 - ((null (cdr formats)) ;; - Tag was deliberately hidden,
\r
174 - nil) ;; no format must be returned
\r
175 - (t ;; - Tag was found and has formats,
\r
176 - (let ((tag tag)) ;; we must apply all the formats.
\r
177 - (dolist (format (cdr formats) tag)
\r
178 - (setq tag (eval format))))))))
\r
179 + (let ((formatted (gethash tag notmuch-tag--format-cache 'missing)))
\r
180 + (when (eq formatted 'missing)
\r
183 + (assoc* tag notmuch-tag-formats
\r
184 + :test (lambda (tag key)
\r
185 + (and (eq (string-match key tag) 0)
\r
186 + (= (match-end 0) (length tag))))))))
\r
189 + ((null formats) ;; - Tag not in `notmuch-tag-formats',
\r
190 + tag) ;; the format is the tag itself.
\r
191 + ((null (cdr formats)) ;; - Tag was deliberately hidden,
\r
192 + nil) ;; no format must be returned
\r
193 + (t ;; - Tag was found and has formats,
\r
194 + (let ((tag tag)) ;; we must apply all the formats.
\r
195 + (dolist (format (cdr formats) tag)
\r
196 + (setq tag (eval format)))))))
\r
197 + (puthash tag formatted notmuch-tag--format-cache)))
\r
200 (defun notmuch-tag-format-tags (tags &optional face)
\r
201 "Return a string representing formatted TAGS."
\r
202 diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
\r
203 index 4f2ac02..a106e09 100644
\r
204 --- a/emacs/notmuch-tree.el
\r
205 +++ b/emacs/notmuch-tree.el
\r
206 @@ -881,6 +881,7 @@ the same as for the function notmuch-tree."
\r
207 (message-arg "--entire-thread"))
\r
208 (if (equal (car (process-lines notmuch-command "count" search-args)) "0")
\r
209 (setq search-args basic-query))
\r
210 + (notmuch-tag-clear-cache)
\r
211 (let ((proc (notmuch-start-notmuch
\r
212 "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
\r
213 "show" "--body=false" "--format=sexp"
\r
214 diff --git a/emacs/notmuch.el b/emacs/notmuch.el
\r
215 index 0471750..0c767f7 100644
\r
216 --- a/emacs/notmuch.el
\r
217 +++ b/emacs/notmuch.el
\r
218 @@ -888,6 +888,7 @@ the configured default sort order."
\r
219 (set 'notmuch-search-oldest-first oldest-first)
\r
220 (set 'notmuch-search-target-thread target-thread)
\r
221 (set 'notmuch-search-target-line target-line)
\r
222 + (notmuch-tag-clear-cache)
\r
223 (let ((proc (get-buffer-process (current-buffer)))
\r
224 (inhibit-read-only t))
\r