unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Daniel Schoepe <daniel.schoepe@googlemail.com>
To: Austin Clements <amdragon@mit.edu>
Cc: notmuch@notmuchmail.org
Subject: Re: [PATCH] emacs: Make the queries used in the all-tags section
Date: Wed, 25 May 2011 23:21:54 +0200	[thread overview]
Message-ID: <87ei3mcw7h.fsf@gilead.invalid> (raw)
In-Reply-To: <BANLkTikAB0mogUuS-nT_-i51LBdUBHCz3g@mail.gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 3250 bytes --]

On Wed, 25 May 2011 15:11:16 -0400, Austin Clements <amdragon@mit.edu> wrote:
> At least in Emacs 23.3.1, it has to be (const :tag "tag:TAG" nil).  I
> didn't think the order mattered, but the tag didn't display otherwise.
>  It would also be good to give descriptive tags to the other choices.
> 
> It would be more consistent if the function form of this also returned
> a filter expression, rather than a whole expression.  This also
> simplifies the documentation.

Thanks for the suggestions. (At first, I wanted to allow the user
to be able to also include messages that don't have that tag, but this
really no longer belongs in the all tags-section).

> So, perhaps something like
>
> (defcustom notmuch-hello-tag-list-counts nil
>   "Method for generating counts displayed in the all tags list.
> 
> This variable controls the query used to generate counts for each
> tag in the \"all tags\" list.  If nil, the tag list will count
> all messages with each tag.  This can be a query string that will
> filter the messages counted for each tag.  Finally, this can be a
> function that will be called for each tag and should return a
> filter query for that tag, or nil to hide the tag."
>   :type '(choice (const :tag "Count all messages" nil)
>                  (const :tag "Count unread messages" "tag:unread")
>                  (const :tag "Custom filter" string)
>                  (const :tag "Custom filter function" function))
>   :group 'notmuch)

That is slightly less accurate though, since the query is not only used
to generate the counts, but also the searches that are performed when
one presses return on a tag in the list.

> > +(defun notmuch-hello-generate-tag-alist ()
> > +  "Return an alist from tags to queries to display in the all-tags section."
> > +  (notmuch-filter
> > +   'cdr
> > +   (mapcar '(lambda (tag)
> 
> You don't need the quote before a lambda form.  (You can also change
> 'cdr to #'cdr to further hint the compiler, though it appears to not
> matter in this case.)

Oh, yeah, normally I'm aware of that, don't know what made me quote it
at the time I wrote it.

> > +(defun notmuch-filter (pred lst)
> > +  "Return a list containing all elements from LST that satisfy PRED."
> 
> notmuch-remove-if-not would be more canonical (yeah, it's unwieldy,
> blame Common Lisp).  Also, since Elisp doesn't do tail-recursion, the
> standard way to define a remove-if-not function is
> 
> (defun notmuch-remove-if-not (predicate list)
>   "Return a copy of LIST with all items not satisfying PREDICATE removed."
>   (let (out)
>     (while list
>       (when (funcall predicate (car list))
>         (push (car list) out))
>       (setq list (cdr list)))
>     (nreverse out)))
> 
> (Why oh why Elisp hasn't just made remove-if and remove-if-not
> standard I don't know; they're redefined all over the Elisp code base.
>  Any everybody's afraid to use cl-seq's remove-if-not because it's so
> ridiculously complicated.)

Ah, thanks. I guess too much exposure to Haskell (and how smart GHC is)
makes me write things in a functional style without thinking about
performance.

I incorporated most of you recommendations in the attached patch.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: 0001-emacs-Make-queries-used-in-the-all-tags-section-conf.patch --]
[-- Type: text/x-diff, Size: 4426 bytes --]

From 2056a455cdec6b980426552b8dcd7055f6cd0805 Mon Sep 17 00:00:00 2001
From: Daniel Schoepe <daniel.schoepe@googlemail.com>
Date: Fri, 20 May 2011 00:53:50 +0200
Subject: [PATCH] emacs: Make queries used in the all-tags section
 configurable

This patch adds a customization variable that controls what queries
are used to construct the all-tags section in notmuch-hello. It allows
the user to specify a function to construct the query given a tag or
a string that is used as a filter for each tag.
It also adds a variable to hide various tags from the all-tags section.

Signed-off-by: Daniel Schoepe <daniel.schoepe@googlemail.com>
---
 emacs/notmuch-hello.el |   43 ++++++++++++++++++++++++++++++++++++++++---
 emacs/notmuch-lib.el   |    9 +++++++++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index e58dd24..bd95849 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -55,6 +55,26 @@
   :type 'boolean
   :group 'notmuch)
 
+(defcustom notmuch-hello-tag-list-make-query nil
+  "Function or string to generate queries for the all tags list.
+
+This variable controls which query results are shown for each tag
+in the \"all tags\" list. If nil, it will use all messages with
+that tag. If this is set to a string, it is used as a filter for
+messages having that tag (equivalent to \"tag:TAG and (THIS-VARIABLE)\").
+Finally this can be a function that will be called for each tag and
+should return a filter for that tag, or nil to hide the tag."
+  :type '(choice (const :tag "All messages" nil)
+		 (const :tag "Unread messages" "tag:unread")
+		 (const :tag "Custom filter" string)
+		 (const :tag "Custom filter function" function))
+  :group 'notmuch)
+
+(defcustom notmuch-hello-hide-tags nil
+  "List of tags to be hidden in the \"all tags\"-section."
+  :type '(repeat string)
+  :group 'notmuch)
+
 (defface notmuch-hello-logo-background
   '((((class color)
       (background dark))
@@ -318,6 +338,25 @@ Complete list of currently available key bindings:
  ;;(setq buffer-read-only t)
 )
 
+(defun notmuch-hello-generate-tag-alist ()
+  "Return an alist from tags to queries to display in the all-tags section."
+  (notmuch-remove-if-not
+   #'cdr
+   (mapcar (lambda (tag)
+	     (cons tag
+		   (cond
+		    ((functionp notmuch-hello-tag-list-make-query)
+		     (concat "tag:" tag " and ("
+			     (funcall notmuch-hello-tag-list-make-query tag) ")"))
+		    ((stringp notmuch-hello-tag-list-make-query)
+		     (concat "tag:" tag " and ("
+			     notmuch-hello-tag-list-make-query ")"))
+		    (t (concat "tag:" tag)))))
+	   (notmuch-remove-if-not
+	    (lambda (tag)
+	      (not (member tag notmuch-hello-hide-tags)))
+	    (process-lines notmuch-command "search-tags")))))
+
 ;;;###autoload
 (defun notmuch-hello (&optional no-display)
   "Run notmuch and display saved searches, known tags, etc."
@@ -396,9 +435,7 @@ Complete list of currently available key bindings:
 		      if (> (string-to-number (notmuch-saved-search-count (cdr elem))) 0)
 		      collect elem)))
 	     (saved-widest (notmuch-hello-longest-label saved-alist))
-	     (alltags-alist (if notmuch-show-all-tags-list
-				(mapcar '(lambda (tag) (cons tag (concat "tag:" tag)))
-					(process-lines notmuch-command "search-tags"))))
+	     (alltags-alist (if notmuch-show-all-tags-list (notmuch-hello-generate-tag-alist)))
 	     (alltags-widest (notmuch-hello-longest-label alltags-alist))
 	     (widest (max saved-widest alltags-widest)))
 
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index cc80fb2..d5ca0f4 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -120,6 +120,15 @@ within the current window."
       (or (memq prop buffer-invisibility-spec)
 	  (assq prop buffer-invisibility-spec)))))
 
+(defun notmuch-remove-if-not (predicate list)
+  "Return a copy of LIST with all items not satisfying PREDICATE removed."
+  (let (out)
+    (while list
+      (when (funcall predicate (car list))
+        (push (car list) out))
+      (setq list (cdr list)))
+    (nreverse out)))
+
 ; This lets us avoid compiling these replacement functions when emacs
 ; is sufficiently new enough to supply them alone. We do the macro
 ; treatment rather than just wrapping our defun calls in a when form
-- 
1.7.5.1


[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

  reply	other threads:[~2011-05-25 21:22 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-19 23:18 [PATCH] emacs: Make the queries used in the all-tags section Daniel Schoepe
2011-05-24 20:39 ` Carl Worth
2011-05-24 21:01   ` Daniel Schoepe
2011-05-24 22:04     ` Carl Worth
2011-05-25  4:10 ` Austin Clements
2011-05-25 10:04   ` Daniel Schoepe
2011-05-25 14:44     ` Austin Clements
2011-05-25 16:51       ` Daniel Schoepe
2011-05-25 17:56         ` Daniel Schoepe
2011-05-25 19:11           ` Austin Clements
2011-05-25 21:21             ` Daniel Schoepe [this message]
2011-05-25 22:42               ` Austin Clements
2011-05-25 23:21                 ` Daniel Schoepe
2011-05-26  1:05                   ` Carl Worth
2011-05-26 22:04               ` Carl Worth
2011-05-27  3:56                 ` Daniel Kahn Gillmor
  -- strict thread matches above, loose matches on Subject: below --
2011-05-26  3:27 Austin Clements

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ei3mcw7h.fsf@gilead.invalid \
    --to=daniel.schoepe@googlemail.com \
    --cc=amdragon@mit.edu \
    --cc=notmuch@notmuchmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).