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 BE06D431FCB for ; Tue, 22 Jan 2013 16:24:55 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0.574 X-Spam-Level: X-Spam-Status: No, score=0.574 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7, RDNS_NONE=1.274] 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 Mm9ad9CROnlE for ; Tue, 22 Jan 2013 16:24:52 -0800 (PST) Received: from dmz-mailsec-scanner-8.mit.edu (unknown [18.7.68.37]) by olra.theworths.org (Postfix) with ESMTP id D3AE3431FC0 for ; Tue, 22 Jan 2013 16:24:51 -0800 (PST) X-AuditID: 12074425-b7fec6d000007584-75-50ff2dd34fc5 Received: from mailhub-auth-2.mit.edu ( [18.7.62.36]) by dmz-mailsec-scanner-8.mit.edu (Symantec Messaging Gateway) with SMTP id 03.EC.30084.3DD2FF05; Tue, 22 Jan 2013 19:24:51 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-2.mit.edu (8.13.8/8.9.2) with ESMTP id r0N0OoRt007754; Tue, 22 Jan 2013 19:24:51 -0500 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id r0N0OmX9012539 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT); Tue, 22 Jan 2013 19:24:50 -0500 (EST) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80) (envelope-from ) id 1Txo92-0004Te-MA; Tue, 22 Jan 2013 19:24:48 -0500 From: Austin Clements To: Damien Cassou , notmuch mailing list Subject: Re: emacs: Customize how each tag is displayed In-Reply-To: <1358525039-13569-1-git-send-email-damien.cassou@gmail.com> References: <1358525039-13569-1-git-send-email-damien.cassou@gmail.com> User-Agent: Notmuch/0.14+243~g18d79d1 (http://notmuchmail.org) Emacs/23.4.1 (i486-pc-linux-gnu) Date: Tue, 22 Jan 2013 19:24:48 -0500 Message-ID: <87k3r4d9v3.fsf@awakening.csail.mit.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrLIsWRmVeSWpSXmKPExsUixG6nontZ93+AwfUGMYtdd7cyWVy/OZPZ gclj56y77B7PVt1iDmCK4rJJSc3JLEst0rdL4MqYvvMdS8EBvYpzN6obGL8odzFyckgImEic adzDDGGLSVy4t56ti5GLQ0hgH6PEti3rGCGcDYwSJ5feYoFwLjJJzD59lAnCWcIosfHdU7B+ NgENiW37lzOC2CICKRJb73xgA7GFBcwltt2YyQRicwp4SFy8MYsVxBYScJd4P38dWK+oQLzE nA1T2UFsFgFVie0zj7OA2LxA9116e5IRwhaUODnzCVicWUBL4sa/l0wTGAVmIUnNQpJawMi0 ilE2JbdKNzcxM6c4NVm3ODkxLy+1SNdCLzezRC81pXQTIzgkXVR3ME44pHSIUYCDUYmHN+HZ vwAh1sSy4srcQ4ySHExKorxzdP4HCPEl5adUZiQWZ8QXleakFh9ilOBgVhLhVd4IVM6bklhZ lVqUD5OS5mBREue9kXLTX0ggPbEkNTs1tSC1CCYrw8GhJMFbCDJUsCg1PbUiLTOnBCHNxMEJ MpwHaPhqkBre4oLE3OLMdIj8KUZdjv1P2p8zCrHk5eelSolDDBIAKcoozYObA0slrxjFgd4S 5p0IUsUDTENwk14BLWECWsK7+DfIkpJEhJRUA2PVr0S7BrtlP/QWhBR8Cd7G92/7y6xMN+X/ phra1x/c3T75mznbhSPBRjqPF005wp411ebN9cTO53tfS/38dkZR6XSO5auD4rH1Rv8nzO/5 3/30U1v929ykeP1/OgcaEhN2mlxc/+BDc/PRKWfljaJqp1fO9VyZudZUO98nqjZutlaKwcNT f+crsRRnJBpqMRcVJwIAMtlYtwADAAA= 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: Wed, 23 Jan 2013 00:24:55 -0000 On Fri, 18 Jan 2013, Damien Cassou wrote: > [PATCH 1/4] emacs: Add notmuch-intersperse to notmuch-lib/ > [PATCH 2/4] emacs: pictures that might be used as icons for tags > [PATCH 3/4] emacs: possibility to customize the rendering of tags > [PATCH 4/4] emacs: provide convenience functions for notmuch-tagger > > > These patches are the first of an upcoming series whose goal is to > integrate notmuch-labeler into notmuch. See the following for more > details: https://github.com/DamienCassou/notmuch-labeler > > Points of discussion: > > - This series does not have any unit-test to make it smaller and more > amenable to comments. I will send a patch when requested. > > - Patch 3/4 formats tags as mode-line templates so that we can show > tags in the header-line in a later series. > > - Patch 3/4 introduces `notmuch-tagger-formats', a list of pairs (KEY > FORMAT) to format a tag matching KEY using a special format. > Currently, an example of such a list is: > > (("unread" > (:propertize "unread" face > (:foreground "red"))) > ("flagged" > (:propertize "flagged" display > (image :type svg > :file ,(notmuch-tagger-image-path "star.svg") > :ascent center :mask heuristic)))) > > to set the unread tag to be red and the flagged tag to have a star > picture attached. Because this variable is hard to edit without > making mistakes, patch 4/4 introduces customization functions that > the user can call on their init.el file like this: > > (notmuch-tagger-propertize "unread" :foreground "red") > (notmuch-tagger-image-star "flagged") > > Nevertheless, implementing a customize interface for this variable > is difficult as Emacs does not provide customization widgets for > text-property lists. A possible solution could be to change the list > value so that it looks like: > > (("unread" (propertize :foreground "red")) > ("flagged" (image-star))) > > where the FORMAT part of each pair would be the suffix of a > notmuch-tagger customization function name (as introduced by patch > 4/4) and the rest would be parameters to pass to this function > (except the KEY parameter that is already in each pair of the > `notmuch-tagger-formats' list). This solution would be more amenable > to the customization interface, but maybe less powerful. I'm not sold on your mode-line-format approach. On the one hand, it's rather quaint that you can reuse all of the mode-line formatting mechanism. But, on the other hand, 90% of the mode-line formatting mechanism makes no sense in this context, and all of the utility functions you add to make this variable accessible as well as the difficulty in creating a customize interface for it suggest that this is a false economy: that mode-line formatting is, in fact, the wrong abstraction for this. I'm not sure what the best representation is, but here's one idea. Instead of inventing (or reusing) some specialized formatting language, use the language already at your disposal: make the tag format a list of Elisp expressions that transform the tag string into an arbitrary propertized string to use in place of the tag. You can't get much more powerful than that, and, plus, it would be really easy to implement. Here's what I'm imagining, complete with working (slightly hairy) customize interface: (defcustom notmuch-tag-formats '(("unread" (propertize tag 'face '(:foreground "red"))) ("flagged" (notmuch-tag-format-image tag "star.svg"))) "Custom formats for individual tags. This gives a list that maps from tag names to lists of formatting expressions. The car of each element gives a tag name and the cdr gives a list of Elisp expressions that modify the tag. If the list is empty, the tag will simply be hidden. Otherwise, each expression will be evaluated in order: for the first expression, the variable `tag' will be bound to the tag name; for each later expression, the variable `tag' will be bound to the result of the previous expression. In this way, each expression can build on the formatting performed by the previous expression. The result of the last expression will displayed in place of the tag. For example, to replace a tag with another string, simply use that string as a formatting expression. To change the foreground of a tag to red, use the expression (propertize tag 'face '(:foreground \"red\")) See also `notmuch-tag-format-image', which can help replace tags with images." :group 'notmuch-search :group 'notmuch-show :type '(alist :key-type (string :tag "Tag") :extra-offset -3 :value-type (radio :format "%v" (const :tag "Hidden" nil) (set :tag "Modified" (string :tag "Display as") (list :tag "Face" :extra-offset -4 (const :format "" :inline t (propertize tag 'face)) (list :format "%v" (const :format "" quote) custom-face-edit)) (list :format "%v" :extra-offset -4 (const :format "" :inline t (notmuch-tag-format-image tag)) (choice :tag "Image" (const :tag "Star" "star.svg") (const :tag "Empty star" "star-empty.svg") (const :tag "Tag" "tag.svg") (string :tag "Custom"))) (sexp :tag "Custom"))))) where I'm imagining notmuch-tag-format-image would be very similar to your existing image utilities, with an interface something like (defun notmuch-tag-format-image (tag image) "Replace TAG with IMAGE, if available. Returns a propertized string that will display IMAGE in place of TAG. If IMAGE is a relative path, it will be looked for in the standard notmuch image directory. This is designed for use in `notmuch-tag-formats'." ...) Thoughts?