From 0153f7538ec95b0033c1d1c9cc5c73859d8eec81 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Mon, 15 Mar 2021 22:55:21 +0200 Subject: [PATCH] mu4e: update documentation Add the beginning of some docs for the gnus-view. --- mu4e/mu4e.texi | 403 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 291 insertions(+), 112 deletions(-) diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 1bb61e32..51f5c233 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -90,7 +90,8 @@ section with answers to frequenly asked questions, @ref{FAQ}. * Main view:: The @t{mu4e} overview * Headers view:: Lists of message headers * Message view:: Viewing specific messages -* Editor view:: Creating / editing messages +* Old message view:: The old way to view messages +* Editor view:: Creating and editing messages * Searching:: Some more background on searching/queries` * Marking:: Marking messages and performing actions * Contexts:: Defining contexts and switching between them @@ -753,34 +754,34 @@ The main view looks something like the following: Basics - * [j]ump to some maildir - * enter a [s]earch query - * [C]ompose a new message + * [j]ump to some maildir + * enter a [s]earch query + * [C]ompose a new message Bookmarks - * [bu] Unread messages (26119/26119) - * [bt] Today's messages (1/7) - * [bw] Last 7 days (30/126) - * [bp] Messages with images (268/2309) + * [bu] Unread messages (26119/26119) + * [bt] Today's messages (1/7) + * [bw] Last 7 days (30/126) + * [bp] Messages with images (268/2309) Maildirs - * [ja] /archive (3174/17990) - * [ji] /inbox (0/2) - * [jm] /mu (1541/14884) - * [js] /sent + * [ja] /archive (3174/17990) + * [ji] /inbox (0/2) + * [jm] /mu (1541/14884) + * [js] /sent Misc - * [;]Switch context - * [U]pdate email & database - * toggle [m]ail sending mode (currently direct) + * [;]Switch context + * [U]pdate email & database + * toggle [m]ail sending mode (currently direct) - * [N]ews - * [A]bout mu4e - * [H]elp - * [q]uit + * [N]ews + * [A]bout mu4e + * [H]elp + * [q]uit Info @@ -1182,25 +1183,22 @@ headers-view to the message-view and vice-versa with @code{mu4e-select-other-view}, bound to @key{y} @end itemize + @node Message view @chapter The message view -After selecting a message in the @ref{Headers view}, it appears in a message -view window, which shows the message headers, followed by the message -body. Its major mode is @code{mu4e-view-mode}. +This chapter discusses the new (since version 1.6) Gnus-based message +view. However, the old one is stil available -- see @ref{Old message +view}. -Note, the current message view is to be replaced by a new one, based on -Gnus' article-mode. It is available now as a 'tech preview', which you -can try by setting @code{mu4e-view-use-gnus} to @code{t} before starting -@code{mu4e}. +After selecting a message in the @ref{Headers view}, it appears in a +message view window, which shows the message headers, followed by the +message body. Its major mode is @code{mu4e-view-mode}, which derives +from @t{gnus-article-mode}. @menu * Overview: MSGV Overview. What is the Message View * Keybindings: MSGV Keybindings. Do things with your keyboard -* Attachments:: Opening and saving them -* Viewing images inline::Images display inside emacs -* Displaying rich-text messages::Dealing with HTML mail -* Verifying signatures and decryption: MSGV Crypto. Support for cryptography * Custom headers: MSGV Custom headers. Your own headers * Actions: MSGV Actions. Defining and using actions. @end menu @@ -1210,6 +1208,184 @@ can try by setting @code{mu4e-view-use-gnus} to @code{t} before starting An example message view: +@cartouche +@verbatim + From: randy@epiphyte.com + To: julia@eruditorum.org + Subject: Re: some pics + Flags: seen, attach + Date: Thu, 11 Feb 2021 12:59:30 +0200 (4 weeks, 3 days, 21 hours ago) + Maildir: /inbox + Attachments: [2. image/jpeg; DSCN4961.JPG]... [3. image/jpeg; DSCN4962.JPG]... + + Hi Julia, + + Some pics from our trip to Cerin Amroth. Enjoy! + + All the best, + Randy. + + On Sun 21 Dec 2003 09:06:34 PM EET, Julia wrote: + + [....] +@end verbatim +@end cartouche + +Some notes: +@itemize +@item The variable @code{mu4e-view-fields} determines the header fields to be +shown; see @code{mu4e-header-info} for a list of built-in fields. Apart from +the built-in fields, you can also create custom fields using +@code{mu4e-header-info-custom}; see @ref{MSGV Custom headers}. +@item For search-related operations, see @ref{Searching}. +@item You can scroll down the message using @key{SPC}; if you do this at the +end of a message,it automatically takes you to the next one. If you want to +prevent this behavior, set @code{mu4e-view-scroll-to-next} to @code{nil}. +@end itemize + +@node MSGV Keybindings +@section Keybindings + +You can find most things you can do with this message in the @emph{Mu4e} menu, +or by using the keyboard; the default bindings are: + +@verbatim +key description +============================================================== +n,p view the next, previous message +],[ move to the next, previous unread message +y select the headers view (if it's visible) + +RET scroll down +M-RET open URL at point / attachment at point + +SPC scroll down, if at end, move to next message +S-SPC scroll up + +searching +--------- +s search +e edit last query +/ narrow the search +b search bookmark +B edit bookmark before search +j jump to maildir + +M-left previous query +M-right next query + +marking +------- +d mark for moving to the trash folder += mark for removing trash flag ('untrash') +DEL,D mark for complete deletion +m mark for moving to another maildir folder +r mark for refiling ++,- mark for flagging/unflagging + +u unmark message at point +U unmark *all* messages + +% mark based on a regular expression +T,t mark whole thread, subthread + +,* mark for 'something' (decide later) +# resolve deferred 'something' marks + +x execute actions for the marked messages + +composition +----------- +R,F,C reply/forward/compose +E edit (only allowed for draft messages) + +actions +------- +g go to (visit) numbered URL (using `browse-url') +(or: or M-RET with point on url) +C-u g visits multiple URLs +f fetch (download )the numbered URL. +C-u f fetches multiple URLs +k save the numbered URL in the kill-ring. +C-u k saves multiple URLs + +e extract (save) one or more attachments (asks for numbers) +(or: or S-RET with point on attachment) +a execute some custom action on the message + +misc +---- +; switch context +c copy address at point (with C-u copy long version) + +h toggle between html/text (if available) + +. show the raw message view. 'q' takes you back. +C-+,C-- increase / decrease the number of headers shown +H get help +C-S-u update mail & reindex +q leave the message view +@end verbatim + +For the marking commands, please refer to @ref{Marking messages}. + + +@node MSGV Custom headers +@section Custom headers + +Sometimes the normal headers that @t{mu4e} offers (Date, From, To, +Subject etc.) may not be enough. For these cases, @t{mu4e} offers +@emph{custom headers} in both the headers-view and the message-view. + +See @ref{HV Custom headers} for an example of this; the difference for +the message-view is that you should add your custom header to +@code{mu4e-view-fields} rather than @code{mu4e-headers-fields}. + +@node MSGV Actions +@section Actions + +You can perform custom functions (``actions'') on messages and their +attachments. For a general discussion on how to define your own, see +@ref{Actions}. + +@subsection Message actions +@code{mu4e-view-action} (@key{a}) lets you pick some custom action to perform +on the current message. You can specify these actions using the variable +@code{mu4e-view-actions}; @t{mu4e} defines a number of example actions. + + +@node Old message view +@chapter The old message view + +Since version 1.6 @t{mu4e} defaults to the new, Gnus-based, message view. + +However, the older view is still available, and this chapter is about +that one. While we recommend using the default one, you can still use +the old one by configuring it: +@lisp +(setq mu4e-view-use-gnus nil) +@end lisp + +After selecting a message in the @ref{Headers view}, it appears in a message +view window, which shows the message headers, followed by the message +body. Its major mode is @code{mu4e-view-mode}. + +@menu +* Overview: OMSGV Overview. What is the Message View +* Keybindings: OMSGV Keybindings. Do things with your keyboard +* Attachments:: Opening and saving them +* Viewing images inline::Images display inside emacs +* Displaying rich-text messages::Dealing with HTML mail +* Verifying signatures and decryption: OMSGV Crypto. Support for cryptography +* Custom headers: OMSGV Custom headers. Your own headers +* Actions: OMSGV Actions. Defining and using actions. +@end menu + +@node OMSGV Overview +@section Overview + +An example message view: + @cartouche @verbatim From: randy@epiphyte.com @@ -1238,7 +1414,7 @@ Some notes: @item The variable @code{mu4e-view-fields} determines the header fields to be shown; see @code{mu4e-header-info} for a list of built-in fields. Apart from the built-in fields, you can also create custom fields using -@code{mu4e-header-info-custom}; see @ref{MSGV Custom headers}. +@code{mu4e-header-info-custom}; see @ref{OMSGV Custom headers}. @item You can set the date format with the variable @code{mu4e-date-format-long}. @item By default, only the names of contacts in address fields are visible @@ -1263,7 +1439,7 @@ end of a message,it automatically takes you to the next one. If you want to prevent this behavior, set @code{mu4e-view-scroll-to-next} to @code{nil}. @end itemize -@node MSGV Keybindings +@node OMSGV Keybindings @section Keybindings You can find most things you can do with this message in the @emph{Mu4e} menu, @@ -1508,8 +1684,8 @@ long messages in some external browser (see `browse-url-generic-program')." (let ((html (or (mu4e-message-field msg :body-html) ""))) (if (> (length html) 20000) (progn - (mu4e-action-view-in-browser msg) - "[Viewing message in external browser]") + (mu4e-action-view-in-browser msg) + "[Viewing message in external browser]") (mu4e-shr2text msg)))) (setq mu4e-html2text-command 'my-mu4e-html2text) @@ -1526,7 +1702,7 @@ If that is an issue, it is recommended to use a browser (or browser profile) that does not load images. The same applies to Javascript. -@node MSGV Crypto +@node OMSGV Crypto @section Crypto The @t{mu4e} message view supports decryption of encrypted messages, @@ -1598,7 +1774,7 @@ Also, the From: address can easily be forged. For more information, see the @command{mu-verify} manual page. -@node MSGV Custom headers +@node OMSGV Custom headers @section Custom headers Sometimes the normal headers that @t{mu4e} offers (Date, From, To, Subject @@ -1609,7 +1785,7 @@ See @ref{HV Custom headers} for an example of this; the difference for the message-view is that you should add your custom header to @code{mu4e-view-fields} rather than @code{mu4e-headers-fields}. -@node MSGV Actions +@node OMSGV Actions @section Actions You can perform custom functions (``actions'') on messages and their @@ -1773,13 +1949,13 @@ Let's look at some examples. First, suppose we want to set the "Set the From address based on the To address of the original." (let ((msg mu4e-compose-parent-message)) ;; msg is shorter... (when msg - (setq user-mail-address - (cond - ((mu4e-message-contact-field-matches msg :to "me@@foo.example.com") - "me@@foo.example.com") - ((mu4e-message-contact-field-matches msg :to "me@@bar.example.com") - "me@@bar.example.com") - (t "me@@cuux.example.com"))))))) + (setq user-mail-address + (cond + ((mu4e-message-contact-field-matches msg :to "me@@foo.example.com") + "me@@foo.example.com") + ((mu4e-message-contact-field-matches msg :to "me@@bar.example.com") + "me@@bar.example.com") + (t "me@@cuux.example.com"))))))) @end lisp Secondly, as mentioned, @code{mu4e-compose-mode-hook} is especially @@ -1810,12 +1986,12 @@ Or to something context-specific: (add-hook 'mu4e-compose-mode-hook (lambda() (let* ((ctx (mu4e-context-current)) - (name (if ctx (mu4e-context-name ctx)))) + (name (if ctx (mu4e-context-name ctx)))) (when name - (cond - ((string= name "account1") + (cond + ((string= name "account1") (save-excursion (message-add-header "Bcc: account1@@example.com\n"))) - ((string= name "account2") + ((string= name "account2") (save-excursion (message-add-header "Bcc: account2@@example.com\n")))))))) @end lisp @@ -1833,7 +2009,7 @@ mml-secure-message-encrypt-pgp}, @kbd{M-x mml-secure-message-sign-pgp}. The support for encryption and signing is @emph{independent} of the support for their counterparts, decrypting and signature verification (as discussed in -@ref{MSGV Crypto}). Even if your @t{mu4e} does not have support for the latter +@ref{OMSGV Crypto}). Even if your @t{mu4e} does not have support for the latter two, you can still sign/encrypt messages. Important note: the messages are encrypted when they are @emph{sent}: @@ -2434,7 +2610,7 @@ than @emph{n} recipients --- we could do this with the following recipe: '("More than n recipients" (lambda (msg n) (> (+ (length (mu4e-message-field msg :to)) - (length (mu4e-message-field msg :cc))) n)) + (length (mu4e-message-field msg :cc))) n)) (lambda () (read-number "Match messages with more recipients than: "))) t) @end lisp @@ -2498,7 +2674,7 @@ loading @t{mu4e}): :prompt "gtag" :ask-target (lambda () (read-string "What tag do you want to add?")) :action (lambda (docid msg target) - (mu4e-action-retag-message msg (concat "+" target))))) + (mu4e-action-retag-message msg (concat "+" target))))) @end lisp As another example, suppose we would like to ``archive and mark read'' @@ -2512,10 +2688,10 @@ loading @t{mu4e}): :prompt "Archive" :show-target (lambda (target) "archive") :action (lambda (docid msg target) - ;; must come before proc-move since retag runs - ;; 'sed' on the file - (mu4e-action-retag-message msg "-\\Inbox") - (mu4e~proc-move docid nil "+S-u-N")))) + ;; must come before proc-move since retag runs + ;; 'sed' on the file + (mu4e-action-retag-message msg "-\\Inbox") + (mu4e~proc-move docid nil "+S-u-N")))) @end lisp Adding to @code{mu4e-marks} list allows to use the mark in bulk operations @@ -2616,9 +2792,10 @@ following options: things out the context by itself (through the match-function). This is a good policy if there are no match functions, or if the match functions don't cover all cases. -@item a symbol @code{ask-if-none}: if there's already a context, don't change it; otherwise, -ask the user. -@item a symbol @code{pick-first}: pick the first (default) context. This is a good choice if +@item a symbol @code{ask-if-none}: if there's already a context, don't change it; +otherwise, ask the user. +@item a symbol @code{pick-first}: pick the first (default) context. This is a +good choice if you want to specify context for special case, and fall back to the first one if none match. @item @code{nil}: don't change the context; this is useful if you don't change @@ -2666,48 +2843,48 @@ when starting; see the discussion in the previous section. (setq mu4e-contexts `( ,(make-mu4e-context - :name "Private" - :enter-func (lambda () (mu4e-message "Entering Private context")) + :name "Private" + :enter-func (lambda () (mu4e-message "Entering Private context")) :leave-func (lambda () (mu4e-message "Leaving Private context")) - ;; we match based on the contact-fields of the message - :match-func (lambda (msg) - (when msg - (mu4e-message-contact-field-matches msg - :to "aliced@@home.example.com"))) - :vars '( ( user-mail-address . "aliced@@home.example.com" ) - ( user-full-name . "Alice Derleth" ) - ( mu4e-compose-signature . - (concat - "Alice Derleth\n" - "Lauttasaari, Finland\n")))) + ;; we match based on the contact-fields of the message + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "aliced@@home.example.com"))) + :vars '( ( user-mail-address . "aliced@@home.example.com" ) + ( user-full-name . "Alice Derleth" ) + ( mu4e-compose-signature . + (concat + "Alice Derleth\n" + "Lauttasaari, Finland\n")))) ,(make-mu4e-context - :name "Work" - :enter-func (lambda () (mu4e-message "Switch to the Work context")) - ;; no leave-func - ;; we match based on the maildir of the message - ;; this matches maildir /Arkham and its sub-directories - :match-func (lambda (msg) - (when msg - (string-match-p "^/Arkham" (mu4e-message-field msg :maildir)))) - :vars '( ( user-mail-address . "aderleth@@miskatonic.example.com" ) - ( user-full-name . "Alice Derleth" ) - ( mu4e-compose-signature . - (concat - "Prof. Alice Derleth\n" - "Miskatonic University, Dept. of Occult Sciences\n")))) + :name "Work" + :enter-func (lambda () (mu4e-message "Switch to the Work context")) + ;; no leave-func + ;; we match based on the maildir of the message + ;; this matches maildir /Arkham and its sub-directories + :match-func (lambda (msg) + (when msg + (string-match-p "^/Arkham" (mu4e-message-field msg :maildir)))) + :vars '( ( user-mail-address . "aderleth@@miskatonic.example.com" ) + ( user-full-name . "Alice Derleth" ) + ( mu4e-compose-signature . + (concat + "Prof. Alice Derleth\n" + "Miskatonic University, Dept. of Occult Sciences\n")))) ,(make-mu4e-context - :name "Cycling" - :enter-func (lambda () (mu4e-message "Switch to the Cycling context")) - ;; no leave-func - ;; we match based on the maildir of the message; assume all - ;; cycling-related messages go into the /cycling maildir - :match-func (lambda (msg) - (when msg - (string= (mu4e-message-field msg :maildir) "/cycling"))) - :vars '( ( user-mail-address . "aderleth@@example.com" ) - ( user-full-name . "AliceD" ) - ( mu4e-compose-signature . nil))))) + :name "Cycling" + :enter-func (lambda () (mu4e-message "Switch to the Cycling context")) + ;; no leave-func + ;; we match based on the maildir of the message; assume all + ;; cycling-related messages go into the /cycling maildir + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/cycling"))) + :vars '( ( user-mail-address . "aderleth@@example.com" ) + ( user-full-name . "AliceD" ) + ( mu4e-compose-signature . nil))))) ;; set `mu4e-context-policy` and `mu4e-compose-policy` to tweak when mu4e should ;; guess or ask the correct context, e.g. @@ -2797,19 +2974,19 @@ message. An example should clarify this: (cond ;; messages to the mu mailing list go to the /mu folder ((mu4e-message-contact-field-matches msg :to - "mu-discuss@@googlegroups.com") - "/mu") + "mu-discuss@@googlegroups.com") + "/mu") ;; messages sent directly to some spefic address me go to /private ((mu4e-message-contact-field-matches msg :to "me@@example.com") - "/private") + "/private") ;; messages with football or soccer in the subject go to /football ((string-match "football\\|soccer" - (mu4e-message-field msg :subject)) - "/football") + (mu4e-message-field msg :subject)) + "/football") ;; messages sent by me go to the sent folder ((mu4e-message-sent-by-me msg - (mu4e-personal-addresses)) - mu4e-sent-folder) + (mu4e-personal-addresses)) + mu4e-sent-folder) ;; everything else goes to /archive ;; important to have a catch-all at the end! (t "/archive")))) @@ -3030,18 +3207,20 @@ There are a number of places where @t{mu4e} lets you plug in your own functions: @itemize @item Custom functions for message headers in the message-view and -headers-view --- see @ref{HV Custom headers}, @ref{MSGV Custom headers} +headers-view --- see @ref{HV Custom headers}, @ref{OMSGV Custom headers} @item Using message-specific folders for drafts, trash, sent messages and refiling, based on a function --- see @ref{Dynamic folders} @item Using an attachment-specific download-directory --- see the variable @code{mu4e-attachment-dir}. @item Apply a function to a message in the headers view - see @ref{Headers view actions} -@item Apply a function to a message in the message view --- see @ref{Message view actions} +@item Apply a function to a message in the message view --- +see @ref{Message view actions} @item Add a new kind of mark for use in the headers view - see @ref{Adding a new kind of mark} @item Apply a function to an attachment --- see @ref{Attachment actions} -@item Custom function to mark certain messages --- see @ref{Custom mark functions} +@item Custom function to mark certain messages --- +see @ref{Custom mark functions} @item Using various @emph{mode}-hooks, @code{mu4e-compose-pre-hook} (see @ref{Compose hooks}), @code{mu4e-index-updated-hook} (see @ref{FAQ}) @end itemize @@ -3126,7 +3305,7 @@ point. Requires the 'formail' tool from procmail." (replace-regexp-in-string "\n$" "" (shell-command-to-string (concat "formail -x " hdr " -c < " - (shell-quote-argument (mu4e-message-field-at-point :path)))))) + (shell-quote-argument (mu4e-message-field-at-point :path)))))) @end lisp @subsection Rewriting the message body @@ -3579,10 +3758,10 @@ well; so put in your configuration: (let (buffers) (save-current-buffer (dolist (buffer (buffer-list t)) - (set-buffer buffer) - (when (and (derived-mode-p 'message-mode) - (null message-sent-message-via)) - (push (buffer-name buffer) buffers)))) + (set-buffer buffer) + (when (and (derived-mode-p 'message-mode) + (null message-sent-message-via)) + (push (buffer-name buffer) buffers)))) (nreverse buffers))) (setq gnus-dired-mail-mode 'mu4e-user-agent) @@ -4396,7 +4575,7 @@ understand the latter as it is the case for Google or Github), use uncheck the box @t{format=flowed} in the @t{Text} menu when composing a message. -@subsection How can force images to be shown at the end of my messages, regardless of where I insert them? +@subsection How can I force images to be shown at the end of my messages, regardless of where I insert them? User Marcin Borkowski has a solution: @lisp (defun mml-attach-file--go-to-eob (orig-fun &rest args)