Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id DA368431FAE for ; Fri, 13 Jul 2012 20:43:42 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id O-IvwWFw35iW for ; Fri, 13 Jul 2012 20:43:41 -0700 (PDT) Received: from dmz-mailsec-scanner-6.mit.edu (DMZ-MAILSEC-SCANNER-6.MIT.EDU [18.7.68.35]) by olra.theworths.org (Postfix) with ESMTP id B2D15429E33 for ; Fri, 13 Jul 2012 20:43:39 -0700 (PDT) X-AuditID: 12074423-b7f396d0000008f4-81-5000eaeb60e5 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35]) by dmz-mailsec-scanner-6.mit.edu (Symantec Messaging Gateway) with SMTP id 5F.83.02292.BEAE0005; Fri, 13 Jul 2012 23:43:39 -0400 (EDT) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id q6E3hcGP029857; Fri, 13 Jul 2012 23:43:38 -0400 Received: from drake.dyndns.org (209-6-116-242.c3-0.arl-ubr1.sbo-arl.ma.cable.rcn.com [209.6.116.242]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q6E3havc021325 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Fri, 13 Jul 2012 23:43:38 -0400 (EDT) Received: from amthrax by drake.dyndns.org with local (Exim 4.77) (envelope-from ) id 1SptGa-0000Zx-Mm; Fri, 13 Jul 2012 23:43:36 -0400 From: Austin Clements To: notmuch@notmuchmail.org Subject: [PATCH v2 2/7] emacs: Use text properties instead of overlays for tag coloring Date: Fri, 13 Jul 2012 23:43:21 -0400 Message-Id: <1342237406-32507-3-git-send-email-amdragon@mit.edu> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1342237406-32507-1-git-send-email-amdragon@mit.edu> References: <1342140319-19859-1-git-send-email-amdragon@mit.edu> <1342237406-32507-1-git-send-email-amdragon@mit.edu> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDIsWRmVeSWpSXmKPExsUixCmqrPv6FUOAwelzPBar5/JYXL85k9mB yWPnrLvsHs9W3WIOYIrisklJzcksSy3St0vgypi9MaVghnTFmt3drA2MXWJdjJwcEgImErvX tDJD2GISF+6tZ+ti5OIQEtjHKDHh+nJmCGcDo8SSee1QmUdMEidvPWCFcOYySmx83cgO0s8m oCGxbf9yRhBbREBaYufd2awgNrOAo8Tn/YvYQGxhgXCJ/+92g9ksAqoSDVt+gNXzCjhITOw6 wg5xh7zE0/t9YDWcQL1tvbfBaoQEyiWuf1vDNIGRfwEjwypG2ZTcKt3cxMyc4tRk3eLkxLy8 1CJdM73czBK91JTSTYygQGJ3Ud7B+Oeg0iFGAQ5GJR7eJH+GACHWxLLiytxDjJIcTEqivLzA MBTiS8pPqcxILM6ILyrNSS0+xCjBwawkwmveBpTjTUmsrEotyodJSXOwKInzXku56S8kkJ5Y kpqdmlqQWgSTleHgUJLgFQYZKliUmp5akZaZU4KQZuLgBBnOAzRcGqSGt7ggMbc4Mx0if4pR UUqc9/JLoIQASCKjNA+uFxbprxjFgV4R5mUCaecBJgm47ldAg5mABs/6+c8faHBJIkJKqoFx xawL8dt5i/d5K9T/4fJ98VxHKUHj/OWCdX9Xvzyx0ELacunUoJ3b3igt/98StTDphfKv2y29 LV4zOV4vYN35T0zsjNfG+QuVDHfcb9kW9SjAq0PRPu3ahPV82b/TiyNm9dT/8wxuySw1PPu4 VKJhl9Iqt51dAsUcCvzhESuENy7Z/aMxLYFXiaU4I9FQi7moOBEAp4xGGs8CAAA= X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Jul 2012 03:43:43 -0000 Previously, tag-based search result highlighting was done by creating an overlay over each search result. However, overlays have annoying front- and rear-advancement semantics that make it difficult to manipulate text at their boundaries, which the next patch will do. They also have performance problems (creating an overlay is linear in the number of overlays between point and the new overlay, making highlighting a search buffer quadratic in the number of results). Text properties have neither problem. However, text properties make it more difficult to apply multiple faces since, unlike with overlays, a given character can only have a single 'face text property. Hence, we introduce a utility function that combines faces into any existing 'face text properties. Using this utility function, it's straightforward to apply all of the appropriate tag faces in notmuch-search-color-line. --- emacs/notmuch-lib.el | 15 +++++++++++++++ emacs/notmuch.el | 21 +++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index aa25513..30db58f 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -269,6 +269,21 @@ current buffer, if possible." (loop for (key value . rest) on plist by #'cddr collect (cons (intern (substring (symbol-name key) 1)) value))) +(defun notmuch-combine-face-text-property (start end face) + "Combine FACE into the 'face text property between START and END. + +This function combines FACE with any existing faces between START +and END. Attributes specified by FACE take precedence over +existing attributes. FACE must be a face name (a symbol or +string), a property list of face attributes, or a list of these." + + (let ((pos start)) + (while (< pos end) + (let ((cur (get-text-property pos 'face)) + (next (next-single-property-change pos 'face nil end))) + (put-text-property pos next 'face (cons face cur)) + (setq pos next))))) + ;; Compatibility functions for versions of emacs before emacs 23. ;; ;; Both functions here were copied from emacs 23 with the following copyright: diff --git a/emacs/notmuch.el b/emacs/notmuch.el index ef18927..82c148d 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -633,20 +633,13 @@ foreground and blue background." (defun notmuch-search-color-line (start end line-tag-list) "Colorize lines in `notmuch-show' based on tags." - ;; Create the overlay only if the message has tags which match one - ;; of those specified in `notmuch-search-line-faces'. - (let (overlay) - (mapc (lambda (elem) - (let ((tag (car elem)) - (attributes (cdr elem))) - (when (member tag line-tag-list) - (when (not overlay) - (setq overlay (make-overlay start end))) - ;; Merge the specified properties with any already - ;; applied from an earlier match. - (overlay-put overlay 'face - (append (overlay-get overlay 'face) attributes))))) - notmuch-search-line-faces))) + (mapc (lambda (elem) + (let ((tag (car elem)) + (attributes (cdr elem))) + (when (member tag line-tag-list) + (notmuch-combine-face-text-property start end attributes)))) + ;; Reverse the list so earlier entries take precedence + (reverse notmuch-search-line-faces))) (defun notmuch-search-author-propertize (authors) "Split `authors' into matching and non-matching authors and -- 1.7.10