mu4e: implement label updating through marks
Add support for updating label, using the marking interface. Add some helpers for dealing with (delta) labels Add keybindings to headers / views Update docs
This commit is contained in:
@ -52,6 +52,7 @@ mu4e_srcs=[
|
||||
'mu4e-headers.el',
|
||||
'mu4e-helpers.el',
|
||||
'mu4e-icalendar.el',
|
||||
'mu4e-labels.el',
|
||||
'mu4e-lists.el',
|
||||
'mu4e-main.el',
|
||||
'mu4e-mark.el',
|
||||
@ -115,7 +116,6 @@ foreach src : mu4e_srcs
|
||||
'--eval', '(setq byte-compile-warnings \'(not obsolete))',
|
||||
'--eval', target_func,
|
||||
'--funcall', 'batch-byte-compile', '@INPUT@'])
|
||||
|
||||
endforeach
|
||||
|
||||
# this depends on the above hack: all mu4e elisp files needs to be in builddir
|
||||
|
||||
@ -913,6 +913,8 @@ COUNT is the number of messages found."
|
||||
(mu4e~headers-defun-mark-for untrash)
|
||||
(mu4e~headers-defun-mark-for unmark)
|
||||
(mu4e~headers-defun-mark-for unread)
|
||||
(mu4e~headers-defun-mark-for label)
|
||||
(mu4e~headers-defun-mark-for unlabel)
|
||||
(mu4e~headers-defun-mark-for action)
|
||||
|
||||
(declare-function mu4e-view-pipe "mu4e-view")
|
||||
@ -964,6 +966,9 @@ COUNT is the number of messages found."
|
||||
|
||||
(define-key map (kbd "?") #'mu4e-headers-mark-for-unread)
|
||||
(define-key map (kbd "!") #'mu4e-headers-mark-for-read)
|
||||
(define-key map (kbd "l") #'mu4e-headers-mark-for-label)
|
||||
(define-key map (kbd "L") #'mu4e-headers-mark-for-unlabel)
|
||||
|
||||
(define-key map (kbd "A") #'mu4e-headers-mark-for-action)
|
||||
|
||||
(define-key map (kbd "u") #'mu4e-headers-mark-for-unmark)
|
||||
|
||||
153
mu4e/mu4e-labels.el
Normal file
153
mu4e/mu4e-labels.el
Normal file
@ -0,0 +1,153 @@
|
||||
;;; mu4e-labels.el --- Dealing with labels -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2025 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; mu4e is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; mu4e is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with mu4e. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; In this file, add some helpers for dealing with message labels
|
||||
|
||||
;;; Code:
|
||||
(require 'mu4e-message)
|
||||
(require 'mu4e-server)
|
||||
(require 'mu4e-helpers)
|
||||
|
||||
(defconst mu4e-label-regex
|
||||
(rx-let ((taboo (any cntrl blank "\"'\\/`$"))
|
||||
(taboo1-extra (any "-+")))
|
||||
(rx (seq
|
||||
;; First character: base forbidden + extra chars
|
||||
(not (or taboo taboo1-extra))
|
||||
;; Rest: just base forbidden chars
|
||||
(zero-or-more (not taboo)))))
|
||||
"Unanchored regular expression matching a valid label.
|
||||
|
||||
Any character is allowed that is not a control-character, a
|
||||
blank, or ASCII single/double quotes,backtick or
|
||||
forward/backward slash; additionally, the first character cannot
|
||||
be a \"+\" or \"-\", \"$\" either.")
|
||||
|
||||
(defun mu4e-label-validate (str)
|
||||
"Validate label STR.
|
||||
|
||||
If STR is a valid label, return STR. Otherwise, raise an warning.
|
||||
This function attempts to be a bit more informative than simply
|
||||
checking a regular expression.
|
||||
|
||||
See `mu4e-label-regex' for the definition of the valid format."
|
||||
(when (string-empty-p str) ;; i. must not be empty
|
||||
(mu4e-warn "invalid: empty string"))
|
||||
(let ((first (aref str 0)))
|
||||
;; ii. must not start with + or -
|
||||
(when (or (char-equal first ?+) (char-equal first ?-))
|
||||
(mu4e-warn "invalid: starts with '%c'" first))
|
||||
;; iii. check all characters a valid:
|
||||
(seq-do (lambda (kar)
|
||||
(unless (string-match-p mu4e-label-regex
|
||||
(string ?_ kar))
|
||||
(mu4e-warn "invalid: character '%c'" kar)))
|
||||
str))
|
||||
str)
|
||||
|
||||
(defun mu4e-label-parse-expr (expr)
|
||||
"Parse a single delta expression EXPR.
|
||||
|
||||
If EXPR is non-empty, raises an error if EXPR is not a valid
|
||||
delta. Otherwise, returns EXPR with extra whitespace removed.
|
||||
|
||||
If STR is empty, return nil."
|
||||
(let ((op (aref expr 0))
|
||||
(label (substring expr 1)))
|
||||
(unless (or (char-equal op ?+) (char-equal op ?-))
|
||||
(mu4e-warn "invalid: delta-expression must start with '+' or '-'"))
|
||||
(concat (char-to-string op)
|
||||
(mu4e-label-validate label))))
|
||||
|
||||
(defun mu4e-label-parse-exprs (exprs)
|
||||
"Parse a string EXPRS with deltas to a string.
|
||||
|
||||
If EXPRS is non-empty, raises an error if EXPRS is invalid.
|
||||
Otherwise, return EXPRS with extra whitespace removed.
|
||||
|
||||
If EXPRS is empty, return nil."
|
||||
(mapconcat #'mu4e-label-parse-expr (split-string exprs) " "))
|
||||
|
||||
(defvar mu4e-labels-list nil "Cached list of labels.")
|
||||
|
||||
(defun mu4e--labels-completion-at-point ()
|
||||
"Provide completion when entering a label delta expressions."
|
||||
(cond
|
||||
((not (looking-back "[^ \t]*" nil))
|
||||
(let ((bounds (bounds-of-thing-at-point 'word)))
|
||||
(list (or (car bounds) (point))
|
||||
(or (cdr bounds) (point)))))
|
||||
((looking-back
|
||||
(rx (any "+" "-")
|
||||
(group
|
||||
(opt (regex mu4e-label-regex)))) nil)
|
||||
(list (match-beginning 1)
|
||||
(match-end 1)
|
||||
mu4e-labels-list))))
|
||||
|
||||
(defvar mu4e-minibuffer-label-expr-map
|
||||
(let ((map (copy-keymap minibuffer-local-map)))
|
||||
(define-key map (kbd "TAB") #'completion-at-point)
|
||||
map)
|
||||
"The keymap for reading label delta expression.")
|
||||
|
||||
(defun mu4e-labels-delta-read ()
|
||||
"Ask for a labels delta expression."
|
||||
(minibuffer-with-setup-hook
|
||||
(lambda ()
|
||||
(setq-local completion-at-point-functions
|
||||
#'mu4e--labels-completion-at-point)
|
||||
(use-local-map mu4e-minibuffer-label-expr-map))
|
||||
(mu4e-label-parse-exprs
|
||||
(read-string "Label delta expression: "))))
|
||||
|
||||
(defun mu4e--labels-update-server (docid expr)
|
||||
"Tell the server to update message with DOCID with EXPR.
|
||||
EXPR is a label delta-expression, such as \"+foo -bar\".
|
||||
|
||||
Update the label cache while doing so."
|
||||
;; update the cache
|
||||
(let ((expr (mu4e-label-parse-exprs expr))
|
||||
(labels ;; the list of labels without +/- prefix
|
||||
(seq-map (lambda (pmlabel)
|
||||
(substring pmlabel 1))
|
||||
(split-string expr " "))))
|
||||
;; don't care about dups etc.; the list
|
||||
;; will be replaced by a fresh server-side one, after
|
||||
;; update / restart
|
||||
(setq mu4e-labels-list
|
||||
(append labels mu4e-labels-list))
|
||||
;; update the server
|
||||
(mu4e--server-label docid expr)))
|
||||
|
||||
(defun mu4e--labels-clear-server (docid)
|
||||
"Clear all labels from message with DOCID."
|
||||
;; update the server
|
||||
;; '-*' is not a valid label, but special-cased
|
||||
;; on the server-side
|
||||
(mu4e--server-label docid "-*"))
|
||||
|
||||
|
||||
(provide 'mu4e-labels)
|
||||
;;; mu4e-labels.el ends here
|
||||
@ -1,6 +1,6 @@
|
||||
;;; mu4e-mark.el --- Marking messages -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2011-2024 Dirk-Jan C. Binnema
|
||||
;; Copyright (C) 2011-2025 Dirk-Jan C. Binnema
|
||||
|
||||
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||
@ -30,6 +30,7 @@
|
||||
(require 'mu4e-server)
|
||||
(require 'mu4e-message)
|
||||
(require 'mu4e-folders)
|
||||
(require 'mu4e-labels)
|
||||
|
||||
;; keep byte-compiler happy
|
||||
(declare-function mu4e~headers-mark "mu4e-headers")
|
||||
@ -155,6 +156,11 @@ The current buffer must be either a headers or view buffer."
|
||||
:show-target (lambda (target) "flag")
|
||||
:action (lambda (docid msg target)
|
||||
(mu4e--server-move docid nil "+F-u-N")))
|
||||
(unflag
|
||||
:char ("-" . "➖")
|
||||
:prompt "-unflag"
|
||||
:show-target (lambda (target) "unflag")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "-F-N")))
|
||||
(move
|
||||
:char ("m" . "▷")
|
||||
:prompt "move"
|
||||
@ -166,6 +172,12 @@ The current buffer must be either a headers or view buffer."
|
||||
:prompt "!read"
|
||||
:show-target (lambda (target) "read")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "+S-u-N")))
|
||||
(unread
|
||||
:char ("?" . "◻")
|
||||
:prompt "?unread"
|
||||
:show-target (lambda (target) "unread")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "-S+u-N")))
|
||||
|
||||
(trash
|
||||
:char ("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
@ -174,25 +186,29 @@ The current buffer must be either a headers or view buffer."
|
||||
(mu4e--server-move docid
|
||||
(mu4e--mark-check-target target)
|
||||
(if mu4e-trash-without-flag "-N" "+T-N"))))
|
||||
(unflag
|
||||
:char ("-" . "➖")
|
||||
:prompt "-unflag"
|
||||
:show-target (lambda (target) "unflag")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "-F-N")))
|
||||
(untrash
|
||||
:char ("=" . "▲")
|
||||
:prompt "=untrash"
|
||||
:show-target (lambda (target) "untrash")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "-T")))
|
||||
(unread
|
||||
:char ("?" . "◻")
|
||||
:prompt "?unread"
|
||||
:show-target (lambda (target) "unread")
|
||||
:action (lambda (docid msg target) (mu4e--server-move docid nil "-S+u-N")))
|
||||
|
||||
(label
|
||||
:char ("l" . "🏷")
|
||||
:prompt "label"
|
||||
:ask-target mu4e-labels-delta-read
|
||||
:action (lambda (docid msg expr)
|
||||
(mu4e--labels-update-server docid expr)))
|
||||
(unlabel
|
||||
:char ("L" . "∅")
|
||||
:prompt "unlabel"
|
||||
:show-target (lambda (target) "clear labels")
|
||||
:action (lambda (docid msg expr)
|
||||
(mu4e--labels-clear-server docid)))
|
||||
(unmark
|
||||
:char " "
|
||||
:prompt "unmark"
|
||||
:action (mu4e-error "No action for unmarking"))
|
||||
|
||||
(action
|
||||
:char ( "a" . "◯")
|
||||
:prompt "action"
|
||||
@ -251,6 +267,8 @@ The following marks are available, and the corresponding props:
|
||||
`untrash' n remove the `trashed' flag from a message
|
||||
`unmark' n unmark this message
|
||||
`unread' n mark the message as unread
|
||||
`label' y (re)label the message
|
||||
`unlabel' n clear all labels
|
||||
`action' y mark the message for some action."
|
||||
(interactive)
|
||||
(let* ((msg (mu4e-message-at-point))
|
||||
@ -311,6 +329,11 @@ The following marks are available, and the corresponding props:
|
||||
(when (mu4e-create-maildir-maybe fulltarget)
|
||||
target)))
|
||||
|
||||
(defun mu4e--mark-get-labels-target ()
|
||||
"Ask for a labels expression."
|
||||
(let* ((exprs (read-from-minibuffer "Label expression: ")))
|
||||
(mu4e-label-parse-exprs exprs)))
|
||||
|
||||
(defun mu4e--mark-ask-target (mark)
|
||||
"Ask the target for MARK, if the user should be asked the target."
|
||||
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target)))
|
||||
@ -431,7 +454,8 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
|
||||
(message nil)))))
|
||||
|
||||
(defun mu4e-mark-unmark-all (&optional no-confirmation)
|
||||
"Unmark all marked messages."
|
||||
"Unmark all marked messages.
|
||||
If NO-CONFIRMATION is non-nil, do not ask for confirmation."
|
||||
(interactive)
|
||||
(mu4e--mark-in-context
|
||||
(when (zerop (mu4e-mark-marks-num))
|
||||
|
||||
@ -154,9 +154,6 @@ but also manually invoked searches."
|
||||
:type 'hook
|
||||
:group 'mu4e-search)
|
||||
|
||||
(defvar mu4e-labels-list nil
|
||||
"Cached list of labels.")
|
||||
|
||||
;; Internals
|
||||
|
||||
;;; History
|
||||
|
||||
@ -708,6 +708,10 @@ the directory time stamp."
|
||||
:lazy-check ,(and lazy-check t)))
|
||||
(setq mu4e--server-indexing t)) ;; remember we're indexing.
|
||||
|
||||
(defun mu4e--server-label (docid delta-expr)
|
||||
"Apply the label DELTA-EXPR to the message with DOCID."
|
||||
(mu4e--server-call-mu `(label :docid ,docid :labels ,delta-expr)))
|
||||
|
||||
(defun mu4e--server-mkdir (path &optional update)
|
||||
"Create a new maildir-directory at file system PATH.
|
||||
When UPDATE is non-nil, send a update when completed.
|
||||
|
||||
@ -411,6 +411,8 @@ list."
|
||||
(mu4e--view-defun-mark-for unread)
|
||||
(mu4e--view-defun-mark-for trash)
|
||||
(mu4e--view-defun-mark-for untrash)
|
||||
(mu4e--view-defun-mark-for label)
|
||||
(mu4e--view-defun-mark-for unlabel)
|
||||
|
||||
(defun mu4e-view-marked-execute ()
|
||||
"Execute the marked actions."
|
||||
@ -1008,6 +1010,9 @@ This is useful for advising some Gnus-functionality that does not work in mu4e."
|
||||
(define-key map (kbd "=") #'mu4e-view-mark-for-untrash)
|
||||
(define-key map (kbd "&") #'mu4e-view-mark-custom)
|
||||
|
||||
(define-key map (kbd "l") #'mu4e-view-mark-for-label)
|
||||
(define-key map (kbd "L") #'mu4e-view-mark-for-unlabel)
|
||||
|
||||
(define-key map (kbd "*") #'mu4e-view-mark-for-something)
|
||||
(define-key map (kbd "<kp-multiply>") #'mu4e-view-mark-for-something)
|
||||
(define-key map (kbd "<insert>") #'mu4e-view-mark-for-something)
|
||||
|
||||
111
mu4e/mu4e.texi
111
mu4e/mu4e.texi
@ -196,9 +196,10 @@ following information:
|
||||
|
||||
@itemize
|
||||
@item What did you expect or wish to happen? what actually happened?
|
||||
Please describe in detail what you saw. Also, try some related scenarios and
|
||||
whether the problem either @emph{always} happens, or only @emph{sometimes}.
|
||||
E.g., it might happen with only one particular type of message
|
||||
Please describe in detail what you saw; what did you expect to happen and what
|
||||
actually happened? Also, please try some related scenarios and whether the
|
||||
problem either @emph{always} happens, or only @emph{sometimes}. E.g., the issue
|
||||
might happen with only one particular type of message
|
||||
@item Provide some exact steps to reproduce?
|
||||
In particular, some minimal steps, starting from @t{emacs -Q} and with minimal
|
||||
configuration. If the problem is easily producible, it may be easily fixable as
|
||||
@ -215,7 +216,6 @@ reproducing your problem, not the ``remix'' version that some Emacs
|
||||
In general, imagine you would be the person receiving the bug-report, and think
|
||||
about the information you would need to diagnose the problem.
|
||||
|
||||
|
||||
@node Getting started
|
||||
@chapter Getting started
|
||||
|
||||
@ -1046,6 +1046,7 @@ DEL,D mark for complete deletion
|
||||
m mark for moving to another maildir folder
|
||||
r mark for refiling
|
||||
+,- mark for flagging/unflagging
|
||||
l mark for labels
|
||||
?,! mark message as unread, read
|
||||
|
||||
u unmark message at point
|
||||
@ -1090,11 +1091,13 @@ Some keybindings are available through minor modes:
|
||||
@node HV Marking
|
||||
@section Marking
|
||||
|
||||
You can @emph{mark} messages for a certain action, such as deletion or
|
||||
move. After one or more messages are marked, you can then execute
|
||||
You can @emph{mark} messages for a certain action, such as deletion or move or
|
||||
changing the labels.
|
||||
|
||||
After one or more messages are marked, you can then execute
|
||||
(@code{mu4e-mark-execute-all}, @key{x}) these actions. This two-step
|
||||
mark-execute sequence is similar to what e.g. @t{dired} does. It is how
|
||||
@t{mu4e} tries to be as quick as possible, while avoiding accidents.
|
||||
mark-execute sequence is similar to what e.g. @t{dired} does. It is how @t{mu4e}
|
||||
tries to be as quick as possible, while avoiding accidents.
|
||||
|
||||
The mark/unmark commands support the @emph{region} (i.e., ``selection'')
|
||||
--- so, for example, if you select some messages and press @key{DEL},
|
||||
@ -1423,6 +1426,7 @@ d mark for moving to the trash folder
|
||||
DEL,D mark for complete deletion
|
||||
m mark for moving to another maildir folder
|
||||
r mark for refiling
|
||||
l mark for labels
|
||||
+,- mark for flagging/unflagging
|
||||
|
||||
u unmark message at point
|
||||
@ -2431,7 +2435,7 @@ Note, messages are considered duplicates when they have the same
|
||||
In @t{mu4e}, the common way to do things with messages is a two-step process -
|
||||
first you @emph{mark} them for a certain action, then you @emph{execute}
|
||||
(@key{x}) those marks. This is similar to the way @t{dired} operates. Marking
|
||||
can happen in both the @ref{Headers view} and the @ref{Message view}.
|
||||
can happen from both the @ref{Headers view} and the @ref{Message view}.
|
||||
|
||||
@menu
|
||||
* Marking messages::Selecting message do something with them
|
||||
@ -2472,22 +2476,84 @@ messages.
|
||||
@verbatim
|
||||
mark for/as | keybinding | description
|
||||
-------------+-------------+------------------------------
|
||||
'something' | *, <insert> | mark now, decide later
|
||||
delete | D, <delete> | delete
|
||||
flag | + | mark as 'flagged' ('starred')
|
||||
move | m | move to some maildir
|
||||
read | ! | mark as read
|
||||
refile | r | mark for refiling
|
||||
-------------+-------------+------------------------------
|
||||
flag | + | mark as 'flagged' ('starred')
|
||||
unflag | - | remove 'flagged' mark
|
||||
read | ! | mark as read
|
||||
unread | ? | marks as unread
|
||||
trash | d | move to the trash folder
|
||||
untrash | = | remove 'trash' flag
|
||||
unflag | - | remove 'flagged' mark
|
||||
-------------+-------------+------------------------------
|
||||
label | l | change the labels
|
||||
unlabel | L | clear all labels
|
||||
action | a | apply some action
|
||||
'something' | *, <insert> | mark now, decide later
|
||||
-------------+-------------------------------------------
|
||||
unmark | u | remove mark at point
|
||||
unmark all | U | remove all marks
|
||||
unread | ? | marks as unread
|
||||
action | a | apply some action
|
||||
-------------+-------------------------------------------
|
||||
@end verbatim
|
||||
@end cartouche
|
||||
|
||||
@itemize
|
||||
@item @emph{delete} deletes the message from database and file-system
|
||||
@item @emph{move} moves the message to some different maildir
|
||||
@item @emph{refile} is similar @emph{move}, but determines the target maildir based
|
||||
on the characteristics of the message; this is very powerful. See
|
||||
@code{mu4e-refile-folder} and especially @xref{Smart refiling} for details.
|
||||
@item @emph{flag}/@emph{unflag}, @emph{read}/@emph{unread} and @emph{trash}/@emph{untrash}
|
||||
set or unset the corresponding Maildir flags
|
||||
@item @emph{label} lets you enter a label delta expression which gets applied; see below
|
||||
@item @emph{unlabel} lets you clear @emph{all} labels; see below
|
||||
@item @emph{action} lets you apply some pre-defined action on the message, as per @code{mu4e-headers-actions}
|
||||
@item @emph{'something'} marks the message for ``something'', and then decide
|
||||
later what this something should be; see below
|
||||
@item @emph{unmark} and @emph{unmark all} are ``meta'' marks, which remove the mark from the currently selected message(s) or all
|
||||
@end itemize
|
||||
|
||||
@node Applying and clearing labels
|
||||
@subsection Applying and clearing labels
|
||||
@cindex labels
|
||||
|
||||
The @t{label} mark lets you apply @emph{labels} to messages, which are short
|
||||
strings to attach to this message which you can query using the @t{label:}
|
||||
field. To see them in your headers / message views, you need to add the field to
|
||||
the @code{mu4e-headers-fields} and @code{mu4e-view-fields}, respectively.
|
||||
|
||||
To change the labels for some message, you specify a @emph{label expression},
|
||||
which consists of a space-separated sequence of labels, each prefixed either
|
||||
with a @t{+} to add the label or @t{-} to remove it.
|
||||
|
||||
For instance, to remove the @t{boring} label and add @t{urgent} from the message
|
||||
at point or the messages in region, press @kbd{l} and enter:
|
||||
@example
|
||||
+urgent -boring
|
||||
@end example
|
||||
|
||||
For @emph{clearing all labels}, you mark with @kbd{L} ('unlabel').
|
||||
|
||||
You can search for labels using the @t{label:} field. For instance,
|
||||
@t{label:urgent} retrieves all messages labeled @t{urgent}.
|
||||
|
||||
It is important to note that the labels are only stored in the database (the
|
||||
message files are not changed). This means that you loose this information when
|
||||
you remove the database and recrate it; it is however possible to @emph{export}
|
||||
the labels and re-@emph{import} them later; see the @t{mu-label} man-page for
|
||||
further details.
|
||||
|
||||
@subsection Doing @emph{something}
|
||||
|
||||
@t{something} is a special kind of mark; you can use it to mark messages for
|
||||
`something', and then decide later what the `something' should be@footnote{This
|
||||
kind of `deferred marking' is similar to the facility in @t{dired}, @t{midnight
|
||||
commander} (@url{https://www.midnight-commander.org/}) and the like, and uses
|
||||
the same key binding (@key{insert}).} Later, you can set the actual mark using
|
||||
@kbd{M-x mu4e-mark-resolve-deferred-marks} (@key{#}). Alternatively, @t{mu4e}
|
||||
will ask you when you try to execute the marks (@key{x}).
|
||||
|
||||
After marking a message, the left-most columns in the headers view indicate
|
||||
the kind of mark. This is informative, but if you mark many (say, thousands)
|
||||
messages, this slows things down significantly@footnote{this uses an
|
||||
@ -2495,15 +2561,6 @@ Emacs feature called @emph{overlays}, which are slow when used a lot
|
||||
in a buffer}. For this reason, you can disable this by setting
|
||||
@code{mu4e-headers-show-target} to @code{nil}.
|
||||
|
||||
@t{something} is a special kind of mark; you can use it to mark messages
|
||||
for `something', and then decide later what the `something' should
|
||||
be@footnote{This kind of `deferred marking' is similar to the facility
|
||||
in @t{dired}, @t{midnight commander}
|
||||
(@url{https://www.midnight-commander.org/}) and the like, and uses the
|
||||
same key binding (@key{insert}).} Later, you can set the actual mark
|
||||
using @kbd{M-x mu4e-mark-resolve-deferred-marks}
|
||||
(@key{#}). Alternatively, @t{mu4e} will ask you when you try to execute
|
||||
the marks (@key{x}).
|
||||
|
||||
@node Executing the marks
|
||||
@section Executing the marks
|
||||
@ -2598,7 +2655,6 @@ messages. There are more examples in the defaults for
|
||||
@code{mu4e-headers-custom-markers}; see @file{mu4e-headers.el} and see
|
||||
@ref{Extending mu4e} for general information about writing your own functions.
|
||||
|
||||
|
||||
@node Adding a new kind of mark
|
||||
@section Adding a new kind of mark
|
||||
|
||||
@ -3128,7 +3184,10 @@ viewing messages in an external web browser or tagging.
|
||||
It is easy to add such actions to your configuration; for instance, to enable
|
||||
@emph{tagging}@footnote{@t{mu4e} does not offer tagging by default since it
|
||||
mutates the message files, something that @t{mu}/@t{mu4e} generally try to
|
||||
avoid.} both in the message view and headers view, you could add:
|
||||
avoid. An alternative to tagging is @emph{labeling}, @xref{Applying and clearing
|
||||
labels}
|
||||
|
||||
} both in the message view and headers view, you could add:
|
||||
@lisp
|
||||
(add-to-list 'mu4e-headers-actions
|
||||
'("Tag message" . mu4e-action-retag-message))
|
||||
|
||||
Reference in New Issue
Block a user