mu4e: include unread/all counts for bookmarks

Show the unread/all matches counts in the main-view.
This commit is contained in:
Dirk-Jan C. Binnema
2020-01-21 20:53:09 +02:00
parent aba328c930
commit a4265bb8e9
5 changed files with 117 additions and 82 deletions

View File

@ -45,7 +45,6 @@
(define-key map "m" 'mu4e~main-toggle-mail-sending-mode)
(define-key map "f" 'smtpmail-send-queued-mail)
;;
(define-key map "U" 'mu4e-update-mail-and-index)
(define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
@ -106,6 +105,35 @@ clicked."
(- (length newstr) 1) 'mouse-face 'highlight newstr)
newstr))
(defun mu4e~main-bookmarks ()
;; TODO: it's a bit uncool to hard-code the "b" shortcut...
(mapconcat
(lambda (bm)
(unless (plist-get bm :hide)
(let* ((key (plist-get bm :key))
(name (plist-get bm :name))
(query (plist-get bm :query))
(qcounts
(seq-filter (lambda (q)
(string= (plist-get q :query) query))
(plist-get mu4e~server-props :queries))))
(concat
;; menu entry
(mu4e~main-action-str
(concat "\t* [b" (make-string 1 key) "] " name)
(concat "b" (make-string 1 key)))
;; append all/unread numbers, if available.
(if qcounts
(let ((unread (propertize (format "%s" (plist-get (car qcounts) :unread))
'face 'mu4e-header-key-face))
(count (propertize(format "%s" (plist-get (car qcounts) :count))
'face 'default)))
(concat " (" unread "/" count ")"))
"")))))
(mu4e-bookmarks) "\n"))
;; NEW
;; This is the old `mu4e~main-view' function but without
;; buffer switching at the end.
@ -132,15 +160,7 @@ clicked."
"\t* [C]ompose a new message\n" 'mu4e-compose-new)
"\n"
(propertize " Bookmarks\n\n" 'face 'mu4e-title-face)
;; TODO: it's a bit uncool to hard-code the "b" shortcut...
(mapconcat
(lambda (bm)
(unless (plist-get bm :hide)
(mu4e~main-action-str
(concat "\t* [b" (make-string 1 (plist-get bm :key)) "] "
(plist-get bm :name))
(concat "b" (make-string 1 (plist-get bm :key))))))
(mu4e-bookmarks) "\n")
(mu4e~main-bookmarks)
"\n\n"
(propertize " Misc\n\n" 'face 'mu4e-title-face)

View File

@ -468,9 +468,12 @@ to a temporary file, then respond with
:what ,what
:param ,param)))
(defun mu4e~proc-ping ()
"Sends a ping to the mu server, expecting a (:pong ...) in response."
(mu4e~call-mu '(ping)))
(defun mu4e~proc-ping (&optional queries)
"Sends a ping to the mu server, expecting a (:pong ...) in response.
QUERIES is a list of queries for the number of results with read/unread status
are returned in the 'pong' response."
(mu4e~call-mu `(ping
:queries ,queries)))
(defun mu4e~proc-contacts (personal after tstamp)
"Ask for contacts with PERSONAL AFTER TSTAMP.

View File

@ -693,8 +693,10 @@ This is used by the completion function in mu4e-compose."
(puthash address (cdr contact) mu4e~contacts))))
(setq mu4e~contacts-tstamp (or tstamp "0"))
(mu4e-index-message "Contacts updated: %d; total %d"
n (hash-table-count mu4e~contacts))))
(unless (zerop n)
(mu4e-index-message "Contacts updated: %d; total %d"
n (hash-table-count mu4e~contacts)))))
(defun mu4e-contacts-info ()
"Display information about the cache used for contacts
@ -784,6 +786,23 @@ nothing."
(mu4e-parse-time-string mu4e-compose-complete-only-after))))
mu4e~contacts-tstamp)))
(defun mu4e~pong-handler (props func)
"Handle 'pong' responses from the mu server."
(setq mu4e~server-props props) ;; save props from the server
(let ((version (plist-get props :version))
(doccount (plist-get props :doccount)))
(mu4e~check-requirements)
(when func (funcall func))
(when (zerop doccount)
(mu4e-message "Store is empty; (re)indexing. This can take a while.") ;
(mu4e-update-index))
(when (and mu4e-update-interval (null mu4e~update-timer))
(setq mu4e~update-timer
(run-at-time 0 mu4e-update-interval
(lambda () (mu4e-update-mail-and-index
mu4e-index-update-in-background)))))))
(defun mu4e~start (&optional func)
"If `mu4e-contexts' have been defined, but we don't have a
context yet, switch to the matching one, or none matches, the
@ -791,7 +810,7 @@ first. If mu4e is already running, execute function FUNC (if
non-nil). Otherwise, check various requireme`'nts, then start mu4e.
When successful, call FUNC (if non-nil) afterwards."
;; if we're already running, simply go to the main view
(if (mu4e-running-p) ;; already running?
(if (and nil mu4e-running-p) ;; already running?
(when func (funcall func)) ;; yes! run func if defined
(progn
;; no! try to set a context, do some checks, set up pong handler and ping
@ -799,26 +818,15 @@ When successful, call FUNC (if non-nil) afterwards."
(mu4e~context-autoswitch nil mu4e-context-policy)
(mu4e~check-requirements)
;; set up the 'pong' handler func
(setq mu4e-pong-func
(lambda (props)
(setq mu4e~server-props props) ;; save props from the server
(let ((version (plist-get props :version))
(doccount (plist-get props :doccount)))
(mu4e~check-requirements)
(when func (funcall func))
(when (zerop doccount)
(mu4e-message "Store is empty; (re)indexing. This can take a while.") ;
(mu4e-update-index))
(when (and mu4e-update-interval (null mu4e~update-timer))
(setq mu4e~update-timer
(run-at-time
0 mu4e-update-interval
(lambda () (mu4e-update-mail-and-index
mu4e-index-update-in-background)))))
(mu4e-message "Started mu4e with %d message%s in store"
doccount (if (= doccount 1) "" "s")))))
(setq mu4e-pong-func #'(lambda (props) (mu4e~pong-handler props func)))
;; wake up server
(mu4e~proc-ping)
(mu4e~proc-ping
(mapcar ;; send it a list of queries we'd like to see read/unread info
;; for.
(lambda(bm) (plist-get bm :query))
(seq-filter (lambda (bm) ;; exclude bookmarks with these flags.
(not (or (plist-get bm :hide) (plist-get bm :hide-unread))))
mu4e-bookmarks)))
;; maybe request the list of contacts, automatically refresh after
;; reindexing
(mu4e~request-contacts-maybe))))
@ -961,7 +969,7 @@ run in the background; otherwise, pop up a window."
;; ;;(switch-to-buffer buf)
;; (set-window-dedicated-p win t)
(erase-buffer)
(insert "\n") ;; FIXME -- needed so output start
(insert "\n") ;; FIXME -- needed so output starts
(mu4e~update-mail-mode)))
(setq mu4e~progress-reporter
(unless mu4e-hide-index-messages

View File

@ -81,8 +81,6 @@ already retrieved in another way."
:group 'mu4e
:safe 'stringp)
(defcustom mu4e-index-update-error-warning t
"Whether to display warnings during the retrieval process.
This depends on the `mu4e-get-mail-command' exit code."
@ -206,6 +204,8 @@ If the string exceeds this limit, it will be truncated to fit."
"Create a mu4e proplist with the following elements:
- `name': the user-visible name of the bookmark
- `key': a single key to search for this bookmark
- `show-unread' whether to show an indicator for read/unread messages. Specifying
this for too many bookmarks may incur slowdowns in showing the mu4e main page.
- `query': the query for this bookmark. Either a literal string or a function
that evaluates to a string."
`(:name ,name :query ,query :key ,key))
@ -221,6 +221,7 @@ are plists" "1.3.7")
:key ?t)
( :name "Last 7 days"
:query "date:7d..now"
:show-unread t
:key ?w)
( :name "Messages with images"
:query "mime:image/*"
@ -234,6 +235,9 @@ Each of the list elements is a plist with at least:
Optionally, you add the following:
:hide - if t, bookmark is hdden from the main-view and speedbar.
:hide-unread - do not show the counts of unread/total number
of matches for the query. This can be useful if a bookmark uses
a very slow query. :hide-unread is implied from :hide.
"
:type '(repeat (plist))
:group 'mu4e)

View File

@ -12,7 +12,7 @@
@c %**end of header
@copying
Copyright @copyright{} 2012-2019 Dirk-Jan C. Binnema
Copyright @copyright{} 2012-2020 Dirk-Jan C. Binnema
@quotation
Permission is granted to copy, distribute and/or modify this document
@ -674,7 +674,7 @@ The main view looks something like the following:
@cartouche
@verbatim
* mu4e - mu for emacs version 0.X.X CG
* mu4e - mu for emacs version @value{VERSION}; (in store: 78379 messages)
Basics
@ -684,14 +684,10 @@ The main view looks something like the following:
Bookmarks
* [bu] Unread messages
* [bt] Today's messages
* [bw] Last 7 days
* [bp] Messages with images
* [bs] Sent mail
* [bf] Flagged messages
* [b]] Flow
* [b/] Test
* [bu] Unread messages (26217/26217)
* [bt] Today's messages (2/8)
* [bw] Last 7 days (7/34)
* [bp] Messages with images (276/2315)
Misc
@ -706,15 +702,6 @@ The main view looks something like the following:
@end verbatim
@end cartouche
In the example above, you can see the letters ``@t{CG}'', which indicate:
@itemize
@item @t{C}: support for decryption of encrypted messages, and verifying
signatures. See @ref{MSGV Crypto} in the @ref{Message view} for details.
@item @t{G}: support for the Guile 2.0 programming language
@end itemize
Whether you see both, one or none of these letters depends on the way @t{mu}
is built.
Let's walk through the menu.
@node Basic actions
@ -738,11 +725,16 @@ the @ref{Editor view} to write a new message.
@node MV Bookmarks
@section Bookmarks
The next item in the Main view is @emph{Bookmarks}. Bookmarks are predefined
queries with a descriptive name and a shortcut --- in the example above, we see
the default bookmarks. You can view the list of messages matching a certain
bookmark by pressing @key{b} followed by the bookmark's shortcut. If you'd
like to edit the bookmarked query first before invoking it, use @key{B}.
The next item in the Main view is @emph{Bookmarks}.
Bookmarks are predefined queries with a descriptive name and a
shortcut --- in the example above, we see the default bookmarks. You
can view the list of messages matching a certain bookmark by pressing
@key{b} followed by the bookmark's shortcut. If you'd like to edit the
bookmarked query first before invoking it, use @key{B}.
Next to each bookmark there is the number of (unread/all) messages
that match.
Bookmarks are stored in the variable @code{mu4e-bookmarks}; you can add your
own and/or replace the default ones; @xref{Bookmarks}.
@ -1966,27 +1958,35 @@ mu4e-search-bookmark-edit}) which lets you edit the bookmark first.
be instructive:
@lisp
(defvar mu4e-bookmarks
'( ( :name "Unread messages"
:query "flag:unread AND NOT flag:trashed"
:key ?u)
( :name "Today's messages"
:query "date:today..now"
:key ?t)
( :name "Last 7 days"
:query "date:7d..now"
:key ?w)
( :name "Messages with images"
:query "mime:image/*"
:key ?p))
"A list of pre-defined queries. Each query is represented by a
mu4e-bookmark structure with parameters @t{:name} with the name
of the bookmark, @t{:query} with the query expression (a query
string or an s-expression that evaluates to query string) and a
@t{:key}, which is the shortcut-key for the query.
(defcustom mu4e-bookmarks
'(( :name "Unread messages"
:query "flag:unread AND NOT flag:trashed"
:key ?u)
( :name "Today's messages"
:query "date:today..now"
:key ?t)
( :name "Last 7 days"
:query "date:7d..now"
:show-unread t
:key ?w)
( :name "Messages with images"
:query "mime:image/*"
:key ?p))
"List of pre-defined queries that are shown on the main screen.
An older form of bookmark, a 3-item list with (QUERY DESCRIPTION
KEY) is still recognized as well, for backward-compatibility.")
Each of the list elements is a plist with at least:
:name - the name of the queryt
:query - the query expression
:key - the shortcut key.
Optionally, you add the following:
:hide - if t, bookmark is hdden from the main-view and speedbar.
:hide-unread - do not show the counts of unread/total number
of matches for the query. This can be useful if a bookmark uses
a very slow query. :hide-unread is implied from :hide.
"
:type '(repeat (plist))
:group 'mu4e)
@end lisp
You can replace these or add your own items, by putting in your