mu4e: implement mu4e-emacs-bookmark-policy

Allow for creating Emacs bookmarks for either messages (as before & the
default), queries or as the user.
This commit is contained in:
Dirk-Jan C. Binnema
2025-05-20 21:57:40 +03:00
parent bd23e293f5
commit acef5b2381
4 changed files with 97 additions and 36 deletions

View File

@ -123,10 +123,6 @@
- 1.12.9: the cleanup phase after indexing is significantly faster now - 1.12.9: the cleanup phase after indexing is significantly faster now
- 1.12.10: ~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.
*** mu4e *** mu4e
**** message composer **** message composer
@ -230,7 +226,7 @@
- links (in text-mode emails) are now clickable through <mouse-2>, to be - links (in text-mode emails) are now clickable through <mouse-2>, to be
consistent with eww. consistent with eww.
- support new-mail notifications on MacOS out-of-the-box - support new-mail notifications on MacOS/OSX out-of-the-box
- allow sorting by tag - allow sorting by tag
@ -270,6 +266,18 @@
message view as well, such as ~gnus-mailing-list-subscribe~, message view as well, such as ~gnus-mailing-list-subscribe~,
~gnus-mailing-list-unsubscribe~. ~gnus-mailing-list-unsubscribe~.
- 1.12.10: ~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.10: ~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.12: it now possible to create Emacs bookmarks for both messages
(default) and queries. See the new variable ~mu4e-emacs-bookmark-policy~.
*** Contributors *** Contributors
Thanks to our contributors - code committers belows, but also to everyone Thanks to our contributors - code committers belows, but also to everyone

View File

@ -288,7 +288,7 @@ user can then choose by typing CHAR. Example:
User now will be presented with a list: \"Choose an animal: User now will be presented with a list: \"Choose an animal:
[M]onkey, [G]nu, [x]Moose\". [M]onkey, [G]nu, [x]Moose\".
If optional character KEY is provied, use that instead of asking If optional character KEY is provided, use that instead of asking
the user. the user.
Function returns the value (cdr) of the matching cell." Function returns the value (cdr) of the matching cell."
@ -520,30 +520,21 @@ Or go to the top level if there is none."
('mu4e-view-mode "(mu4e)Message view") ('mu4e-view-mode "(mu4e)Message view")
(_ "mu4e")))) (_ "mu4e"))))
;;; Emacs bookmarks
(defcustom mu4e-emacs-bookmark-policy 'message
"The policy to decide what kind of Emacs bookmark to create.
;;; bookmarks This applies to the Emacs bookmark system command `bookmark-set'.
(defun mu4e--make-bookmark-record ()
"Create a bookmark for the message at point."
(let* ((msg (mu4e-message-at-point))
(subject (or (plist-get msg :subject) "No subject"))
(date (plist-get msg :date))
(date (if date (format-time-string "%F: " date) ""))
(title (format "%s%s" date subject))
(msgid (or (plist-get msg :message-id)
(mu4e-error
"Cannot bookmark message without message-id"))))
`(,title
,@(bookmark-make-record-default 'no-file 'no-context)
(message-id . ,msgid)
(handler . mu4e--jump-to-bookmark))))
(declare-function mu4e-view-message-with-message-id "mu4e-view") The policy is some symbol; you have the following choices:
(declare-function mu4e-message-at-point "mu4e-message") - `message': bookmark the message at point
- `query': bookmark the most recent query
(defun mu4e--jump-to-bookmark (bookmark) - `ask': ask the user interactively"
"View the message referred to by BOOKMARK." :type '(choice
(when-let* ((msgid (bookmark-prop-get bookmark 'message-id))) (const :tag "Bookmark query at point" message)
(mu4e-view-message-with-message-id msgid))) (const :tag "Bookmark the last query" query)
(const :tag "Ask user" ask))
:group 'mu4e)
(defun mu4e--popup-lisp-buffer (bufname data) (defun mu4e--popup-lisp-buffer (bufname data)
"Show or hide an s-expression string in a popup-buffer. "Show or hide an s-expression string in a popup-buffer.

View File

@ -617,8 +617,66 @@ query before submitting it."
(mu4e-warn "No query for %s" chosen)))) (mu4e-warn "No query for %s" chosen))))
(mu4e-search-bookmark query edit))) (mu4e-search-bookmark query edit)))
;; Emacs bookmark support.
(declare-function mu4e-view-message-with-message-id "mu4e-view")
(declare-function mu4e-message-at-point "mu4e-message")
(declare-function mu4e-search-bookmark "mu4e-search")
(declare-function mu4e-server-last-query "mu4e-server")
(defun mu4e--jump-to-bookmark (bmark)
"Handle Emacs bookmark BMARK for either message or query."
(let ((message-id (bookmark-prop-get bmark 'message-id))
(last-query (bookmark-prop-get bmark 'last-query)))
(cond
(message-id (mu4e-view-message-with-message-id message-id))
(last-query (mu4e-search-bookmark (plist-get last-query :query))))))
(defun mu4e--make-bookmark-record ()
"Create an Emacs bookmark for the message at point.
Not to be confused with a *mu4e* bookmark: this is about the
standard Emacs bookmarking facility.
Also see `mu4e-emacs-bookmark-policy'."
(let* ((policy mu4e-emacs-bookmark-policy)
(policy (if (member policy '(message query))
policy
(mu4e-read-option "What to bookmark? "
'(("mMessage at point" . message)
("qLast query" . query)))))
(bmark (cons nil (bookmark-make-record-default
'no-file 'no-context))))
(progn
(bookmark-prop-set bmark 'handler 'mu4e--jump-to-bookmark)
;; add bookmark-type specifics.
(cond
;; bookmark the last query (the full plist)
((eq policy 'query)
(let* ((last-query (mu4e-server-last-query))
(title (plist-get last-query :query)))
(bookmark-prop-set bmark 'defaults (list (concat "Query: " title)))
(bookmark-prop-set bmark 'last-query last-query)))
;; bookmark the message at point
((eq policy 'message)
(let* ((msg (mu4e-message-at-point))
(subject (or (plist-get msg :subject) "No subject"))
(date (plist-get msg :date))
(date (if date (format-time-string "%F: " date) ""))
(title (format "%s%s" date subject))
(msgid (or (plist-get msg :message-id)
(mu4e-error
"Cannot bookmark message without message-id"))))
(bookmark-prop-set bmark 'defaults (list title))
(bookmark-prop-set bmark 'message-id msgid)))
(t ;; something went awry
(mu4e-error "Invalid bookmark policy"))))
;;
bmark))
(defvar mu4e-search-minor-mode-map (defvar mu4e-search-minor-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map "s" #'mu4e-search) (define-key map "s" #'mu4e-search)
(define-key map "S" #'mu4e-search-edit) (define-key map "S" #'mu4e-search-edit)
(define-key map "/" #'mu4e-search-narrow) (define-key map "/" #'mu4e-search-narrow)
@ -637,7 +695,7 @@ query before submitting it."
(define-key map "j" #'mu4e-search-maildir) (define-key map "j" #'mu4e-search-maildir)
map) map)
"Keymap for mu4e-search-minor-mode.") "Keymap for mu4e-search-minor-mode.")
(define-minor-mode mu4e-search-minor-mode (define-minor-mode mu4e-search-minor-mode
"Mode for searching for messages." "Mode for searching for messages."

View File

@ -3464,13 +3464,17 @@ want tweak the details, have a look at @code{mu4e-notification-filter} and
@section Emacs bookmarks @section Emacs bookmarks
@cindex Emacs bookmarks @cindex Emacs bookmarks
Note, Emacs bookmarks are not to be confused with mu4e's bookmarks; the former @t{mu4e} integrates with the Emacs bookmarks system, and allows you to create
are a generic linking system across Emacs, while the latter are stored queries bookmarks with with @code{bookmark-set} for either message-at-point or the last
within @t{mu4e}. query. The message links are based on the message's message-id, and thus the
bookmarks stay valid even if you move the message around.
@t{mu4e} supports linking to the message-at-point through the normal Emacs For deciding whether to link to message or query, you can customize
built-in bookmark system. The links are based on the message's message-id, and @var{mu4e-emacs-bookmark-policy}.
thus the bookmarks stay valid even if you move the message around.
Emacs bookmarks are not to be confused with mu4e's bookmarks; the former are a
generic linking system across Emacs, while the latter are stored queries within
@t{mu4e}.
@node Eldoc @node Eldoc
@section Eldoc @section Eldoc