comparison lisp/mail/rmail.el @ 17620:30a88c9b3505

(rmail-msgref-vector): New variable. Holds, for each message, a cons cell which contains the message number and which relocates if the message number changes. (rmail-forget-messages): Clear rmail-msgref-vector. (rmail-variables): Make rmail-msgref-vector buffer-local. (rmail-count-new-messages): Extend rmail-msgref-vector. (rmail-set-message-counters): Initialize rmail-msgref-vector. (rmail-only-expunge): Update rmail-msgref-vector. Don't look for mail-mode buffers specially. (rmail-reply): Use rmail-msgref-vector element as arg. (rmail-forward, rmail-retry-failure): Likewise. (rmail-mark-message): Accept an element of rmail-mark-message as arg.
author Richard M. Stallman <rms@gnu.org>
date Fri, 02 May 1997 07:25:43 +0000
parents 09d1f6578d7f
children de5770c149d9
comparison
equal deleted inserted replaced
17619:c8e876b73dcd 17620:30a88c9b3505
1 ;;; rmail.el --- main code of "RMAIL" mail reader for Emacs. 1 ;;; rmail.el --- main code of "RMAIL" mail reader for Emacs.
2 2
3 ;; Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985,86,87,88,93,94,95,96,97 Free Software Foundation, Inc.
4 4
5 ;; Maintainer: FSF 5 ;; Maintainer: FSF
6 ;; Keywords: mail 6 ;; Keywords: mail
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
175 175
176 (defvar rmail-current-message nil) 176 (defvar rmail-current-message nil)
177 (defvar rmail-total-messages nil) 177 (defvar rmail-total-messages nil)
178 (defvar rmail-message-vector nil) 178 (defvar rmail-message-vector nil)
179 (defvar rmail-deleted-vector nil) 179 (defvar rmail-deleted-vector nil)
180 (defvar rmail-msgref-vector nil
181 "In an Rmail buffer, a vector whose Nth element is a list (N).
182 When expunging renumbers messages, these lists are modified
183 by substituting the new message number into the existing list.")
180 184
181 (defvar rmail-overlay-list nil) 185 (defvar rmail-overlay-list nil)
182 186
183 (defvar rmail-font-lock-keywords 187 (defvar rmail-font-lock-keywords
184 (eval-when-compile 188 (eval-when-compile
775 (make-local-variable 'kill-buffer-hook) 779 (make-local-variable 'kill-buffer-hook)
776 (add-hook 'kill-buffer-hook 'rmail-mode-kill-summary) 780 (add-hook 'kill-buffer-hook 'rmail-mode-kill-summary)
777 (make-local-variable 'file-precious-flag) 781 (make-local-variable 'file-precious-flag)
778 (setq file-precious-flag t) 782 (setq file-precious-flag t)
779 (make-local-variable 'rmail-message-vector) 783 (make-local-variable 'rmail-message-vector)
784 (make-local-variable 'rmail-msgref-vector)
780 (make-local-variable 'rmail-inbox-list) 785 (make-local-variable 'rmail-inbox-list)
781 (setq rmail-inbox-list (rmail-parse-file-inboxes)) 786 (setq rmail-inbox-list (rmail-parse-file-inboxes))
782 ;; Provide default set of inboxes for primary mail file ~/RMAIL. 787 ;; Provide default set of inboxes for primary mail file ~/RMAIL.
783 (and (null rmail-inbox-list) 788 (and (null rmail-inbox-list)
784 (or (equal buffer-file-name (expand-file-name rmail-file-name)) 789 (or (equal buffer-file-name (expand-file-name rmail-file-name))
1673 (n (length v))) 1678 (n (length v)))
1674 (while (< i n) 1679 (while (< i n)
1675 (move-marker (aref v i) nil) 1680 (move-marker (aref v i) nil)
1676 (setq i (1+ i))))) 1681 (setq i (1+ i)))))
1677 (setq rmail-message-vector nil) 1682 (setq rmail-message-vector nil)
1683 (setq rmail-msgref-vector nil)
1678 (setq rmail-deleted-vector nil))) 1684 (setq rmail-deleted-vector nil)))
1679 1685
1680 (defun rmail-maybe-set-message-counters () 1686 (defun rmail-maybe-set-message-counters ()
1681 (if (not (and rmail-deleted-vector 1687 (if (not (and rmail-deleted-vector
1682 rmail-message-vector 1688 rmail-message-vector
1707 rmail-current-message (car messages-head)) 1713 rmail-current-message (car messages-head))
1708 (setq rmail-deleted-vector 1714 (setq rmail-deleted-vector
1709 (concat rmail-deleted-vector deleted-head)) 1715 (concat rmail-deleted-vector deleted-head))
1710 (setq rmail-summary-vector 1716 (setq rmail-summary-vector
1711 (vconcat rmail-summary-vector (make-vector total-messages nil))) 1717 (vconcat rmail-summary-vector (make-vector total-messages nil)))
1718 (setq rmail-msgref-vector
1719 (vconcat rmail-msgref-vector (make-vector total-messages nil)))
1720 ;; Fill in the new elements of rmail-msgref-vector.
1721 (let ((i (- rmail-total-messages old-total-messages)))
1722 (while (<= i rmail-total-messages)
1723 (aset rmail-msgref-vector i (list i))
1724 (setq i (1+ i))))
1712 (goto-char (point-min)) 1725 (goto-char (point-min))
1713 (or nomsg (message "Counting new messages...done (%d)" total-messages)))) 1726 (or nomsg (message "Counting new messages...done (%d)" total-messages))))
1714 1727
1715 (defun rmail-set-message-counters () 1728 (defun rmail-set-message-counters ()
1716 (rmail-forget-messages) 1729 (rmail-forget-messages)
1739 (min total-messages 1752 (min total-messages
1740 (max 1 (- total-messages messages-after-point)))) 1753 (max 1 (- total-messages messages-after-point))))
1741 (setq rmail-message-vector 1754 (setq rmail-message-vector
1742 (apply 'vector (cons (point-min-marker) messages-head)) 1755 (apply 'vector (cons (point-min-marker) messages-head))
1743 rmail-deleted-vector (concat "D" deleted-head) 1756 rmail-deleted-vector (concat "D" deleted-head)
1744 rmail-summary-vector (make-vector rmail-total-messages nil)) 1757 rmail-summary-vector (make-vector rmail-total-messages nil)
1758 rmail-msgref-vector (make-vector (1+ rmail-total-messages) nil))
1759 (let ((i 0))
1760 (while (<= i rmail-total-messages)
1761 (aset rmail-msgref-vector i (list i))
1762 (setq i (1+ i))))
1745 (message "Counting messages...done"))))) 1763 (message "Counting messages...done")))))
1746 1764
1747 (defun rmail-set-message-counters-counter (&optional stop) 1765 (defun rmail-set-message-counters-counter (&optional stop)
1748 (while (search-backward "\n\^_\^L\n" stop t) 1766 (while (search-backward "\n\^_\^L\n" stop t)
1749 (forward-char 1) 1767 (forward-char 1)
2206 (let ((counter 0) 2224 (let ((counter 0)
2207 (number 1) 2225 (number 1)
2208 (total rmail-total-messages) 2226 (total rmail-total-messages)
2209 (new-message-number rmail-current-message) 2227 (new-message-number rmail-current-message)
2210 (new-summary nil) 2228 (new-summary nil)
2229 (new-msgref (list (list 0)))
2211 (rmailbuf (current-buffer)) 2230 (rmailbuf (current-buffer))
2212 (buffer-read-only nil) 2231 (buffer-read-only nil)
2213 (messages rmail-message-vector) 2232 (messages rmail-message-vector)
2214 (deleted rmail-deleted-vector) 2233 (deleted rmail-deleted-vector)
2215 (summary rmail-summary-vector)) 2234 (summary rmail-summary-vector))
2216 (setq rmail-total-messages nil 2235 (setq rmail-total-messages nil
2217 rmail-current-message nil 2236 rmail-current-message nil
2218 rmail-message-vector nil 2237 rmail-message-vector nil
2219 rmail-deleted-vector nil 2238 rmail-deleted-vector nil
2220 rmail-summary-vector nil) 2239 rmail-summary-vector nil)
2221
2222 ;; Find each sendmail buffer that is set to reply
2223 ;; to a message in this buffer, and update its
2224 ;; message number.
2225 (let ((bufs (buffer-list)))
2226 (while bufs
2227 (save-excursion
2228 (set-buffer (car bufs))
2229 (let ((tail mail-send-actions) action)
2230 (while tail
2231 (setq action (car tail)
2232 tail (cdr tail))
2233 (and (eq (car action) 'rmail-mark-message)
2234 (eq (nth 1 action) rmailbuf)
2235 (setcar (nthcdr 2 action)
2236 (rmail-msg-number-after-expunge
2237 deleted
2238 (nth 2 action)))))))
2239 (setq bufs (cdr bufs))))
2240 2240
2241 (while (<= number total) 2241 (while (<= number total)
2242 (if (= (aref deleted number) ?D) 2242 (if (= (aref deleted number) ?D)
2243 (progn 2243 (progn
2244 (delete-region 2244 (delete-region
2251 (setq messages-tail 2251 (setq messages-tail
2252 (setcdr messages-tail 2252 (setcdr messages-tail
2253 (cons (aref messages number) nil))) 2253 (cons (aref messages number) nil)))
2254 (setq new-summary 2254 (setq new-summary
2255 (cons (if (= counter number) (aref summary (1- number))) 2255 (cons (if (= counter number) (aref summary (1- number)))
2256 new-summary))) 2256 new-summary))
2257 (setq new-msgref
2258 (cons (aref rmail-msgref-vector number)
2259 new-msgref))
2260 (setcar (car new-msgref) counter))
2257 (if (zerop (% (setq number (1+ number)) 20)) 2261 (if (zerop (% (setq number (1+ number)) 20))
2258 (message "Expunging deleted messages...%d" number))) 2262 (message "Expunging deleted messages...%d" number)))
2259 (setq messages-tail 2263 (setq messages-tail
2260 (setcdr messages-tail 2264 (setcdr messages-tail
2261 (cons (aref messages number) nil))) 2265 (cons (aref messages number) nil)))
2262 (setq rmail-current-message new-message-number 2266 (setq rmail-current-message new-message-number
2263 rmail-total-messages counter 2267 rmail-total-messages counter
2264 rmail-message-vector (apply 'vector messages-head) 2268 rmail-message-vector (apply 'vector messages-head)
2265 rmail-deleted-vector (make-string (1+ counter) ?\ ) 2269 rmail-deleted-vector (make-string (1+ counter) ?\ )
2266 rmail-summary-vector (vconcat (nreverse new-summary)) 2270 rmail-summary-vector (vconcat (nreverse new-summary))
2271 rmail-msgref-vector (apply 'vector (nreverse new-msgref))
2267 win t))) 2272 win t)))
2268 (message "Expunging deleted messages...done") 2273 (message "Expunging deleted messages...done")
2269 (if (not win) 2274 (if (not win)
2270 (narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax))) 2275 (narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax)))
2271 (rmail-show-message 2276 (rmail-show-message
2388 (if (null cc) to (concat to ", " cc)))))) 2393 (if (null cc) to (concat to ", " cc))))))
2389 (if (string= cc-list "") nil cc-list))) 2394 (if (string= cc-list "") nil cc-list)))
2390 rmail-view-buffer 2395 rmail-view-buffer
2391 (list (list 'rmail-mark-message 2396 (list (list 'rmail-mark-message
2392 rmail-view-buffer 2397 rmail-view-buffer
2393 msgnum 2398 (aref rmail-msgref-vector msgnum)
2394 "answered")) 2399 "answered"))
2395 nil 2400 nil
2396 (list (cons "References" (concat (mapconcat 'identity references " ") 2401 (list (cons "References" (concat (mapconcat 'identity references " ")
2397 " " message-id)))))) 2402 " " message-id))))))
2398 2403
2399 (defun rmail-mark-message (buffer msgnum attribute) 2404 (defun rmail-mark-message (buffer msgnum-list attribute)
2400 "Give BUFFER's message number MSGNUM the attribute ATTRIBUTE. 2405 "Give BUFFER's message number in MSGNUM-LIST the attribute ATTRIBUTE.
2401 This is use in the send-actions for message buffers." 2406 This is use in the send-actions for message buffers.
2407 MSGNUM-LIST is a list of the form (MSGNUM)
2408 which is an element of rmail-msgref-vector."
2402 (save-excursion 2409 (save-excursion
2403 (set-buffer buffer) 2410 (set-buffer buffer)
2404 (if msgnum 2411 (if (car msgnum-list)
2405 (rmail-set-attribute attribute t msgnum)))) 2412 (rmail-set-attribute attribute t (car msgnum-list)))))
2406 2413
2407 (defun rmail-make-in-reply-to-field (from date message-id) 2414 (defun rmail-make-in-reply-to-field (from date message-id)
2408 (cond ((not from) 2415 (cond ((not from)
2409 (if message-id 2416 (if message-id
2410 message-id 2417 message-id
2479 (or (mail-fetch-field "Subject") "") 2486 (or (mail-fetch-field "Subject") "")
2480 "]"))) 2487 "]")))
2481 (if (rmail-start-mail 2488 (if (rmail-start-mail
2482 nil nil subject nil nil nil 2489 nil nil subject nil nil nil
2483 (list (list 'rmail-mark-message 2490 (list (list 'rmail-mark-message
2484 forward-buffer msgnum 2491 forward-buffer
2492 (aref rmail-msgref-vector msgnum)
2485 "forwarded")) 2493 "forwarded"))
2486 ;; If only one window, use it for the mail buffer. 2494 ;; If only one window, use it for the mail buffer.
2487 ;; Otherwise, use another window for the mail buffer 2495 ;; Otherwise, use another window for the mail buffer
2488 ;; so that the Rmail buffer remains visible 2496 ;; so that the Rmail buffer remains visible
2489 ;; and sending the mail will get back to it. 2497 ;; and sending the mail will get back to it.
2698 ;; Turn off the usual actions for initializing the message body 2706 ;; Turn off the usual actions for initializing the message body
2699 ;; because we want to get only the text from the failure message. 2707 ;; because we want to get only the text from the failure message.
2700 (let (mail-signature mail-setup-hook) 2708 (let (mail-signature mail-setup-hook)
2701 (if (rmail-start-mail nil nil nil nil nil rmail-buffer 2709 (if (rmail-start-mail nil nil nil nil nil rmail-buffer
2702 (list (list 'rmail-mark-message 2710 (list (list 'rmail-mark-message
2703 rmail-buffer msgnum "retried"))) 2711 rmail-buffer
2712 (aref rmail-msgref-vector msgnum)
2713 "retried")))
2704 ;; Insert original text as initial text of new draft message. 2714 ;; Insert original text as initial text of new draft message.
2705 ;; Bind inhibit-read-only since the header delimiter 2715 ;; Bind inhibit-read-only since the header delimiter
2706 ;; of the previous message was probably read-only. 2716 ;; of the previous message was probably read-only.
2707 (let ((inhibit-read-only t)) 2717 (let ((inhibit-read-only t))
2708 (erase-buffer) 2718 (erase-buffer)