mu4e: implement mu4e-compose-post-hook
A hook for when we're done with message composition. We populate it with a function to kill created frames and one to attempt to restore window configuration.
This commit is contained in:
@ -72,6 +72,25 @@ the place to do that."
|
|||||||
:type 'hook
|
:type 'hook
|
||||||
:group 'mu4e-compose)
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
(defcustom mu4e-compose-post-hook
|
||||||
|
(list
|
||||||
|
;; kill compose frames
|
||||||
|
#'mu4e-compose-post-kill-frame
|
||||||
|
;; attempt to restore the old configuration.
|
||||||
|
#'mu4e-compose-post-restore-window-configuration)
|
||||||
|
"Hook run *after* message composition is over.
|
||||||
|
|
||||||
|
This is hook is run when composition buffer,
|
||||||
|
either by sending, postponing, exiting or killing it.
|
||||||
|
|
||||||
|
This multiplexes the `message-mode' hooks `message-send-actions',
|
||||||
|
`message-postpone-actions', `message-exit-actions' and
|
||||||
|
`message-kill-actions', and the hook is run with a variable
|
||||||
|
`mu4e-compose-post-trigger' set correspondingly to a symbol,
|
||||||
|
`send', `postpone', `exit' or `kill'."
|
||||||
|
:type 'hook
|
||||||
|
:group 'mu4e-compose)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(defvar mu4e-captured-message)
|
(defvar mu4e-captured-message)
|
||||||
|
|||||||
@ -606,22 +606,79 @@ COMPOSE-TYPE and PARENT are as in `mu4e--draft'."
|
|||||||
(set-buffer-modified-p nil)
|
(set-buffer-modified-p nil)
|
||||||
(undo-boundary))
|
(undo-boundary))
|
||||||
|
|
||||||
(defun mu4e--prepare-message-actions (oldframe)
|
;;
|
||||||
"Set up some message actions.
|
;; mu4e-compose-pos-hook helpers
|
||||||
In particular, handle closing frames when we created it. OLDFRAME
|
|
||||||
is the frame from which the message-composition was triggered."
|
(defvar mu4e--before-draft-window-config nil
|
||||||
(let* ((msgframe (selected-frame))
|
"The window configuration just before creating the draft.")
|
||||||
(maybe-kill-frame ;; kill frame when it was created for this
|
|
||||||
(lambda ()
|
(defun mu4e-compose-post-restore-window-configuration()
|
||||||
(when (and (frame-live-p msgframe) (not (eq oldframe msgframe)))
|
"Function that perhaps restores the window configuration.
|
||||||
(delete-frame msgframe)))))
|
I.e. the configuration just before the draft buffer appeared.
|
||||||
|
This is for use in `mu4e-compose-post-hook'.
|
||||||
|
See `set-window-configuration' for further details."
|
||||||
|
(when mu4e--before-draft-window-config
|
||||||
|
;;(message "RESTORE to %s" mu4e--before-draft-window-config)
|
||||||
|
(set-window-configuration mu4e--before-draft-window-config)
|
||||||
|
(setq mu4e--before-draft-window-config nil)))
|
||||||
|
|
||||||
|
(defvar mu4e--draft-activation-frame nil
|
||||||
|
"Frame from which composition was activated.
|
||||||
|
Used internally for mu4e-compose-post-kill-frame.")
|
||||||
|
|
||||||
|
(defun mu4e-compose-post-kill-frame ()
|
||||||
|
"Function that perhaps kills the composition frame.
|
||||||
|
This is for use in `mu4e-compose-post-hook'."
|
||||||
|
(let ((msgframe (selected-frame)))
|
||||||
|
;;(message "kill frame? %s %s" mu4e--draft-activation-frame msgframe)
|
||||||
|
(when (and (frame-live-p msgframe)
|
||||||
|
(not (eq mu4e--draft-activation-frame msgframe)))
|
||||||
|
(delete-frame msgframe))))
|
||||||
|
|
||||||
|
(defvar mu4e-message-post-action nil
|
||||||
|
"Runtime variable for use with `mu4e-compose-post-hook'.
|
||||||
|
It contains a symbol denoting the action that triggered the hook,
|
||||||
|
either `send', `exit', `kill' or `postpone'.")
|
||||||
|
|
||||||
|
(defvar mu4e-compose-post-hook)
|
||||||
|
(defun mu4e--message-post-actions (trigger)
|
||||||
|
"Invoked after we're done with a message.
|
||||||
|
|
||||||
|
I.e. this multiplexes the `message-(send|exit|kill|postpone)-actions';
|
||||||
|
with the mu4e-message-post-action set accordingly."
|
||||||
|
(setq mu4e-message-post-action trigger)
|
||||||
|
(run-hooks 'mu4e-compose-post-hook))
|
||||||
|
|
||||||
|
(defun mu4e--prepare-post (&optional oldframe oldwindconf)
|
||||||
|
"Prepare the `mu4e-compose-post-hook` handling.
|
||||||
|
|
||||||
|
Set up some message actions. In particular, handle closing frames
|
||||||
|
when we created it. OLDFRAME is the frame from which the
|
||||||
|
message-composition was triggered. OLDWINDCONF is the current
|
||||||
|
window configuration."
|
||||||
|
;; remember current frame & window conf
|
||||||
|
(setq mu4e--draft-activation-frame oldframe
|
||||||
|
mu4e--before-draft-window-config oldwindconf)
|
||||||
|
|
||||||
|
;; make message's "post" hooks local, and multiplex them
|
||||||
(make-local-variable 'message-send-actions)
|
(make-local-variable 'message-send-actions)
|
||||||
|
(make-local-variable 'message-postpone-actions)
|
||||||
(make-local-variable 'message-exit-actions)
|
(make-local-variable 'message-exit-actions)
|
||||||
(make-local-variable 'message-kill-actions)
|
(make-local-variable 'message-kill-actions)
|
||||||
(make-local-variable 'message-postpone-actions)
|
|
||||||
|
|
||||||
(add-to-list 'message-kill-actions maybe-kill-frame)
|
(push (lambda () (mu4e--message-post-actions 'send))
|
||||||
(add-to-list 'message-postpone-actions maybe-kill-frame)))
|
message-send-actions)
|
||||||
|
(push (lambda () (mu4e--message-post-actions 'postpone))
|
||||||
|
message-postpone-actions)
|
||||||
|
(push (lambda () (mu4e--message-post-actions 'exit))
|
||||||
|
message-exit-actions)
|
||||||
|
(push (lambda () (mu4e--message-post-actions 'kill))
|
||||||
|
message-kill-actions))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; creating drafts
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e--draft (compose-type compose-func &optional parent)
|
(defun mu4e--draft (compose-type compose-func &optional parent)
|
||||||
"Create a new message draft.
|
"Create a new message draft.
|
||||||
@ -645,9 +702,11 @@ Returns the new buffer."
|
|||||||
;; a temp buffer with contains the parent-message, if any. if there's a
|
;; a temp buffer with contains the parent-message, if any. if there's a
|
||||||
;; PARENT, load the corresponding message into a temp-buffer before calling
|
;; PARENT, load the corresponding message into a temp-buffer before calling
|
||||||
;; compose-func
|
;; compose-func
|
||||||
(let ((draft-buffer) (oldframe (selected-frame)))
|
(let ((draft-buffer)
|
||||||
|
(oldframe (selected-frame))
|
||||||
|
(oldwinconf (current-window-configuration)))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
;; provide a temp buffer so the compose-func can do its thing. without
|
;; provide a temp buffer so the compose-func can do its thing. withou
|
||||||
;; interference.
|
;; interference.
|
||||||
(setq draft-buffer (mu4e--validate-hidden-buffer (funcall compose-func)))
|
(setq draft-buffer (mu4e--validate-hidden-buffer (funcall compose-func)))
|
||||||
(with-current-buffer draft-buffer
|
(with-current-buffer draft-buffer
|
||||||
@ -660,7 +719,7 @@ Returns the new buffer."
|
|||||||
(pop-to-buffer draft-buffer)
|
(pop-to-buffer draft-buffer)
|
||||||
(mu4e-display-buffer draft-buffer 'do-select))
|
(mu4e-display-buffer draft-buffer 'do-select))
|
||||||
;; prepare possible message actions (such as cleaning-up)
|
;; prepare possible message actions (such as cleaning-up)
|
||||||
(mu4e--prepare-message-actions oldframe)
|
(mu4e--prepare-post oldframe oldwinconf)
|
||||||
draft-buffer))
|
draft-buffer))
|
||||||
|
|
||||||
(defun mu4e--draft-with-parent (compose-type parent compose-func)
|
(defun mu4e--draft-with-parent (compose-type parent compose-func)
|
||||||
|
|||||||
@ -1798,11 +1798,15 @@ value of various properties (and see @ref{Message functions}).
|
|||||||
starts, when the whole buffer has already been set up. This is a good place
|
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)
|
for editing-related settings. @code{mu4e-compose-parent-message} (see above)
|
||||||
is also at your disposal.
|
is also at your disposal.
|
||||||
|
@item @code{mu4e-compose-post-hook}: this hook is run when we're done with
|
||||||
|
message compositions. See the docstring for details.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Let's look at an examples. As mentioned, @code{mu4e-compose-mode-hook} is especially
|
As mentioned, @code{mu4e-compose-mode-hook} is especially useful for
|
||||||
useful for editing-related settings. For example:
|
editing-related settings:
|
||||||
|
|
||||||
|
Let's look at an example:
|
||||||
@lisp
|
@lisp
|
||||||
(add-hook 'mu4e-compose-mode-hook
|
(add-hook 'mu4e-compose-mode-hook
|
||||||
(defun my-do-compose-stuff ()
|
(defun my-do-compose-stuff ()
|
||||||
@ -1811,7 +1815,7 @@ useful for editing-related settings. For example:
|
|||||||
(flyspell-mode)))
|
(flyspell-mode)))
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
This hook is also useful for adding headers or changing headers, since the
|
The 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
|
message is fully formed when this hook runs. For example, to add a
|
||||||
@t{Bcc:}-header, you could add something like the following, using
|
@t{Bcc:}-header, you could add something like the following, using
|
||||||
@code{message-add-header} from @code{message-mode}.
|
@code{message-add-header} from @code{message-mode}.
|
||||||
|
|||||||
Reference in New Issue
Block a user