home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- subject: v08i112: pcmail part 04 of 08
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Reply-To: markl@oracle.com (Croaker the Physician)
-
- Posting-number: Volume 8, Issue 112
- Submitted-by: markl@oracle.com (Croaker the Physician)
- Archive-name: pcmail/part04
-
- #--------------------------------CUT HERE-------------------------------------
- #! /bin/sh
- #
- # This is a shell archive. Save this into a file, edit it
- # and delete all lines above this comment. Then give this
- # file to sh by executing the command "sh file". The files
- # will be extracted into the current directory owned by
- # you with default permissions.
- #
- # The files contained herein are:
- #
- # -rw-rw-r-- 1 markl 24644 Nov 1 13:33 pcmailattr.el
- # -rw-rw-r-- 1 markl 10900 Oct 31 11:50 pcmailmove.el
- #
- echo 'x - pcmailattr.el'
- if test -f pcmailattr.el; then echo 'shar: not overwriting pcmailattr.el'; else
- sed 's/^X//' << '________This_Is_The_END________' > pcmailattr.el
- X;;;; GNU-EMACS PCMAIL mail reader
- X
- X;; Written by Mark L. Lambert
- X;; Architecture Group, Network Products Division
- X;; Oracle Corporation
- X;; 20 Davis Dr,
- X;; Belmont CA, 94002
- X;;
- X;; internet: markl@oracle.com or markl%oracle.com@apple.com
- X;; UUCP: {hplabs,uunet,apple}!oracle!markl
- X
- X;; Copyright (C) 1989 Mark L. Lambert
- X
- X;; This file is not officially part of GNU Emacs, but is being
- X;; donated to the Free Software Foundation. As such, it is
- X;; subject to the standard GNU-Emacs General Public License,
- X;; referred to below.
- X
- X;; GNU Emacs is distributed in the hope that it will be useful,
- X;; but WITHOUT ANY WARRANTY. No author or distributor
- X;; accepts responsibility to anyone for the consequences of using it
- X;; or for whether it serves any particular purpose or works at all,
- X;; unless he says so in writing. Refer to the GNU Emacs General Public
- X;; License for full details.
- X
- X;; Everyone is granted permission to copy, modify and redistribute
- X;; GNU Emacs, but only under the conditions described in the
- X;; GNU Emacs General Public License. A copy of this license is
- X;; supposed to have been given to you along with GNU Emacs so you
- X;; can know your rights and responsibilities. It should be in a
- X;; file named COPYING. Among other things, the copyright notice
- X;; and this notice must be preserved on all copies.
- X
- X;;;; global variables
- X
- X(defvar pcmail-attribute-obarray (make-vector 47 0)
- X "An attribute obarray used for completion in attribute-manipulation
- Xcommands.")
- X
- X;; note the inclusion of pcmail-defined attributes here. In order to
- X;; conform to Babyl, these attributes must also be present in the user-defined
- X;; labels section of a babyl mail file header. Normally this would
- X;; automatically load them into the obarray at folder-open time.
- X;; Unfortunately some older pcmail mail files won't have them, so we provide
- X;; them here for backward compatibility
- X
- X(mapcar '(lambda (a) (intern a pcmail-attribute-obarray))
- X (append pcmail-babyl-defined-attributes
- X '("printed" "copied" "edited" "timely" "expired"
- X "undigestified" "archived" "precious")))
- X
- X;;; sticky defaults
- X
- X(defvar pcmail-last-attr nil
- X "The name of the last attribute given to an attribute command.")
- X
- X(defvar pcmail-last-priority nil
- X "The last priority assigned a message.")
- X
- X;;;; priority setting commands
- X
- X(defun pcmail-change-message-priority (priority)
- X "Change the current message's priority.
- XArgs: (priority)
- X Change the current message's priority. A priority is represented by a
- Xnon-zero number, the lower the number the higher the priority; messages can
- Xbe sorted by priority using the \\[pcmail-sort-folder\\] command.
- XInput defaults to last priority given a message."
- X (interactive
- X (if current-prefix-arg
- X '(nil)
- X (let ((p (pcmail-read-string-default "Message priority: "
- X pcmail-last-priority t)))
- X (or (> (string-to-int p) 0)
- X (error "Priority must be a number greater than zero."))
- X (list (string-to-int (setq pcmail-last-priority p))))))
- X (pcmail-change-message-priority-1 priority pcmail-current-subset-message 1)
- X (pcmail-update-folder-mode-line pcmail-current-subset-message))
- X
- X(defun pcmail-change-priority-subset (priority)
- X "Change the current message subset's priority.
- XArgs: (priority)
- X Change the current subset's priority. A priority is represented by a
- Xnon-zero number, the lower the number the higher the priority; messages can
- Xbe sorted by priority using the \\[pcmail-sort-folder\\] command.
- XInput defaults to last priority given a message."
- X (interactive
- X (if current-prefix-arg
- X '(nil)
- X (let ((p (pcmail-read-string-default "Message priority: "
- X pcmail-last-priority t)))
- X (or (> (string-to-int p) 0)
- X (error "Priority must be a number greater than zero."))
- X (list (string-to-int (setq pcmail-last-priority p))))))
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-priority-1 priority 1 (pcmail-current-subset-length))
- X (pcmail-update-folder-mode-line pcmail-current-subset-message))
- X
- X(defun pcmail-change-message-priority-1 (p start len)
- X "Change message priorities to P starting with START for LEN subset messages.
- XArgs: (p start len)"
- X (pcmail-barf-if-empty-folder)
- X (let ((i start))
- X (unwind-protect
- X (while (< i (+ start len))
- X (pcmail-set-priority (pcmail-make-absolute i) p)
- X (and (zerop (% (- (setq i (1+ i)) start) pcmail-progress-interval))
- X (message "Setting priorities...%d" (- i start))))
- X (pcmail-update-folder-mode-line pcmail-current-subset-message))
- X (and (>= (- i start) pcmail-progress-interval)
- X (message "Setting priorities...done (%d message%s)"
- X (- i start) (pcmail-s-ending (- i start))))))
- X
- X;;;; attribute-changing operations: deletion, undeletion, general attribute
- X;;;; setting and clearing.
- X
- X(defun pcmail-change-message-attr (attr mode)
- X "Toggle a named attribute of the current message.
- XArgs: (attr mode)
- X Toggle a named attribute of the current message. Completion on input is
- Xpermitted; input defaults to last attribute given to an attribute command.
- XWith a prefix arg, don't toggle. If the arg is positive, set the attribute;
- Xif negative, clear the attribute."
- X (interactive (list (pcmail-read-attr
- X (concat
- X (cond ((null current-prefix-arg) "Toggle")
- X ((>= current-prefix-arg 0) "Set")
- X (t "Clear"))
- X " attribute: "))
- X current-prefix-arg))
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-attr-1 attr
- X (cond ((null mode) 'toggle)
- X ((>= mode 0) t))
- X pcmail-current-subset-message 1))
- X
- X(defun pcmail-change-attr-subset (attr mode)
- X "Toggle a named attribute in each message of the current message subset.
- XArgs: (attr mode)
- X Toggle a named attribute in each message of the current message subset.
- XCompletion on input is permitted; input defaults to last attribute given to
- Xan attribute command. With a prefix arg, don't toggle. If the arg is
- Xpositive, set the attribute; if negative, clear the attribute."
- X (interactive (list (pcmail-read-attr
- X (concat
- X (cond ((null current-prefix-arg) "Toggle")
- X ((>= current-prefix-arg 0) "Set")
- X (t "Clear"))
- X " message subset attribute: "))
- X current-prefix-arg))
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-attr-1 attr
- X (cond ((null mode) 'toggle)
- X ((>= mode 0) t))
- X 1 (pcmail-current-subset-length)))
- X
- X(defun pcmail-change-message-attr-1 (attr state start len)
- X "Munge message attributes in the current message subset.
- XArgs: (attr state start len)
- X Set attribute ATTR to STATE for all messages in the current subset from START
- Xfor LEN messages. If STATE is 'toggle, toggle the current attribute state."
- X (let ((i start))
- X (unwind-protect
- X (while (< i (+ start len))
- X (pcmail-set-attribute (pcmail-make-absolute i) attr state)
- X (and (zerop (% (- (setq i (1+ i)) start) pcmail-progress-interval))
- X (message "%sing %s attribute...%d"
- X (cond ((eq state 'toggle) "Toggl")
- X (state "Sett")
- X (t "Clear"))
- X attr (- i start))))
- X (pcmail-update-folder-mode-line pcmail-current-subset-message))
- X (and (>= (- i start) pcmail-progress-interval)
- X (message "%sing %s attribute...done (%d message%s)"
- X (cond ((eq state 'toggle) "Toggl")
- X (state "Sett")
- X (t "Clear"))
- X attr (- i start) (pcmail-s-ending (- i start))))))
- X
- X(defun pcmail-undelete-previous-message ()
- X "Looking backward from the current message, clear the first deleted
- Xmessage's delete attribute.
- XArgs: none"
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (let ((n (pcmail-next-subset-message-of-type
- X nil nil 'include-current 'pcmail-has-attribute-p "deleted")))
- X (cond (n
- X (pcmail-set-attribute (pcmail-make-absolute n) "deleted" nil)
- X (pcmail-goto-message n))
- X (t
- X (message "No previous deleted message in the current subset.")))))
- X
- X(defun pcmail-undelete-subset ()
- X "Undelete all messages in the current message subset.
- XArgs: none"
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-attr-1 "deleted" nil 1
- X (pcmail-current-subset-length)))
- X
- X(defun pcmail-delete-message (&optional dont-skip)
- X "Delete this message and move to the next interesting message.
- XArgs: (&optional dont-skip)
- XDelete this message and move to the next interesting message. Deleted
- Xmessages remain in the folder until the \\[pcmail-expunge-folder] command
- Xis given. With a prefix argument, delete and move to the next message in the
- Xcurrent subset whether or not it is interesting."
- X (interactive "P")
- X (pcmail-barf-if-empty-folder)
- X (let ((n pcmail-current-subset-message))
- X (pcmail-set-attribute (pcmail-make-absolute n) "deleted" t)
- X (pcmail-next-message dont-skip)
- X (and (= n pcmail-current-subset-message)
- X (pcmail-update-folder-mode-line n))))
- X
- X(defun pcmail-delete-message-backward (&optional dont-skip)
- X "Delete this message and move to the previous interesting message.
- XArgs: (&optional dont-skip)
- X Delete this message and move to the previous interesting message.
- XDeleted messages remain in the folder until the \\[pcmail-expunge-folder]
- Xcommand is given. With a prefix argument, delete and move to the previous
- Xmessage in the current subset whether or not it is interesting."
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (let ((n pcmail-current-subset-message))
- X (pcmail-set-attribute (pcmail-make-absolute n) "deleted" t)
- X (pcmail-previous-message dont-skip)
- X (and (= n pcmail-current-subset-message)
- X (pcmail-update-folder-mode-line n))))
- X
- X(defun pcmail-delete-subset ()
- X "Delete all messages in the current message subset.
- XArgs: none
- X Delete all messages in the current message subset. Deleted messages remain
- Xin the folder until the \\[pcmail-expunge-folder] command is given."
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-attr-1 "deleted" t 1 (pcmail-current-subset-length)))
- X
- X(defun pcmail-zap-to-message ()
- X "Delete all messages in the current subset from the current message forward.
- XArgs: none
- X Delete all messages in the current subset from the current message forward.
- XDeleted messages remain in the folder until the \\[pcmail-expunge-folder]
- Xcommand is given."
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (pcmail-change-message-attr-1 "deleted" t pcmail-current-subset-message
- X (1+ (- (pcmail-current-subset-length)
- X pcmail-current-subset-message))))
- X
- X(defun pcmail-kill-message-later (n date)
- X "Arrange for something to happen to a message some time in the future.
- XArgs: (n date)
- X If called interactively, read a date of the form dd-mmm-yy from the
- Xminibuffer. N is current message. If called as a function, supply an
- Xabsolute message number and a date string in the form dd-mmm-yy. Set
- Xmessage N's \"timely\" attribute. Insert an expires: field in the message
- Xheader. When the current date is greater than a message's expiration date,
- Xapply the hook pcmail-expiration-hook to the message. With a prefix argument
- X(called interactively) or a DATE value of NIL (called as a function), remove
- Xthe expired field and clear the message's \"timely\" attribute, effectively
- Xunexpiring the message."
- X (interactive
- X (list (pcmail-make-absolute pcmail-current-subset-message)
- X (if current-prefix-arg
- X nil
- X (let ((expiration))
- X (while
- X ; string-to-date triple validates date format
- X (not (pcmail-string-to-date-triple
- X (setq expiration
- X (pcmail-read-string-default
- X "Expiration date (dd-mmm-yy): " nil t))))
- X (message "Date not dd-mmm-yy.") (ding) (sit-for 2))
- X expiration))))
- X (pcmail-set-message-expiration n date)
- X (pcmail-set-attribute n "timely" (and date t))
- X (pcmail-update-folder-mode-line pcmail-current-subset-message))
- X
- X;;;; attribute-hacking utilities
- X
- X;;; two functions that work on messages with relative numbers. A relative
- X;;; message number is that message's index within the current subset. Its
- X;;; absolute number is its index within the entire folder.
- X
- X(defun pcmail-update-folder-mode-line (n)
- X "Display message information in the mode line.
- XArgs: (n)
- X Set pcmail-display-info to string describing message with relative number N.
- XThe string is formatted by the directives in pcmail-folder-mode-line-format.
- XSee description of that variable for details. The formatted string will be
- Xdisplayed in the mode line."
- X (setq pcmail-display-info
- X (pcmail-format-string
- X pcmail-folder-mode-line-format
- X (list (list "s" '(lambda (n) n) n)
- X (list "S" '(lambda () (pcmail-current-subset-length)))
- X (list "e" '(lambda ()
- X (if (eq major-mode 'pcmail-edit-mode)
- X "Editing "
- X "")))
- X (list "E" '(lambda (n)
- X (let ((abs (pcmail-make-absolute n)) (exp))
- X (if (and (pcmail-has-attribute-p abs "timely")
- X (setq exp
- X (pcmail-message-expiration abs)))
- X (concat "Expires: " exp)
- X "")))
- X n)
- X (list "n"
- X '(lambda (n)
- X (cond ((or (/= (pcmail-current-subset-length)
- X pcmail-total-messages)
- X (/= n (pcmail-make-absolute n)))
- X (format "[%d/%d]" (pcmail-make-absolute n)
- X pcmail-total-messages))
- X (t
- X ""))) n)
- X (list "f" '(lambda () pcmail-folder-name))
- X (list "a"
- X '(lambda (n)
- X (let ((attrs (aref pcmail-attr-vector
- X (pcmail-make-absolute n))))
- X (if attrs
- X (mapconcat 'identity attrs ", ")
- X "[no attributes]"))) n)
- X (list "l"
- X '(lambda (n)
- X (pcmail-message-line-count (pcmail-make-absolute n)))
- X n)
- X (list "c"
- X '(lambda (n)
- X (pcmail-message-char-count (pcmail-make-absolute n)))
- X n)
- X (list "p"
- X '(lambda (n)
- X (let ((p (pcmail-message-priority
- X (pcmail-make-absolute n))))
- X (if (= p 1) ""
- X (format "Priority: %d" p))))
- X n))))
- X (and (= n pcmail-current-subset-message)
- X (pcmail-force-mode-line-update)))
- X
- X(defun pcmail-next-subset-message-of-type (forward-p invert-p include-current-p
- X pred &rest args)
- X "Return the number of the next message that satisfies a predicate.
- XArgs: (forward-p invert-p include-current-p pred &rest args)
- X Starting with the current subset message if INCLUDE-CURRENT-P is non-nil,
- Xthe first message after/before current otherwise, return the number of the
- Xfirst subset message that satisfies PRED applied to ARGS, or if INVERT-P is
- Xnon-NIL, does not satisfy PRED applied to ARGS. Search forward
- Xif FORWARD-P is non-nil, backward else. If no such message is found,
- Xreturn NIL."
- X (let ((found) (current pcmail-current-subset-message))
- X (or include-current-p
- X (setq current (funcall (if forward-p '1+ '1-) current)))
- X (while (and (not found)
- X (funcall (if forward-p '<= '>=) current
- X (if forward-p (pcmail-current-subset-length) 1)))
- X (and (if invert-p
- X (not (apply pred (pcmail-make-absolute current) args))
- X (apply pred (pcmail-make-absolute current) args))
- X (setq found current))
- X (setq current (funcall (if forward-p '1+ '1-) current)))
- X found))
- X
- X;;; all following routines deal with absolute-numbered messages
- X
- X(defun pcmail-hack-timely-messages (tl)
- X "Given a list of timely messages, figure out what to do with them.
- XArgs: (tl)
- X TL is a list of message numbers, corresponding to messages with the
- X\"timely\" attribute set. If any of these messages has an expired: header
- Xfield earlier than the current date, apply pcmail-expiration-hook to
- Xthe message number."
- X (let ((now-days (pcmail-date-triple-to-ndays
- X (pcmail-string-to-date-triple))))
- X (mapcar
- X '(lambda (n)
- X (let ((expiration (pcmail-message-expiration n)))
- X (cond ((and expiration
- X pcmail-expiration-hook
- X (not (pcmail-has-attribute-p n "expired"))
- X (setq expiration
- X (pcmail-string-to-date-triple expiration))
- X (setq expiration
- X (pcmail-date-triple-to-ndays expiration))
- X (<= expiration now-days))
- X (funcall pcmail-expiration-hook n)
- X (pcmail-set-attribute n "expired" t)
- X (pcmail-set-attribute n "timely" nil)))))
- X tl)))
- X
- X(defun pcmail-set-message-expiration (n date)
- X "Set message absolute-numbered N's expiration to DATE.
- XArgs: (n date)
- X N is an absolute message number, DATE is a date string dd-mmm-yy.
- XRemove N's expires: field if it has one. If DATE is non-nil, place its
- Xentries in a new expires: field."
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header n)
- X (goto-char (point-min))
- X (let ((buffer-read-only nil)
- X (case-fold-search t))
- X (and (re-search-forward "^expires:.*\n\\([ \t]+.*\n\\)*" nil t)
- X (replace-match ""))
- X (and date (insert "Expires: " date "\n"))))))
- X
- X(defun pcmail-message-expiration (n)
- X "Return message absolute-numbered N's expiration date as a date string
- XArgs: (n)
- X If N has a a valid expired: field in the form \"dd mm yy\", return it,
- Xelse return NIL."
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header n)
- X (goto-char (point-min))
- X (mail-fetch-field "expires"))))
- X
- X(defun pcmail-interesting-p (n)
- X "Return non-NIL if message absolute-numbered N is interesting, NIL else.
- XArgs: (n)
- X Return non-NIL if message absolute-numbered N is interesting, NIL else.
- XMessage N is interesting if pcmail-interesting-hook returns non-NIL
- Xwhen applied to N. If pcmail-interesting-hook is NIL, all messages
- Xare interesting."
- X (if pcmail-interesting-hook
- X (funcall pcmail-interesting-hook n)
- X t))
- X
- X(defun pcmail-has-attribute-p (n attr)
- X "Check an attribute's membership in a message attribute list.
- XArgs: (n attr)
- X Return T if ATTR is a member of message absolute-numbered N's attribute
- Xlist, NIL else."
- X (pcmail-in-sequence-p attr (aref pcmail-attr-vector n)))
- X
- X(defun pcmail-set-attribute (n attr state)
- X "Set, clear, or toggle a message attribute.
- XArgs: (n attr state)
- X Set message absolute-numbered N's attribute ATTR to STATE. If STATE is
- X'toggle, toggle the attribute's state. If ATTR is \"deleted\", do not
- Xset state to non-NIL if N already has the \"precious\" attribute"
- X (pcmail-barf-if-empty-folder)
- X (or (pcmail-attribute-p attr)
- X (error "No attribute named %s." attr))
- X (let ((curstate (pcmail-babyl-attr-present-p n attr)))
- X (cond ((and curstate (or (eq state 'toggle) (not state)))
- X (pcmail-remove-from-message-attribute-list n attr)
- X (pcmail-remove-babyl-attr n attr))
- X ((and (not curstate) state
- X (if (and (pcmail-has-attribute-p n "precious")
- X (string= attr "deleted"))
- X nil
- X t))
- X (pcmail-add-to-message-attribute-list n attr)
- X (pcmail-add-babyl-attr n attr))))
- X
- X ; this may have screwed up the region around the current message. Fix it.
- X (pcmail-narrow-to-message
- X (pcmail-make-absolute pcmail-current-subset-message))
- X state)
- X
- X(defun pcmail-priority-less-than-p (a b)
- X "Args: (a b)
- XReturn T is message A's priority is higher (less than) B's, NIL else."
- X (< (pcmail-message-priority a) (pcmail-message-priority b)))
- X
- X(defun pcmail-message-priority (n)
- X "Return specified message's Priority: field contents as a number.
- XArgs: (n)
- X First search the pcmail-priority-vector cache for a priority number. If
- Xnone is found, get message N's Priority: field and turn it into a number.
- XIf no priority exists, return the highest priority, 1."
- X (or (aref pcmail-priority-vector n)
- X (aset pcmail-priority-vector n
- X (cond ((zerop n)
- X 1)
- X (t
- X (save-excursion
- X (save-restriction
- X (let ((case-fold-search t))
- X (pcmail-narrow-to-unpruned-header n)
- X (let ((p (mail-fetch-field "priority")))
- X (if p (string-to-int p) 1))))))))))
- X
- X(defun pcmail-set-priority (n p)
- X "Set message absolute-numbered N's priority to P. Kill priority if P is NIL.
- XArgs: (n p)"
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header n)
- X (goto-char (point-min))
- X (let ((buffer-read-only nil)
- X (case-fold-search t))
- X (and (re-search-forward "^priority:.*\n\\([ \t]+.*\n\\)*" nil t)
- X (replace-match ""))
- X (and p
- X (insert "Priority: " (int-to-string p) "\n"))
- X (aset pcmail-priority-vector n (or p 1))))))
- X
- X;; sort routines for sort by from or to fields. Shouldn't be here, but I
- X;; can't think of a better place to put them
- X
- X(defun pcmail-from-field-less-than-p (a b)
- X "Return t if message A's from field is lexicographically less than B's
- XArgs: (a b)"
- X (let ((afrom) (bfrom))
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header a)
- X (setq afrom (mail-strip-quoted-names
- X (or (mail-fetch-field "resent-from")
- X (mail-fetch-field "resent-sender")
- X (mail-fetch-field "from")
- X (mail-fetch-field "sender")
- X "")))))
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header b)
- X (setq bfrom (mail-strip-quoted-names
- X (or (mail-fetch-field "resent-from")
- X (mail-fetch-field "resent-sender")
- X (mail-fetch-field "from")
- X (mail-fetch-field "sender")
- X "")))))
- X (string< afrom bfrom)))
- X
- X(defun pcmail-to-field-less-than-p (a b)
- X "Return t if message A's to field is lexicographically less than B's
- XArgs: (a b)"
- X (let ((ato) (bto))
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header a)
- X (setq ato (mail-strip-quoted-names
- X (or (mail-fetch-field "resent-to")
- X (mail-fetch-field "resent-apparently-to")
- X (mail-fetch-field "to")
- X (mail-fetch-field "apparently-to") ;uck
- X "")))))
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-unpruned-header b)
- X (setq bto (mail-strip-quoted-names
- X (or (mail-fetch-field "resent-to")
- X (mail-fetch-field "resent-apparently-to")
- X (mail-fetch-field "to")
- X (mail-fetch-field "apparently-to") ;uck
- X "")))))
- X (string< ato bto)))
- X
- X;;; utilities which know how folder attribute names are stored. All
- X;;; the following are internal to pcmailattr.el
- X;;;
- X;;; system-defined attributes are interned in a completion obarray at load
- X;;; time. New user-defined attributes are interned into the obarray as
- X;;; needed, as well as installed in the current folder's babyl header
- X;;; labels: field. Old user-defined attributes are read from labels: fields
- X;;; and interned into the obarray as folders are opened for the first time
- X
- X(defun pcmail-add-to-message-attribute-list (n attr)
- X "Add an attribute to a message's attribute list.
- XArgs (n attr)
- X Add attribute string ATTR to message absolute-numbered N's attribute list."
- X (aset pcmail-attr-vector n
- X (cons attr (aref pcmail-attr-vector n))))
- X
- X(defun pcmail-remove-from-message-attribute-list (n attr)
- X "Remove an attribute from a message's attribute list.
- XArgs: (n attr)
- X Remove attribute string ATTR from message absolute-numbered N's attribute
- Xlist."
- X (let ((attrs (aref pcmail-attr-vector n))
- X (temp))
- X (while attrs
- X (or (string= attr (car attrs))
- X (setq temp (cons (car attrs) temp)))
- X (setq attrs (cdr attrs)))
- X (aset pcmail-attr-vector n temp)))
- X
- X(defun pcmail-read-attr (prompt)
- X "Read an attribute from the minibuffer.
- XArgs: (prompt)
- X Read an attribute from the minibuffer, prompting with PROMPT. Blank input
- Xcauses the value of pcmail-last-attr to be used. Non-blank input completes
- Xoff pcmail-attribute-obarray, setting pcmail-last-attr to be the input just
- Xreceived. If the attribute is not in the obarray ask if it should be put
- Xthere as well as in the current folder's Babyl header labels: field."
- X (or (pcmail-attribute-p pcmail-last-attr)
- X (setq pcmail-last-attr nil))
- X (let ((a (pcmail-completing-read prompt pcmail-attribute-obarray
- X pcmail-last-attr)))
- X (or (pcmail-attribute-p a)
- X (if (y-or-n-p "Undefined attribute; install? ")
- X (pcmail-install-attribute a)
- X (error "Aborted.")))
- X (setq pcmail-last-attr a)))
- X
- X(defun pcmail-attribute-p (a)
- X "Return non-NIL if A is a valid attribute, NIL else.
- XArgs: (a)"
- X (and (stringp a) (intern-soft a pcmail-attribute-obarray)))
- X
- X(defun pcmail-legal-attribute-name-p (a)
- X "Return non-NIL if A is a legal attribute string, NIL else.
- XArgs: (a)"
- X (not (string-match "," a)))
- X
- X(defun pcmail-load-user-defined-attributes ()
- X "Intern user-defined labels.
- XArgs: none"
- X (mapcar '(lambda (x) (intern x pcmail-attribute-obarray))
- X (pcmail-user-defined-babyl-attr-list)))
- X
- X(defun pcmail-install-attribute (attr)
- X "Install a user-defined message attribute.
- XArgs: (attr)
- X Place attribute ATTR in the completion obarray pcmail-attribute-obarray."
- X (or (pcmail-legal-attribute-name-p attr)
- X (error "%s is not a legal attribute name."))
- X (pcmail-insert-user-defined-babyl-attr attr)
- X (intern attr pcmail-attribute-obarray))
- X
- X(provide 'pcmailattr)
- X
- ________This_Is_The_END________
- if test `wc -c < pcmailattr.el` -ne 24644; then
- echo 'shar: pcmailattr.el was damaged during transit (should have been 24644 bytes)'
- fi
- fi ; : end of overwriting check
- echo 'x - pcmailmove.el'
- if test -f pcmailmove.el; then echo 'shar: not overwriting pcmailmove.el'; else
- sed 's/^X//' << '________This_Is_The_END________' > pcmailmove.el
- X;;;; GNU-EMACS PCMAIL mail reader
- X
- X;; Written by Mark L. Lambert
- X;; Architecture Group, Network Products Division
- X;; Oracle Corporation
- X;; 20 Davis Dr,
- X;; Belmont CA, 94002
- X;;
- X;; internet: markl@oracle.com or markl%oracle.com@apple.com
- X;; UUCP: {hplabs,uunet,apple}!oracle!markl
- X
- X;; Copyright (C) 1989 Mark L. Lambert
- X
- X;; This file is not officially part of GNU Emacs, but is being
- X;; donated to the Free Software Foundation. As such, it is
- X;; subject to the standard GNU-Emacs General Public License,
- X;; referred to below.
- X
- X;; GNU Emacs is distributed in the hope that it will be useful,
- X;; but WITHOUT ANY WARRANTY. No author or distributor
- X;; accepts responsibility to anyone for the consequences of using it
- X;; or for whether it serves any particular purpose or works at all,
- X;; unless he says so in writing. Refer to the GNU Emacs General Public
- X;; License for full details.
- X
- X;; Everyone is granted permission to copy, modify and redistribute
- X;; GNU Emacs, but only under the conditions described in the
- X;; GNU Emacs General Public License. A copy of this license is
- X;; supposed to have been given to you along with GNU Emacs so you
- X;; can know your rights and responsibilities. It should be in a
- X;; file named COPYING. Among other things, the copyright notice
- X;; and this notice must be preserved on all copies.
- X
- X;;;; movement and display commands within a single folder
- X
- X;;; movement commands
- X
- X(defun pcmail-beginning-of-message ()
- X "Move to the beginning of the current message.
- XArgs: none"
- X (interactive)
- X (pcmail-barf-if-empty-folder)
- X (pcmail-goto-message pcmail-current-subset-message))
- X
- X(defun pcmail-goto-message (&optional n)
- X "Move to message number N of the current subset and display it.
- XArgs: (&optional n)
- XDisplay message N in the current folder's curent subset. If called
- Xinteractively, N is specified by a numeric prefix argument. If not
- Xspecified, N defaults to the first message in the subset."
- X (interactive "p")
- X (pcmail-display-subset-message (or n (setq n 1))))
- X
- X(defun pcmail-last-message (&optional dont-skip)
- X "Move to the last interesting message in the current subset and display it.
- XArgs: (&optional dont-skip)
- X Display the last interesting message in the current folder's current subset.
- Xpcmail-interesting-p returns non-NIL when applied to an interesting message.
- XIf called interactively, a prefix argument means move to the last message in
- Xthe subset whether interesting or not."
- X (interactive "P")
- X (pcmail-barf-if-empty-folder)
- X (let ((n))
- X (cond (dont-skip
- X (setq n (pcmail-current-subset-length)))
- X (t
- X (let ((pcmail-current-subset-message
- X (pcmail-current-subset-length)))
- X (setq n (pcmail-next-subset-message-of-type
- X nil nil 'include-current 'pcmail-interesting-p)))))
- X (cond (n
- X (pcmail-goto-message n))
- X (t
- X (pcmail-goto-message 1)
- X (message "No interesting messages in this folder")))))
- X
- X(defun pcmail-next-message (&optional dont-skip)
- X "Move to the next interesting message in the current subset and display it.
- XArgs: (&optional dont-skip)
- X Display the next interesting message in the current folder's current subset.
- Xpcmail-interesting-p returns non-NIL when applied to an interesting message.
- XIf called interactively, a prefix argument means move to the next message in
- Xthe subset whether interesting or not."
- X (interactive "P")
- X (pcmail-barf-if-empty-folder)
- X (let ((n))
- X (cond (dont-skip
- X (setq n (1+ pcmail-current-subset-message)))
- X (t
- X (setq n (pcmail-next-subset-message-of-type
- X 'forward nil nil 'pcmail-interesting-p))))
- X (cond (n
- X (pcmail-goto-message n))
- X (t
- X (message "No further interesting messages.")))))
- X
- X(defun pcmail-next-message-of-type (filter-name)
- X "Move to the next message in the current subset that satisfies a predicate.
- XArgs: (filter)
- X If called interactively, read a filter name from the minibuffer, use
- Xit to read that filter's arguments and get the filter predicate. If called
- Xas a function, supply a valid filter name. Move to and display the next
- Xsuch message."
- X (interactive
- X (list (pcmail-read-filter-name "Show next message in filter: ")))
- X (pcmail-barf-if-empty-folder)
- X (let ((i (1+ pcmail-current-subset-message))
- X (found)
- X (pred (pcmail-get-filter filter-name))
- X (pcmail-current-tested-message)) ;inherited by predicates
- X (while (and (not found) (<= i (pcmail-current-subset-length)))
- X (setq pcmail-current-tested-message (pcmail-make-absolute i))
- X (and (eval pred)
- X (setq found i))
- X (setq i (1+ i)))
- X (cond (found
- X (pcmail-goto-message found))
- X (t
- X (error "No more such messages in the current subset.")))))
- X
- X(defun pcmail-previous-message (&optional dont-skip)
- X "Move to the previous interesting message in the current subset and display.
- XArgs: (&optional dont-skip)
- X Display the previous interesting message in the current folder's current
- Xsubset. pcmail-interesting-p returns non-NIL when applied to an interesting
- Xmessage. If called interactively, a prefix argument means move to the
- Xprevious message in the subset whether interesting or not."
- X (interactive "P")
- X (pcmail-barf-if-empty-folder)
- X (let ((n))
- X (cond (dont-skip
- X (setq n (1- pcmail-current-subset-message)))
- X (t
- X (setq n (pcmail-next-subset-message-of-type
- X nil nil nil 'pcmail-interesting-p))))
- X (cond (n
- X (pcmail-goto-message n))
- X (t
- X (message "No previous interesting messages.")))))
- X
- X
- X(defun pcmail-previous-message-of-type (filter-name)
- X "Move to the previous message in the current subset satisfying a predicate.
- XArgs: (filter)
- X If called interactively, read a filter name from the minibuffer, use
- Xit to read that filter's arguments and get the filter predicate. If called
- Xas a function, supply a valid filter name. Move to and display the first
- Xprevious such message."
- X (interactive
- X (list (pcmail-read-filter-name "Show previous message in filter: ")))
- X (pcmail-barf-if-empty-folder)
- X (let ((i (1- pcmail-current-subset-message))
- X (found)
- X (pred (pcmail-get-filter filter-name))
- X (pcmail-current-tested-message)) ;inherited by predicates
- X (while (and (not found) (>= i 1))
- X (setq pcmail-current-tested-message (pcmail-make-absolute i))
- X (and (eval pred)
- X (setq found i))
- X (setq i (1- i)))
- X (cond (found
- X (pcmail-goto-message found))
- X (t
- X (error "No previous such messages in the current subset.")))))
- X
- X;;; movement utility routines
- X
- X(defun pcmail-display-subset-message (n)
- X "Display the Nth message in the current subset.
- XArgs: (n)"
- X (let ((msg)
- X (absolute))
- X (cond ((< n 1)
- X (setq n (min 1 (pcmail-current-subset-length))
- X msg "Beginning of folder")
- X (setq pcmail-current-subset-message 1))
- X ((> n (pcmail-current-subset-length))
- X (setq n (pcmail-current-subset-length)
- X msg "End of folder")
- X (setq pcmail-current-subset-message
- X (pcmail-current-subset-length)))
- X (t
- X (setq pcmail-current-subset-message n)))
- X (setq absolute (pcmail-make-absolute n))
- X (or (pcmail-header-pruned-p absolute)
- X (pcmail-prune-header absolute))
- X (and (pcmail-has-attribute-p absolute "unseen")
- X (pcmail-set-attribute absolute "unseen" nil))
- X (pcmail-narrow-to-message absolute)
- X (pcmail-update-folder-mode-line n)
- X (and msg (message msg))))
- X
- X(defun pcmail-message-char-count (n)
- X "Return number of characters in message absolute-numbered N.
- XArgs: (n)"
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-message n)
- X (- (point-max) (point-min)))))
- X
- X(defun pcmail-message-line-count (n)
- X "Return number of lines in message absolute-numbered N.
- XArgs: (n)"
- X (save-excursion
- X (save-restriction
- X (pcmail-narrow-to-message n)
- X (count-lines (point-min) (point-max)))))
- X
- X(defun pcmail-message-contents (n)
- X "Return message N's contents
- XArgs: (n)
- X Returns contents of message absolute-numbered N, including all Babyl header
- Xand trailer information, as a string."
- X (save-restriction
- X (widen)
- X (buffer-substring (pcmail-msgbeg n) (pcmail-msgend n))))
- X
- X(defun pcmail-maybe-set-message-vectors ()
- X "Reset message vectors if any are NIL.
- XArgs: none"
- X (or (and pcmail-total-messages
- X pcmail-current-subset-message
- X pcmail-attr-vector
- X pcmail-message-vector)
- X (pcmail-set-message-vectors)))
- X
- X(defun pcmail-set-message-vectors (&optional start)
- X "Scan folder, setting up message information vectors.
- XArgs: (&optional start)
- X Set up current buffer's message information vectors. Build current
- Xsubset using default filter name. Deal with expired messages. Message
- Xscan begins at buffer position START, if present. If start is not present,
- Xflush old message counters before scan, otherwise append new information
- Xto old counters. See also pcmail-scan-babyl-messages."
- X (let ((total-messages 0)
- X (i 0)
- X (case-fold-search)
- X (timely-list)
- X (messages-list)
- X (filter)
- X (filter-start)
- X (attr-list))
- X (unwind-protect
- X (progn
- X (cond ((null start) ;new?
- X (and (vectorp pcmail-message-vector)
- X (while (< i (length pcmail-message-vector))
- X (move-marker (aref pcmail-message-vector i) nil)
- X (setq i (1+ i))))
- X (setq pcmail-message-vector
- X (make-vector 1
- X (save-restriction
- X (widen)
- X (point-min-marker)))
- X pcmail-current-subset-message 1
- X pcmail-attr-vector nil
- X pcmail-total-messages -1
- X pcmail-date-vector (make-vector 1 nil)
- X pcmail-priority-vector (make-vector 1 nil)
- X pcmail-summary-vector (make-vector 1 nil)
- X filter (pcmail-filter-description
- X pcmail-default-filter-name)))
- X (t ;or append?
- X (setq filter-start (1+ pcmail-total-messages)
- X filter pcmail-current-filter-description)))
- X (pcmail-scan-babyl-messages start))
- X (setq pcmail-message-vector
- X (vconcat pcmail-message-vector (apply 'vector messages-list))
- X pcmail-attr-vector
- X (vconcat pcmail-attr-vector (apply 'vector attr-list))
- X pcmail-date-vector
- X (vconcat pcmail-date-vector (make-vector total-messages nil))
- X pcmail-priority-vector
- X (vconcat pcmail-priority-vector (make-vector total-messages nil))
- X pcmail-summary-vector
- X (vconcat pcmail-summary-vector (make-vector total-messages nil))
- X pcmail-total-messages (+ pcmail-total-messages total-messages))
- X (pcmail-build-subset-membership filter filter-start)
- X (pcmail-hack-timely-messages timely-list)
- X (and (>= total-messages pcmail-progress-interval)
- X (message "Counting messages in %s...done (%d message%s)"
- X pcmail-folder-name total-messages
- X (pcmail-s-ending total-messages))))))
- X
- X(defun pcmail-msgbeg (n)
- X "Return marker position of beginning of message absolute-numbered N.
- XArgs: none"
- X (aref pcmail-message-vector n))
- X
- X(defun pcmail-msgend (n)
- X "Return marker position of end of message absolute-numbered N.
- XArgs: none"
- X (aref pcmail-message-vector (1+ n)))
- X
- X(provide 'pcmailmove)
- ________This_Is_The_END________
- if test `wc -c < pcmailmove.el` -ne 10900; then
- echo 'shar: pcmailmove.el was damaged during transit (should have been 10900 bytes)'
- fi
- fi ; : end of overwriting check
- exit 0
-
-