From: short@asf.com (Lee Short)
Subject: rmail utilities
Organization: ASF
Date: Fri, 20 Nov 1992 22:52:36 GMT


Here are some utilities for rmail.  In addition to the utilities
themselves is a short file called init.el which shows a sample piece
of code a typical user might put in his/her .emacs to utilize the
functions.  

The first of utility is a redefinition of rmail-reply designed to
allow you to automatically copy yourself on all replies to rmail
messages.  It is in a file called rmail-reply-cc.el.  What it does is
allow the user to set a variable which will automatically CC him on
all replies to rmail messages.

The other two utilities have to do with mailing lists, and are placed
together in a file called maillist.el.  The first of these is a
utility that is designed to allow you to easily separate out the
messages from a mailing list into an rmail file of their own.  When
called, it files the current mailing list message to a separate rmail
file, and deletes the message from the current rmail file.  

The other utility is designed to alleviate the problem of users
accidentally replying to a mailing list when they intended to send
email to the author of the article.  How it does this is by making any
reply to a mailing list message go to the author of the message, not
the mailing list.  An alternative function submits a followup message
to the list.


--------------------------------CUT HERE-----------------------------
;;  rmail-reply-cc.el
;;  automatically CC's the author of replies to GNU Emacs rmail messages.
;;
;;  written by Lee Short (short@asf.com)
;;  Copyright (C) 1992 Lee Short.
;;  last mod: 20 November, 1992

;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation.  

;; This software is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; For a copy of the GNU General Public License write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.


(defvar  my-mail-address "foo@bar.com" 
"The users email address as it will be automaticlly inserted on CC: 
lines.")

(defvar  auto-cc nil 
"The value of this variable determines if the user will be automatically 
CCed on mail messages.  If maillist.el is also used, then this
variable is overridden by the three auto-cc-on-* variables found in 
that file." )

(defun rmail-reply (just-sender)
  "Reply to the current message.
Normally include CC: to all other recipients of original message;
prefix argument means ignore them.
While composing the reply, use \\[mail-yank-original] to yank the
original message into it."
  (interactive "P")
  ;;>> this gets set even if we abort. Can't do anything about it, though.
  (rmail-set-attribute "answered" t)
  (rmail-display-labels)
  (let (from reply-to cc subject date to message-id resent-reply-to)
    (save-excursion
      (save-restriction
	(widen)
	(goto-char (rmail-msgbeg rmail-current-message))
	(forward-line 1)
	(if (= (following-char) ?0)
	    (narrow-to-region
	     (progn (forward-line 2)
		    (point))
	     (progn (search-forward "\n\n" (rmail-msgend rmail-current-message)
				    'move)
		    (point)))
	  (narrow-to-region (point)
			    (progn (search-forward "\n*** EOOH ***\n")
				   (beginning-of-line) (point))))
	(setq resent-reply-to (mail-fetch-field "resent-reply-to" t)
	      from (mail-fetch-field "from")
	      reply-to (or resent-reply-to
			   (mail-fetch-field "reply-to" nil t)
			   from)
	      cc (cond (just-sender nil)
		       (resent-reply-to (mail-fetch-field "resent-cc" t))
		       (t (mail-fetch-field "cc" nil t)))
	      subject (or (and resent-reply-to
			       (mail-fetch-field "resent-subject" t))
			  (mail-fetch-field "subject"))
	      date (cond (resent-reply-to
			  (mail-fetch-field "resent-date" t))
			 ((mail-fetch-field "date")))
	      to (cond (resent-reply-to
			(mail-fetch-field "resent-to" t))
		       ((mail-fetch-field "to" nil t))
		       ;((mail-fetch-field "apparently-to")) ack gag barf
		       (t ""))
	      message-id (cond (resent-reply-to
				(mail-fetch-field "resent-message-id" t))
			       ((mail-fetch-field "message-id"))))))
    (and subject
	 (string-match "\\`Re: " subject)
	 (setq subject (substring subject 4)))
    (mail-other-window nil
      (mail-strip-quoted-names reply-to)
      subject
      (rmail-make-in-reply-to-field from date message-id)
      (let  ((cc-string
	      (if just-sender
		  nil
  	          (let* ((cc-list (rmail-dont-reply-to
		  	            (mail-strip-quoted-names
			              (if (null cc) to (concat to ", " cc))))))
		     (if (string= cc-list "") nil cc-list)))))
         (if  (null cc-string)
              (if auto-cc my-mail-address nil)
              (if auto-cc
                  (concat cc-string ", " my-mail-address)
                  cc-string)))
      (current-buffer))))

--------------------------------CUT HERE-----------------------------
;;  maillist.el
;;  mailing list utilities for GNU Emacs.
;;
;;  written by Lee Short (short@asf.com)
;;  Copyright (C) 1992 Lee Short.
;;  last mod: 20 November, 1992

;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation.  

;; This software is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; For a copy of the GNU General Public License write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.


(defvar  auto-cc-on-maillist-reply nil
"This variable determines if the user will be automatically CCed on replies
to the author of a mailing list message.  This will not work properly unless 
you also have rmail-reply-cc.el" )

(defvar  auto-cc-on-maillist-followup nil
"This variable determines if the user will be automatically CCed on followups
to a mailing list message.  This will not work properly unless 
you also have rmail-reply-cc.el" )

(defvar  auto-cc-on-nonlist-reply nil
"This variable determines if the user will be automatically CCed on replies
to a mail message.  This will not work properly unless 
you also have rmail-reply-cc.el" )

; the following defvar should be uncommented if rmail-reply-cc.el is not used
;
; (defvar  my-mail-address "foo@bar.com" 
; "The user's email address as it will be automaticlly inserted on CC: 
; lines.")

; the following defvar should be uncommented if rmail-reply-cc.el is not used
;
; (defvar  auto-cc nil 
; "The value of this variable determines if the user will be automatically 
; CC'd on mail messages.  )


(defconst maillists 
       '( ( "Reply-to: DRS@utxvm.cc.utexas.edu" "~/drs.rmail" ) 
          ( "Reply-To: Dead Runners Mind <DRM@DARTCMS1.BITNET>" "~/drs.rmail" )
        )
 "A list which describes the user's mailing lists in a format usable by 
maillist.el.  Each entry in the list is itself a list.  The first entry in 
each sublist is an identifying string in the text of messages from the 
mailing list, the second is the name of the rmail file in which to save 
messages from the mailing list.  Any message in which the identifying 
string is found is assumed to be a message from the mailing list.  Thus, 
a forwarded message from the mailing list is likely to be flagged as 
coming from the list."
)


(defun file-to-maillist ()
"Saves the current rmail message to the rmail file for its mailing list, as 
specified in the constant maillists."
;;  searches the message for a match with any of the identifying strings 
;;  given in maillists.  As soon as it finds a match, it outputs the message
;;  to the mailing list's rmail file and deletes it from the current rmail
;;  file
   (interactive)
   (rmail-output-to-rmail-file 
      (let  ( (current-list maillists) 
              (rmail-filename nil)  )
          (while  (and (car current-list) (not rmail-filename) )
              (if (my-string-find (car (car current-list) ) )
                  (setq rmail-filename (car (cdr ( car current-list) ) ) )  )
              (setq current-list (cdr current-list) )
          )
          rmail-filename
      )
   )
   (rmail-delete-forward)
)


(defun reply-to-maillist-message ()
"Initiates a reply to the author of a mailing list article."
   (let  ( (from nil) )
      (interactive)
      (delete-other-windows)
      (setq auto-cc auto-cc-on-maillist-reply)
      (rmail-reply t)		;; you are now in the mail buffer

      (beginning-of-buffer)
      (word-search-forward "To: " nil t)
      (kill-line)               ;; waste the old "to" field
      (insert ": ")

      (other-window 1)          ;; you are now in the rmail buffer
      (setq from (mail-fetch-field "from") )      ;; find the author's name

      (other-window 1)		;; you are now in the mail buffer
      (insert from)          ;; insert the name of the author

      (end-of-buffer)
      (newline)
   )
)


(defun my-rmail-followup  ()
"Initiates a followup to the mailing list in reply to a mailing list article."
   (interactive)
   (delete-other-windows)
   (setq auto-cc auto-cc-on-maillist-followup)
   (rmail-reply t)
)

(defun my-string-find  (string-arg)
"Searches for a string in the current buffer.  Returns t if it is found, 
nil otherwise."
   (set-mark-command nil)          ;;  store point
   (beginning-of-buffer)
   (if  (word-search-forward string-arg nil t)
       (progn
          (set-mark-command t)          ;;  restore point
          t
       )
       (progn
          (set-mark-command t)          ;;  restore point
          nil
       )
   )
)

(defun maillist-p ()
"Determines if the current rmail message is in one of the mailing lists as 
defined by the constant maillists."
   (let  ( (current-list maillists) 
           (found nil)  )
       (while  (and (car current-list) (not found) )
           (if (my-string-find (car (car current-list) ) )
               (setq found t)  )
           (setq current-list (cdr current-list) )
       )
       found
   )
)

(defun my-rmail-reply  ()
"Sends a reply to the author of an rmail message, if the message is either a 
regular message, or a message from one of the mailing lists defined by the 
variable maillists.  Any other mailing list message will likely result in 
a reply to the mailing list, rather than the author."  
    (interactive)
    (if (maillist-p)
        (reply-to-maillist-message)
        (progn
           (setq auto-cc auto-cc-on-nonlist-reply)
           (rmail-reply nil)
        )
    )
)

--------------------------------CUT HERE-----------------------------
;;  init.el
;;  sample of code for a .emacs

(load "rmail-reply-cc.el")
(load "maillist.el")

(setq  auto-cc-on-maillist-reply t)
(setq  auto-cc-on-maillist-followup t)
(setq  auto-cc-on-nonlist-reply t)

(define-key rmail-mode-map "b" 'file-to-maillist)
(define-key rmail-mode-map "r" 'my-rmail-reply)
(define-key rmail-mode-map "F" 'my-rmail-followup)
--------------------------------CUT HERE-----------------------------

hope this is useful,
Lee
-- 
short@asf.com              The mystery of government is not how Washington
Lee Short                  works, but how to make it stop.  -- P.J. O'Rourke
Software Janitor        I speak for none of the many steps in the food chain
Hughes Training, Inc.         between myself and General Motors corporation.