mu4e: implement :hide-if-no-unread
Make mu4e-maildir-shortcut and mu4e-bookmarks understand a property :hide-if-no-unread~, which hides the maildir/bookmark from the main-view if there are no unread messages which the corresponding query.
This commit is contained in:
4
NEWS.org
4
NEWS.org
@ -91,6 +91,10 @@
|
|||||||
automatically translate; this depends on the ~pcre2el~ package which the user
|
automatically translate; this depends on the ~pcre2el~ package which the user
|
||||||
should install when using regular expression-addresses.
|
should install when using regular expression-addresses.
|
||||||
|
|
||||||
|
- ~mu4e-maildir-shortcuts~ and ~mu4e-bookmarks~ now understand a property
|
||||||
|
~:hide-if-no-unread~, which hides the maildir/bookmark from the main-view if
|
||||||
|
there are no unread messages which the corresponding query.
|
||||||
|
|
||||||
* 1.12 (released on February 24, 2024)
|
* 1.12 (released on February 24, 2024)
|
||||||
|
|
||||||
** Some highlights
|
** Some highlights
|
||||||
|
|||||||
@ -65,6 +65,10 @@ item must be unique among `mu4e-bookmarks' and
|
|||||||
`mu4e-maildir-shortcuts'.
|
`mu4e-maildir-shortcuts'.
|
||||||
- `:hide' - if t, the bookmark is hidden from the main-view and
|
- `:hide' - if t, the bookmark is hidden from the main-view and
|
||||||
speedbar.
|
speedbar.
|
||||||
|
- `:hide-if-no-unread' - if t, the shortcut is hidden from
|
||||||
|
the main-view if it contains are no unread messages.
|
||||||
|
|
||||||
|
You can also use:
|
||||||
- `:hide-unread' - do not show the counts of
|
- `:hide-unread' - do not show the counts of
|
||||||
unread/total number of matches for the query in the main-view.
|
unread/total number of matches for the query in the main-view.
|
||||||
This can be useful if a bookmark uses a very slow query.
|
This can be useful if a bookmark uses a very slow query.
|
||||||
|
|||||||
@ -105,9 +105,13 @@ Each of the list elements is a plist with at least:
|
|||||||
Optionally, you can add the following:
|
Optionally, you can add the following:
|
||||||
`:name' - name of the maildir to be displayed in main-view.
|
`:name' - name of the maildir to be displayed in main-view.
|
||||||
`:hide' - if t, the shortcut is hidden from the main-view.
|
`:hide' - if t, the shortcut is hidden from the main-view.
|
||||||
|
`:hide-if-no-unread' - if it t, the shortcut is hidden from
|
||||||
|
the main-view if it contains no unread messages.
|
||||||
|
|
||||||
|
You can also use:
|
||||||
`:hide-unread' - do not show the counts of unread/total number
|
`:hide-unread' - do not show the counts of unread/total number
|
||||||
of matches for the maildir in the main-view, and is implied
|
of matches for the maildir in the main-view, and is implied
|
||||||
from `:hide'.
|
from `:hide'.
|
||||||
|
|
||||||
For backward compatibility, an older form is recognized as well:
|
For backward compatibility, an older form is recognized as well:
|
||||||
|
|
||||||
|
|||||||
@ -593,6 +593,33 @@ This is mu4e's version of Emacs 29's `plistp'."
|
|||||||
(let ((len (proper-list-p object)))
|
(let ((len (proper-list-p object)))
|
||||||
(and len (zerop (% len 2)))))
|
(and len (zerop (% len 2)))))
|
||||||
|
|
||||||
|
(defun mu4e-plist-do (func plist)
|
||||||
|
"Apply FUNC to each element in PLIST.
|
||||||
|
FUNC receives to arguments: the key and its value."
|
||||||
|
(when plist
|
||||||
|
(funcall func (car plist) (cadr plist))
|
||||||
|
(mu4e-plist-do func (cddr plist))))
|
||||||
|
|
||||||
|
(defun mu4e-plist-remove (plist prop)
|
||||||
|
"Remove PROP from PLIST.
|
||||||
|
Returns the updated PLIST."
|
||||||
|
;; inspired by org-plist-delete
|
||||||
|
(let (p)
|
||||||
|
(while plist
|
||||||
|
(if (not (eq prop (car plist)))
|
||||||
|
(setq p (plist-put p (car plist) (nth 1 plist))))
|
||||||
|
(setq plist (cddr plist)))
|
||||||
|
p))
|
||||||
|
|
||||||
|
(defun mu4e-plist-remove-nils (plist)
|
||||||
|
"Remove all properties with value nil from PLIST."
|
||||||
|
(let (p)
|
||||||
|
(while plist
|
||||||
|
(when (cadr plist)
|
||||||
|
(setq p (plist-put p (car plist) (cadr plist))))
|
||||||
|
(setq plist (cddr plist)))
|
||||||
|
p))
|
||||||
|
|
||||||
(defun mu4e--message-hide-headers ()
|
(defun mu4e--message-hide-headers ()
|
||||||
"Hide headers based on the `message-hidden-headers' variable.
|
"Hide headers based on the `message-hidden-headers' variable.
|
||||||
This is mu4e's version of the post-emacs-28 `message-hide-headers',
|
This is mu4e's version of the post-emacs-28 `message-hide-headers',
|
||||||
|
|||||||
@ -223,10 +223,11 @@ for aligning them."
|
|||||||
(mapconcat
|
(mapconcat
|
||||||
(lambda (item)
|
(lambda (item)
|
||||||
(cl-destructuring-bind
|
(cl-destructuring-bind
|
||||||
(&key hide name key favorite query &allow-other-keys) item
|
(&key name key favorite query
|
||||||
|
hide hide-if-no-unread unread &allow-other-keys) item
|
||||||
;; hide items explicitly hidden, without key or wrong category.
|
;; hide items explicitly hidden, without key or wrong category.
|
||||||
(if hide
|
(if (or hide (and hide-if-no-unread (zerop unread)))
|
||||||
""
|
"" ;; hide
|
||||||
(let ((item-info
|
(let ((item-info
|
||||||
;; note, we have a function for the binding,
|
;; note, we have a function for the binding,
|
||||||
;; and perhaps a different one for the lambda.
|
;; and perhaps a different one for the lambda.
|
||||||
@ -410,7 +411,8 @@ instead."
|
|||||||
(unless (file-directory-p smtpmail-queue-dir)
|
(unless (file-directory-p smtpmail-queue-dir)
|
||||||
(mu4e-error "`smtpmail-queue-dir' does not exist"))
|
(mu4e-error "`smtpmail-queue-dir' does not exist"))
|
||||||
(setq smtpmail-queue-mail (not smtpmail-queue-mail))
|
(setq smtpmail-queue-mail (not smtpmail-queue-mail))
|
||||||
(message (concat "Outgoing mail will now be "
|
(mu4e-message
|
||||||
|
(concat "Outgoing mail will now be "
|
||||||
(if smtpmail-queue-mail "queued" "sent directly")))
|
(if smtpmail-queue-mail "queued" "sent directly")))
|
||||||
(unless (or (eq mu4e-split-view 'single-window)
|
(unless (or (eq mu4e-split-view 'single-window)
|
||||||
(not (buffer-live-p (get-buffer mu4e-main-buffer-name))))
|
(not (buffer-live-p (get-buffer mu4e-main-buffer-name))))
|
||||||
|
|||||||
@ -228,25 +228,21 @@ bookmark or maildir."
|
|||||||
(list
|
(list
|
||||||
:name name
|
:name name
|
||||||
:query query
|
:query query
|
||||||
:key (plist-get item :key)
|
|
||||||
:count count
|
:count count
|
||||||
:unread unread
|
:unread unread
|
||||||
:delta-count (- count baseline-count)
|
:delta-count (- count baseline-count)
|
||||||
:delta-unread delta-unread)))
|
:delta-unread delta-unread)))
|
||||||
;; remember the *effective* query too; we don't really need it, but
|
;; remember the *effective* query too; we don't really need it, but
|
||||||
;; useful for debugging.
|
;; useful for debugging.
|
||||||
(unless (string= query effective-query)
|
(setq value (plist-put value :effective-query effective-query))
|
||||||
(plist-put value :effective-query effective-query))
|
(setq value (plist-put value :maildir maildir))
|
||||||
;;for matching maildir shortcuts
|
;; copy some other items from item.
|
||||||
(when maildir (plist-put value :maildir maildir))
|
(mu4e-plist-do (lambda (k v)
|
||||||
|
(when (memq k '(:key :maildir :hide :hide-if-no-unread
|
||||||
|
:hide-unread))
|
||||||
|
(setq value (plist-put value k v)))) item)
|
||||||
;; nil props bring me discomfort
|
;; nil props bring me discomfort
|
||||||
(when (plist-get item :favorite)
|
(mu4e-plist-remove-nils value)))
|
||||||
(plist-put value :favorite t))
|
|
||||||
(when (plist-get item :hide)
|
|
||||||
(plist-put value :hide t))
|
|
||||||
(when (plist-get item :hide-unread)
|
|
||||||
(plist-put value :hide-unread t))
|
|
||||||
value))
|
|
||||||
data))
|
data))
|
||||||
|
|
||||||
(defun mu4e-query-items (&optional type)
|
(defun mu4e-query-items (&optional type)
|
||||||
|
|||||||
@ -840,12 +840,15 @@ instance:
|
|||||||
:query "list:mu-discuss.googlegroups.com AND date:7d..now"))
|
:query "list:mu-discuss.googlegroups.com AND date:7d..now"))
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
There are optional keys @t{:hide} to hide the bookmark from the main menu, but
|
There are optional keys @code{:hide} to hide the bookmark or maildirs from the
|
||||||
still have it available (using @key{b})) and @t{:hide-unread} to avoid
|
main menu, but still have it available (using @key{b})), and
|
||||||
generating the unread-number; that can be useful if you have bookmarks for slow
|
@code{:hide-if-no-unread} to hide it if there are no unread messages.
|
||||||
queries. Note that @t{:hide-unread} is implied when the query is not a string;
|
|
||||||
this for the common case where the query function involves some user input,
|
To customize the display, there is also @code{:hide-unread} to avoid generating
|
||||||
which would be disruptive in this case.
|
the unread-number; that can be useful if you have bookmarks for slow queries.
|
||||||
|
Note that @code{:hide-unread} is implied when the query is not a string; this
|
||||||
|
for the common case where the query function involves some user input, which
|
||||||
|
would be disruptive in this case.
|
||||||
|
|
||||||
There is also the optional @code{:favorite} property, which at most one bookmark
|
There is also the optional @code{:favorite} property, which at most one bookmark
|
||||||
should have; this bookmark is highlighted in the main view, and its
|
should have; this bookmark is highlighted in the main view, and its
|
||||||
@ -2180,18 +2183,36 @@ be instructive:
|
|||||||
"List of pre-defined queries that are shown on the main screen.
|
"List of pre-defined queries that are shown on the main screen.
|
||||||
|
|
||||||
Each of the list elements is a plist with at least:
|
Each of the list elements is a plist with at least:
|
||||||
:name - the name of the query
|
`:name' - the name of the query
|
||||||
:query - the query expression
|
`:query' - the query expression string or function
|
||||||
:key - the shortcut key.
|
`:key' - the shortcut key (single character)
|
||||||
|
|
||||||
Optionally, you add the following:
|
Optionally, you can add the following:
|
||||||
:hide - if t, bookmark is hidden from the main-view and speedbar.
|
|
||||||
:hide-unread - do not show the counts of unread/total number
|
- `:favorite' - if t, monitor the results of this query, and make
|
||||||
of matches for the query. This can be useful if a bookmark uses
|
it eligible for showing its status in the modeline. At most
|
||||||
a very slow query. :hide-unread is implied from :hide.
|
one bookmark should have this set to t (otherwise the _first_
|
||||||
"
|
bookmark is the implicit favorite). The query for the `:favorite'
|
||||||
|
item must be unique among `mu4e-bookmarks' and
|
||||||
|
`mu4e-maildir-shortcuts'.
|
||||||
|
- `:hide' - if t, the bookmark is hidden from the main-view and
|
||||||
|
speedbar.
|
||||||
|
- `:hide-if-no-unread' - if t, the shortcut is hidden from
|
||||||
|
the main-view if it contains are no unread messages.
|
||||||
|
|
||||||
|
You can also use:
|
||||||
|
- `:hide-unread' - do not show the counts of
|
||||||
|
unread/total number of matches for the query in the main-view.
|
||||||
|
This can be useful if a bookmark uses a very slow query.
|
||||||
|
|
||||||
|
`:hide-unread' is implied from `:hide'.
|
||||||
|
|
||||||
|
Note: for efficiency, queries used to determine the unread/all
|
||||||
|
counts do not discard duplicate or unreadable messages. Thus, the
|
||||||
|
numbers shown may differ from the number you get from a normal
|
||||||
|
query."
|
||||||
:type '(repeat (plist))
|
:type '(repeat (plist))
|
||||||
:group 'mu4e)
|
:group 'mu4e-bookmarks)
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
You can replace these or add your own items, by putting in your
|
You can replace these or add your own items, by putting in your
|
||||||
@ -2303,14 +2324,18 @@ maildirs (folders) very quickly --- for example, getting to the @t{/lists}
|
|||||||
folder only requires you to type @kbd{jl}, then change to @t{/work} with
|
folder only requires you to type @kbd{jl}, then change to @t{/work} with
|
||||||
@kbd{jw}.
|
@kbd{jw}.
|
||||||
|
|
||||||
While in queries you need to quote folder names (maildirs) with spaces in
|
While in queries you need to quote folder names (maildirs) with spaces in them,
|
||||||
them, you should @emph{not} quote them when used in
|
you should @emph{not} quote them when used in @code{mu4e-maildir-shortcuts},
|
||||||
@code{mu4e-maildir-shortcuts}, since @t{mu4e} does that automatically for you.
|
since @t{mu4e} does that automatically for you.
|
||||||
|
|
||||||
The very same shortcuts are used by @kbd{M-x mu4e-mark-for-move} (default
|
The very same shortcuts are used by @kbd{M-x mu4e-mark-for-move} (default
|
||||||
shortcut @key{m}); so, for example, if you want to move a message to the
|
shortcut @key{m}); so, for example, if you want to move a message to the
|
||||||
@t{/archive} folder, you can do so by typing @kbd{ma}.
|
@t{/archive} folder, you can do so by typing @kbd{ma}.
|
||||||
|
|
||||||
|
For further customization, you can use @code{:hide}, @code{:hide-if-no-unread},
|
||||||
|
@code{:hide-unread} and @code{:favorite} properties, just like for
|
||||||
|
@ref{Bookmarks and Maildirs}.
|
||||||
|
|
||||||
@node Other search functionality
|
@node Other search functionality
|
||||||
@section Other search functionality
|
@section Other search functionality
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user