Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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

  • Loading branch information...
commit ed516d54d74adea87d6742dcfe50e024eaab5755 1 parent c17d391
@djcb authored
Showing with 115 additions and 71 deletions.
  1. +19 −20 mu4e/mu4e-compose.el
  2. +96 −51 mu4e/mu4e.texi
View
39 mu4e/mu4e-compose.el
@@ -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
147 mu4e/mu4e.texi
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.