* mu4e: improve `mu4e-compose-pre-hook', document it

This commit is contained in:
djcb 2012-08-29 18:00:23 +03:00
parent c17d3911bd
commit ed516d54d7
2 changed files with 115 additions and 71 deletions

View File

@ -76,9 +76,12 @@ replying to messages."
(defvar mu4e-compose-pre-hook nil
"Hook run just *before* message composition starts. If the
compose-type is either /reply/ or /forward/, the variable
`mu4e-compose-parent-message' points to the message replied to / being forwarded.")
`mu4e-compose-parent-message' points to the message replied to /
being forwarded / edited.")
(defvar mu4e-compose-parent-message nil)
(defvar mu4e-compose-parent-message nil
"The parent message plist (ie., the message being replied to,
forwarded or edited) in `mu4e-compose-pre-hook.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -668,11 +671,11 @@ buffer."
(defun mu4e~compose-run-hooks (compose-type)
"Run the hooks defined for `mu4e-compose-pre-hook'. If
compose-type is either `reply' or `forward',
compose-type is `reply', `forward' or `edit',
`mu4e-compose-parent-message' points to the message being forwarded
or replied to, otherwise it is nil."
(setq mu4e-compose-parent-message
(when (member compose-type '(reply forward))
(when (member compose-type '(reply forward edit))
(mu4e-message-at-point)))
(run-hooks 'mu4e-compose-pre-hook))
@ -681,34 +684,30 @@ or replied to, otherwise it is nil."
a symbol, one of `reply', `forward', `edit', `new'. All but `new'
take the message at point as input. Symbol `edit' is only allowed
for draft messages."
(unless (member compose-type '(reply forward edit new))
(mu4e-error "Invalid compose type '%S'" compose-type))
(when (and (eq compose-type 'edit)
(not (member 'draft (mu4e-field-at-point :flags))))
(mu4e-error "Editing is only allowed for draft messages"))
;; run the hooks
(mu4e~compose-run-hooks compose-type)
;; 'new is special, since it takes no existing message as arg therefore,
;; we don't need to call thec backend, and call the handler *directly*
(if (eq compose-type 'new)
(mu4e~compose-handler 'new)
;; otherwise, we need the doc-id
(let ((docid (mu4e-field-at-point :docid)))
;; note, the first two chars of the line (the mark margin) does *not*
;; have the 'draft property; thus, we check one char before the end of
;; the current line instead
(unless (or (not (eq compose-type 'edit))
(member 'draft (mu4e-field-at-point :flags)))
(mu4e-error "Editing is only allowed for draft messages"))
(mu4e~compose-run-hooks compose-type)
;; if there's a visible view window, select that before starting
;; composing a new message, so that one will be replaced by the
;; compose window. The 10-or-so line headers buffer is not a good way
;; to write it...
;; if there's a visible view window, select that before starting composing
;; a new message, so that one will be replaced by the compose window. The
;; 10-or-so line headers buffer is not a good place to write it...
(let ((viewwin (get-buffer-window mu4e~view-buffer)))
(when (window-live-p viewwin)
(select-window viewwin)))
;; talk to the backend
(mu4e~proc-compose compose-type docid))))

View File

@ -1065,6 +1065,64 @@ the start of 2010.
filter out other 'junk' e-mail addresses; defaults to @t{noreply}.
@end itemize
@subsection Compose hooks
@anchor{Compose hooks}
If you want to execute some custom action before message composition starts,
you can define a @emph{hook function}. @t{mu4e} offers two hooks:
@itemize
@item @code{mu4e-compose-pre-hook}: this hook is run @emph{before} composition
starts; if you are composing a @emph{reply}, @emph{forward} a message, or
@emph{edit} an existing message, the variable
@code{mu4e-compose-parent-message} points to the message being replied to,
forwarded or edit, and you can use @code{mu4e-msg-field} to get the value of
various properties (and see @ref{The message s-expression}).
@item @code{mu4e-compose-mode-hook}: this hook is run just before composition
starts, when the whole buffer has already been set up. This is a good place
for editing-related settings. @code{mu4e-compose-parent-message} (see above)
is also at your disposal.
@end itemize
Let's look at some examples.
First, suppose we want to set the @t{From:}-address for a reply message based
on the receiver of the original:
@lisp
;; messages sent to me@@foo.com should be replied with me@@foo.com as From:
;; address; messages sent to me@@bar.com should be replied with me@@bar.com as From:
;; address; all other mail should use me@@cuux.com as From: address
(add-hook 'mu4e-compose-pre-hook
(defun my-set-from-address ()
"Set the From address based on the To address of the original."
(let ((orig-to (cdar (mu4e-msg-field mu4e-compose-parent-message :to))))
(setq user-mail-address
(cond
((string= "me@@foo.com" orig-to) "me@@foo.com")
((string= "me@@bar.com" orig-to) "me@@bar.com")
(t "me@@cuux.com"))))))
@end lisp
Second, as mentioned, @code{mu4e-compose-mode-hook} is especially useful for
editing-related settings. For example:
@lisp
(add-hook 'mu4e-compose-mode-hook
(defun my-do-compose-stuff ()
"My settings for message composition."
(set-fill-column 72)
(flyspell-mode)))
@end lisp
This hook is also useful for adding headers or changing headers, since the
message is fully formed when this hook runs. For example, to add a
@t{Bcc:}-header, you could add something like the following:
@lisp
(add-hook 'mu4e-compose-mode-hook
(defun my-add-bcc ()
"Add a Bcc: header."
(message-add-header "Bcc: me@@example.com\n")))
@end lisp
@subsection Queuing mail
@anchor{Queuing mail}
@ -2097,6 +2155,8 @@ Mail' folder by pressing @kbd{ma}.
In this chapter we list a number of actual and anticipated questions and their
answers.
@subsection General
@itemize
@item @emph{How can I quickly delete/move/trash a lot of messages?} You can
select ('mark' in emacs-speak) the messages like you would select text in a
@ -2106,34 +2166,6 @@ can also use functions like @code{mu4e-headers-mark-thread} (@key{T}),
@code{mu4e-headers-mark-subthread} (@key{t}) to mark whole threads at the same
time, and @code{mu4e-headers-mark-pattern} (@key{%}) to mark all messages
matching a certain regular expression.
@item @emph{How can I use @t{BBDB}?} Currently, there is no built-in for
address management with @t{BBDB}; instead, we recommend using @t{mu4e}'s
built-in @ref{Address autocompletion}.
@item @emph{How can I automatically set the @t{From:} address for a
reply-message, based on some field in the original?} Currently, you cannot do
that automatically. It is possible to do it non-automatically though, with
something like:
@lisp
(defun mu4e-change-from ()
"Change the from header."
(interactive)
(save-excursion
(when (message-goto-from)
(message-delete-line))
(goto-char (point-min))
(insert
(concat "From: "
(ido-completing-read "From: "
'("Mail1 <foo@@bar.com>"
"Mail2 <test@@example.com>"
"Mail3 <another@@cuux.org>"))
"\n"))))
@end lisp
@item @emph{And what about customizable folders for sent messages, based on
the @t{From:} header?} This is currently not possible either, but you can
periodically move messages from the main sent-folder to the specific
sent-folders. You can easily find those messages with a query like
@t{maildir:/sent from:myaddress@@example.com}.
@item @emph{mu4e seems to return a mere subset of all matches - how can I get
all?}. Indeed, for speed reasons (and because, if you are like the author, you
usually don't need thousands of matches), @t{mu4e} returns only up to the
@ -2141,24 +2173,6 @@ value of the variable @code{m4ue-search-result-limit} matches. To show
@emph{all} results, use @t{M-x mu4e-headers-toggle-full-search}, or customize
the variable @code{mu4e-headers-full-search}. This applies to all search
commands.
@item @emph{How can I automatically add some header to an outgoing message?}
You can use @code{mu4e-compose-mode-hook}. For example, to add a Bcc:-header,
you could add something like the following to your configuration:
@lisp
(add-hook 'mu4e-compose-mode-hook
(defun add-bcc ()
(message-add-header "Bcc: me@@example.com\n")))
@end lisp
@item @emph{How can I show attached images in my message view buffers?} See
@ref{Viewing images inline}.
@item @emph{How can I easily include attachments in the messages I write?}
You can drag-and-drop from your desktop; alternatively, you can use @t{dired}
-- see @ref{Attaching files with dired}.
@item @emph{@t{mu4e} seems to remove myself from the Cc: list; how can I
prevent that?}
Set @code{mu4e-compose-keep-self-cc} to @t{t} in your configuration.
@item @emph{When I try to run @t{mu index} while @t{mu4e} is running I get
errors like @t{mu: mu_store_new_writable: xapian error 'Unable to get write
lock on ~/.mu/xapian: already locked'}. What can I do about this?} You get
@ -2177,18 +2191,50 @@ seems to work quite well.
@item @emph{Can I automatically apply the marks on messages when
leaving the headers buffer?} Yes you can -- see the documentation on
@t{mu4e-headers-leave-behavior}.
@item @emph{How can I automatically apply word-wrapping (and hiding cited
parts) when viewing a message?} See the documentation on
@t{mu4e-view-wrap-lines} (and @t{mu4e-view-hide-cited}). You can always toggle
between the two states with @key{w} and @key{h}, respectively.
@item @emph{Is there context-sensitive help available?} Yes - pressing @key{H}
should take you to the right place in this manual.
@item @emph{How can I set @t{mu4e} as the default e-mail client in emacs?}
See @ref{Setting the default emacs mail program}.
@end itemize
@subsection Reading messages
@itemize
@item @emph{How can I show attached images in my message view buffers?} See
@ref{Viewing images inline}.
@item @emph{How can I automatically apply word-wrapping (and hiding cited
parts) when viewing a message?} See the documentation on
@t{mu4e-view-wrap-lines} (and @t{mu4e-view-hide-cited}). You can always toggle
between the two states with @key{w} and @key{h}, respectively.
@item @emph{How can I perform custom actions on messages and attachments?} See
@ref{Actions}.
@end itemize
@subsection Writing messages
@itemize
@item @emph{How can I use @t{BBDB}?} Currently, there is no built-in for
address management with @t{BBDB}; instead, we recommend using @t{mu4e}'s
built-in @ref{Address autocompletion}.
@item @emph{How can I automatically set the @t{From:} address for a
reply-message, based on some field in the original?} See @ref{Compose hooks}.
@item @emph{And what about customizable folders for sent messages, based on e.g.
the @t{From:} header?} Again, see @ref{Compose hooks}; alternatively, you can
periodically move messages from the main sent-folder to the specific
sent-folders. You can easily find those messages with a query like
@t{maildir:/sent from:myaddress@@example.com}.
@item @emph{How can I automatically add some header to an outgoing message?}
Once more, see @ref{Compose hooks}.
@item @emph{How can I easily include attachments in the messages I write?}
You can drag-and-drop from your desktop; alternatively, you can use @t{dired}
-- see @ref{Attaching files with dired}.
@item @emph{@t{mu4e} seems to remove myself from the Cc: list; how can I
prevent that?}
Set @code{mu4e-compose-keep-self-cc} to @t{t} in your configuration.
@end itemize
@node Known issues / missing features
@chapter Known issues / missing features
@ -2209,7 +2255,6 @@ it should work though, using the built-in mechanisms.
menu assumes the default key-bindings, as do the clicks-on-bookmarks.
@end itemize
@node How it works
@appendix How it works