Mercurial > emacs
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) |