mlittman@WIND.BELLCORE.COM (Michael S. Littman) (02/18/89)
Hi,
Someone suggested a fews days ago (in one of these Emacs
lists...) that mail mode allow the possibility of multiple outgoing
mail messages. I implemented something which does the same thing by
using widening-narrowing in the *mail* buffer. It changes the
existing package only minimally and actually comes in handy quite
often.
-Michael
------------------
;;;
;;; mail-plus.el: Allows multiple active outgoing mail messages.
;;;
; Use, copy, and alter this program at will but don't blame me if it
; doesn't work or erase this notice.
(require 'sendmail) ; This allows this file to augment sendmail.el.
; The main idea is that narrowing in on a single mail message allows
; multiple messages in *mail*. Extra bindings are used to move
; around in the narrowed buffer. Should work as usual for people
; who don't use it. (Michael S. Littman 11/88)
; C-c C-a (mail+append)
; C-c C-d (mail+delete)
; C-c C-p (mail+previous)
; C-c C-n (mail+next)
; C-c < (mail+first)
; C-c > (mail+last)
; C-c C-c (mail+send-and-exit)
(defvar mail+marker "--new message follows this line--"
"Separates mail messages within the *mail* buffer.")
(defun mail+narrow ()
"Narrows the current buffer on a single mail message."
(interactive)
(let (top bottom)
(widen) ; Just in case.
(save-excursion
(if (search-backward mail+marker (point-min) 1)
(setq top (+ 1 (length mail+marker) (point)))
(setq top (point))))
(save-excursion
(if (search-forward mail+marker (point-max) 1)
(setq bottom (+ (- (length mail+marker)) (point)))
(setq bottom (point))))
(narrow-to-region top bottom)))
(defun mail+next ()
"Moves to the next message."
(interactive)
(widen)
(if (not (search-forward mail+marker (point-max) 1))
(message "No next message."))
(mail+narrow)
(goto-char (point-max)))
(defun mail+previous ()
"Moves to the previous message."
(interactive)
(widen)
(if (not (search-backward mail+marker (point-min) 1))
(message "No previous message."))
(mail+narrow)
(goto-char (point-max)))
(defun mail+append ()
"Add a new message to the end."
(interactive)
(widen)
(goto-char (point-max))
(insert-string mail+marker)
(insert-string "\n")
(mail+narrow)
(mail-setup nil nil nil nil nil))
(defun mail+first ()
"Moves to the first message."
(interactive)
(widen)
(goto-char (point-min))
(mail+narrow)
(goto-char (point-max)))
(defun mail+last ()
"Moves to the last message."
(interactive)
(widen)
(goto-char (point-max))
(mail+narrow)
(goto-char (point-max)))
(defun mail+delete (&optional no-message)
"Delete the current message."
(interactive)
(let (top bottom last first)
(widen)
(setq first nil)
(save-excursion
(if (search-backward mail+marker (point-min) 1)
(setq top (+ 1 (length mail+marker) (point)))
(progn
(setq top (point))
(setq first t))))
(setq last nil)
(save-excursion
(if (search-forward mail+marker (point-max) 1)
(setq bottom (+ 1 (point)))
(progn
(setq bottom (point))
(setq last t))))
(if (and last (not first))
(setq top (+ top (- (length mail+marker)) -1)))
(if (and first last)
(if (not no-message) (message "Last message."))
(delete-region top bottom))
(mail+narrow)))
(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. Like mail-send-and-exit
except does a mail+delete."
(interactive "P")
(mail-send)
(mail+delete t)
(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)))))
; Key bindings
(define-key mail-mode-map "\C-c\C-a" 'mail+append)
(define-key mail-mode-map "\C-c\C-d" 'mail+delete)
(define-key mail-mode-map "\C-c\C-p" 'mail+previous)
(define-key mail-mode-map "\C-c\C-n" 'mail+next)
(define-key mail-mode-map "\C-c<" 'mail+first)
(define-key mail-mode-map "\C-c>" 'mail+last)
(define-key mail-mode-map "\C-c\C-c" 'mail+send-and-exit)