[comp.emacs] Making sendmail prompt the user before sending

andyo@masscomp.ccur.com (Andy Oram) (09/19/90)

I recently started using mail within GNU Emacs, and was embarrassed a couple
times because I pressed Control-C twice while the message was half-written --
and woosh, out it went to my recipients.  So I've changed a couple functions
in sendmail.el to prompt me before sending, just like you get prompted before
quitting Emacs.

The changes are pretty trivial.  I'm including two versions here: one if you
want to actually change sendmail.el at your site, and one for an individual
user who wants to override the behavior in the distribution files.

By the way, RMS suggests that you could get the same effect by making C-c C-c
a prefix key and defining mail-send-and-exit on C-c C-c y.

Here's my stuff if you want to change sendmail.el:

 1.  Replace mail-send-and-exit and mail-send with the following definitions.
     mail-send-and-exit will then check for a return value from mail-send
     before doing it's cleanup.  mail-send will prompt the user before
     sending, if the user has set mail-prompt-before-sending.  (The
     mail-prompt-before-sending flag is there for people who are sticklers 
     about backward compatibility.)

 2.  Have users who want the feature add:
	(setq mail-prompt-before-sending t)
     to their .emacs files.

------------------------------------------------------------

(defvar mail-prompt-before-sending nil
  "Non-nil means prompt for confirmation before sending mail.
Set this variable if you want to get an extra chance, in case you pressed the
keys that send mail by mistake.")

(defun mail-send-and-exit (arg)
  "Send message like mail-send, then, if no errors, exit 
from mail buffer.  Prefix arg means don't delete this window."
  (interactive "P")
  (if (mail-send)
      (progn
	(bury-buffer (current-buffer))
	(if (and (not arg)
		 (not (one-window-p))
		 (save-excursion
		   (set-buffer (window-buffer (next-window (selected-window) 'not)))
		   (eq major-mode 'rmail-mode)))
	    (delete-window)
	  (switch-to-buffer (other-buffer (current-buffer)))))))

(defun mail-send ()
  "Send the message in the current buffer.
If mail-prompt-before-sending is non-nil, prompt
the user to make sure the mail should be sent.
Depending on user's reply, return t or nil so that
mail-send-and-exit knows whether or not to exit.
If  mail-interactive  is non-nil, wait for success indication
or error messages, and inform user.
Otherwise any failure is reported in a message back to
the user from the mailer."
  (interactive)
  (if (or (not mail-prompt-before-sending)
	  (y-or-n-p "Do you want to send the message now? "))
      (progn
	(message "Sending...")
	(funcall send-mail-function)
	(set-buffer-modified-p nil)
	(delete-auto-save-file-if-necessary)
	(message "Sending...done")
	t)
    (message "")			;Erase "Yes or No" question.
    nil))

------------------------------------------------------------

If you don't want to or can't change the distribution files, each user can
override the standard functions by redefining them in mail-setup-hook.  Just
put the following into the .emacs file.  The mail-prompt-before-sending flag
is now redundant, but I left it in just so I could copy the functions intact.

------------------------------------------------------------

(setq mail-setup-hook
      '(lambda ()
;;; Redefine the mail sending functions to protect against accidental send
 	 (defun mail-send-and-exit (arg)
 	   "Send message like mail-send, then, if no errors, exit 
 from mail buffer.  Prefix arg means don't delete this window."
 	   (interactive "P")
 	   (if (mail-send)
 	       (progn
 		 (bury-buffer (current-buffer))
 		 (if (and (not arg)
 			  (not (one-window-p))
 			  (save-excursion
 			    (set-buffer (window-buffer
 					 (next-window (selected-window) 'not)))
 			    (eq major-mode 'rmail-mode)))
 		     (delete-window)
 		   (switch-to-buffer (other-buffer (current-buffer)))))))
 	 (defun mail-send ()
 	   "Send the message in the current buffer.
 Enhanced so that if mail-prompt-before-sending is non-nil, prompt
 the user to make sure the mail should be sent.
 If  mail-interactive  is non-nil, wait for success indication
 or error messages, and inform user.
 Otherwise any failure is reported in a message back to
 the user from the mailer."
 	   (interactive)
 	   (if (or (not mail-prompt-before-sending)
 		   (y-or-n-p "Do you want to send the message now? "))
 	       (progn
 		 (message "Sending...")
 		 (funcall send-mail-function)
 		 (set-buffer-modified-p nil)
 		 (delete-auto-save-file-if-necessary)
 		 (message "Sending...done")
 		 t)
 	     (message "")			;Erase "Yes or No" question.
 	     nil))
 	 ))

(setq mail-prompt-before-sending t)

------------------------------------------------------------

andyo@glasperl..westford.ccur.com (Andy Oram) (09/20/90)

Throw out all the changes I posted to sendmail.  If I had just dug a little
deeper in the lisp functions, I would have found the solution below.  Thanks
to Frank P. Bresz for sending it to me.  Sorry for wasting net bandwidth on
my previous posting.

> 	(setq send-mail-function (function (lambda ()
> 				(interactive)
> 				(if (y-or-n-p "Really send? ")
> 				    (sendmail-send-it)
>       				  (error "Send Aborted")))))
> 
> | ()  ()  () | Frank P. Bresz   | Westinghouse Electric Corporation
> |  \  /\  /  | fpb@ittc.wec.com | ITTC Simulators Department
> |   \/  \/   | uunet!ittc!fpb   | Those who can, do. Those who can't, simulate.
> | ---------- | (412)733-6749    | My opinions are mine, WEC don't want 'em.


-------------------------------------------------------------------------------

Andrew Oram                            Concurrent Computer Corporation
(I don't represent Concurrent; this message represents my own opinion)

Digital Communications Route: andyo@westford.ccur.com.{harvard,uunet,petsd}
                              {harvard,uunet,petsd}!masscomp!andyo
Analog Communications Route:  (508) 392-2865

Automatic UN*X documentation utility:

          cref | compress | crypt | man

-------------------------------------------------------------------------------
--

-------------------------------------------------------------------------------

Andrew Oram                            Concurrent Computer Corporation