diff --git a/NEWS.org b/NEWS.org index 4df464a2..e25bec86 100644 --- a/NEWS.org +++ b/NEWS.org @@ -123,10 +123,6 @@ - 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 **** message composer @@ -230,7 +226,7 @@ - links (in text-mode emails) are now clickable through , to be 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 @@ -270,6 +266,18 @@ message view as well, such as ~gnus-mailing-list-subscribe~, ~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 Thanks to our contributors - code committers belows, but also to everyone diff --git a/mu4e/mu4e-helpers.el b/mu4e/mu4e-helpers.el index e8ab7017..17412182 100644 --- a/mu4e/mu4e-helpers.el +++ b/mu4e/mu4e-helpers.el @@ -288,7 +288,7 @@ user can then choose by typing CHAR. Example: User now will be presented with a list: \"Choose an animal: [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. 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")))) +;;; Emacs bookmarks +(defcustom mu4e-emacs-bookmark-policy 'message + "The policy to decide what kind of Emacs bookmark to create. -;;; bookmarks -(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)))) +This applies to the Emacs bookmark system command `bookmark-set'. -(declare-function mu4e-view-message-with-message-id "mu4e-view") -(declare-function mu4e-message-at-point "mu4e-message") - -(defun mu4e--jump-to-bookmark (bookmark) - "View the message referred to by BOOKMARK." - (when-let* ((msgid (bookmark-prop-get bookmark 'message-id))) - (mu4e-view-message-with-message-id msgid))) +The policy is some symbol; you have the following choices: +- `message': bookmark the message at point +- `query': bookmark the most recent query +- `ask': ask the user interactively" + :type '(choice + (const :tag "Bookmark query at point" message) + (const :tag "Bookmark the last query" query) + (const :tag "Ask user" ask)) + :group 'mu4e) (defun mu4e--popup-lisp-buffer (bufname data) "Show or hide an s-expression string in a popup-buffer. diff --git a/mu4e/mu4e-search.el b/mu4e/mu4e-search.el index 72203a01..efcf68da 100644 --- a/mu4e/mu4e-search.el +++ b/mu4e/mu4e-search.el @@ -617,8 +617,66 @@ query before submitting it." (mu4e-warn "No query for %s" chosen)))) (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 - (let ((map (make-sparse-keymap))) + (let ((map (make-sparse-keymap))) (define-key map "s" #'mu4e-search) (define-key map "S" #'mu4e-search-edit) (define-key map "/" #'mu4e-search-narrow) @@ -637,7 +695,7 @@ query before submitting it." (define-key map "j" #'mu4e-search-maildir) map) - "Keymap for mu4e-search-minor-mode.") + "Keymap for mu4e-search-minor-mode.") (define-minor-mode mu4e-search-minor-mode "Mode for searching for messages." diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 5e799a32..9a05eb09 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -3464,13 +3464,17 @@ want tweak the details, have a look at @code{mu4e-notification-filter} and @section Emacs bookmarks @cindex Emacs bookmarks -Note, 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}. +@t{mu4e} integrates with the Emacs bookmarks system, and allows you to create +bookmarks with with @code{bookmark-set} for either message-at-point or the last +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 -built-in bookmark system. The links are based on the message's message-id, and -thus the bookmarks stay valid even if you move the message around. +For deciding whether to link to message or query, you can customize +@var{mu4e-emacs-bookmark-policy}. + +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 @section Eldoc