aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-09 08:08:13 +0000
committerRichard M. Stallman1993-03-09 08:08:13 +0000
commitbd1f0f843fdfc2cb76785928d5baacd9b4ab090b (patch)
treef87a4e49dcdb65fed1362e7303147b83d02fba83
parentaf39530ef0d6622ca5d08948a2da37cbe93f1969 (diff)
downloademacs-bd1f0f843fdfc2cb76785928d5baacd9b4ab090b.tar.gz
emacs-bd1f0f843fdfc2cb76785928d5baacd9b4ab090b.zip
(rmail-delete-forward): Go to summary buf to change D mark.
Always do the motion in the rmail buffer; let that handle summary. (rmail-undelete-previous-message): Likewise. (rmail-select-summary): New macro. (rmail-show-message): Use rmail-select-summary. (rmail-get-new-mail): Likewise. (rmail-expunge): Likewise. (rmail-bury): Record Rmail buffer to bury it later. Major changes from Bob Weiner <weiner@pts.mot.com> Handle some Emacs 18 function names to run in 18. This is to facilitate working with Weiner. (rmail-reply-prefix): New variable. (rmail-reply): Use that variable to add to subject. (rmail-retry-failure): Change binding to M-m. (rmail-forward): Look for >From as well as for From. Handle case where neither is found. (rmail-last-regexp): New variable. (rmail-mode): Make rmail-last-regexp local. (rmail): Don't update rmail-mode data for old buffer if it's not in rmail mode. Error if in Rmail Edit mode. (rmail-bury): New command, plus key binding. (rmail-summary-by-topic): New key binding. (rmail-insert-inbox-text): Check for pop case earlier. (rmail-convert-to-babyl-format): Handle Content-Length field. (rmail-maybe-display-summary): New function. (rmail-redisplay-summary): New user option. (rmail-undelete-previous-message, rmail-delete-forward): (rmail-get-new-mail, rmail-show-message): Update summary buffer if any. Call rmail-maybe-display-summary to put it back on screen. (rmail-only-expunge): Renamed from rmail-expunge. (rmail-expunge): New function. (rmail-message-recipients-p, rmail-message-regexp-p): New functions. (rmail-summary-exists, rmail-summary-displayed): New functions.
-rw-r--r--lisp/mail/rmail.el339
1 files changed, 259 insertions, 80 deletions
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index d300398361e..05cd3d7868f 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -1,6 +1,6 @@
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, 1986, 1987, 1988, 1991, 1992 Free Software Foundation, Inc. 3;; Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
4 4
5;; Maintainer: FSF 5;; Maintainer: FSF
6;; Keywords: mail 6;; Keywords: mail
@@ -28,8 +28,24 @@
28;; selection by dispatch table, summary by attributes and keywords, 28;; selection by dispatch table, summary by attributes and keywords,
29;; expunging by dispatch table, sticky options for file commands. 29;; expunging by dispatch table, sticky options for file commands.
30 30
31;; Extended by Bob Weiner of Motorola
32;; New features include: rmail and rmail-summary buffers remain
33;; synchronized and key bindings basically operate the same way in both
34;; buffers, summary by topic or by regular expression, rmail-reply-prefix
35;; variable, and a bury rmail buffer (wipe) command.
36;;
37
31(require 'mail-utils) 38(require 'mail-utils)
32; These variables now declared paths.el 39
40;; For Emacs V18 compatibility
41(and (not (fboundp 'user-original-login-name))
42 (fboundp 'user-real-login-name)
43 (fset 'user-original-login-name 'user-real-login-name))
44(and (not (fboundp 'buffer-disable-undo))
45 (fboundp 'buffer-flush-undo)
46 (fset 'buffer-disable-undo 'buffer-flush-undo))
47
48; These variables now declared in paths.el.
33;(defvar rmail-spool-directory "/usr/spool/mail/" 49;(defvar rmail-spool-directory "/usr/spool/mail/"
34; "This is the name of the directory used by the system mailer for\n\ 50; "This is the name of the directory used by the system mailer for\n\
35;delivering new mail. It's name should end with a slash.") 51;delivering new mail. It's name should end with a slash.")
@@ -65,9 +81,9 @@ It is useful to set this variable in the site customisation file.")
65\(the first name varies depending on the operating system, 81\(the first name varies depending on the operating system,
66and the value of the environment variable MAIL overrides it).") 82and the value of the environment variable MAIL overrides it).")
67 83
68;; these may be altered by site-init.el to match the format of mmdf files 84;; These may be altered by site-init.el to match the format of mmdf files
69;; delimitation used on a given host (delim1 and delim2 from the config 85;; delimiting used on a given host (delim1 and delim2 from the config
70;; files) 86;; files).
71 87
72(defvar mmdf-delim1 "^\001\001\001\001\n" 88(defvar mmdf-delim1 "^\001\001\001\001\n"
73 "Regexp marking the start of an mmdf message") 89 "Regexp marking the start of an mmdf message")
@@ -78,6 +94,9 @@ and the value of the environment variable MAIL overrides it).")
78 "If non nil, is a filter function for new headers in RMAIL. 94 "If non nil, is a filter function for new headers in RMAIL.
79Called with region narrowed to unformatted header.") 95Called with region narrowed to unformatted header.")
80 96
97(defvar rmail-reply-prefix "Re: "
98 "String to prepend to Subject line when replying to a message.")
99
81(defvar rmail-mode-map nil) 100(defvar rmail-mode-map nil)
82 101
83(defvar rmail-inbox-list nil) 102(defvar rmail-inbox-list nil)
@@ -99,9 +118,10 @@ Called with region narrowed to unformatted header.")
99 118
100;; Last individual label specified to a or k. 119;; Last individual label specified to a or k.
101(defvar rmail-last-label nil) 120(defvar rmail-last-label nil)
102;; Last set of labels specified to C-M-n or C-M-p or C-M-l. 121;; Last set of values specified to C-M-n, C-M-p, C-M-s or C-M-l.
103(defvar rmail-last-multi-labels nil) 122(defvar rmail-last-multi-labels nil)
104(defvar rmail-last-file nil) 123(defvar rmail-last-file nil)
124(defvar rmail-last-regexp nil)
105(defvar rmail-last-rmail-file nil) 125(defvar rmail-last-rmail-file nil)
106 126
107;;; Regexp matching the delimiter of messages in UNIX mail format 127;;; Regexp matching the delimiter of messages in UNIX mail format
@@ -145,7 +165,20 @@ Called with region narrowed to unformatted header.")
145 "\n")) 165 "\n"))
146 nil) 166 nil)
147 167
148 168;; Perform BODY in the summary buffer
169;; in such a way that its cursor is properly updated in its own window.
170(defmacro rmail-select-summary (&rest body)
171 (` (progn (if (rmail-summary-displayed)
172 (let ((window (selected-window)))
173 (unwind-protect
174 (progn
175 (pop-to-buffer rmail-summary-buffer)
176 (,@ body))
177 (select-window window)))
178 (save-excursion
179 (set-buffer rmail-summary-buffer)
180 (progn (,@ body))))
181 (rmail-maybe-display-summary))))
149 182
150;;;; *** Rmail Mode *** 183;;;; *** Rmail Mode ***
151 184
@@ -175,11 +208,14 @@ that file, but does not copy any new mail into the file."
175 ;; in the last message in the RMAIL file. 208 ;; in the last message in the RMAIL file.
176 (let ((enable-local-variables nil)) 209 (let ((enable-local-variables nil))
177 (find-file file-name)) 210 (find-file file-name))
178 (if (verify-visited-file-modtime existed) 211 (if (and (verify-visited-file-modtime existed)
212 (eq major-mode 'rmail-mode))
179 (progn (rmail-forget-messages) 213 (progn (rmail-forget-messages)
180 (rmail-set-message-counters)))) 214 (rmail-set-message-counters))))
181 (let ((enable-local-variables nil)) 215 (let ((enable-local-variables nil))
182 (find-file file-name))) 216 (find-file file-name)))
217 (if (eq major-mode 'rmail-edit-mode)
218 (error "Exit Rmail Edit mode before getting new mail."))
183 (if (and existed (> (buffer-size) 0)) 219 (if (and existed (> (buffer-size) 0))
184 ;; Buffer not new and not empty; ensure in proper mode, but that's all. 220 ;; Buffer not new and not empty; ensure in proper mode, but that's all.
185 (or (eq major-mode 'rmail-mode) 221 (or (eq major-mode 'rmail-mode)
@@ -272,48 +308,51 @@ Note: it means the file has no messages in it.\n\^_")))
272 nil 308 nil
273 (setq rmail-mode-map (make-keymap)) 309 (setq rmail-mode-map (make-keymap))
274 (suppress-keymap rmail-mode-map) 310 (suppress-keymap rmail-mode-map)
275 (define-key rmail-mode-map "." 'rmail-beginning-of-message) 311 (define-key rmail-mode-map "a" 'rmail-add-label)
276 (define-key rmail-mode-map " " 'scroll-up) 312 (define-key rmail-mode-map "b" 'rmail-bury)
277 (define-key rmail-mode-map "\177" 'scroll-down) 313 (define-key rmail-mode-map "c" 'rmail-continue)
278 (define-key rmail-mode-map "n" 'rmail-next-undeleted-message) 314 (define-key rmail-mode-map "d" 'rmail-delete-forward)
279 (define-key rmail-mode-map "p" 'rmail-previous-undeleted-message) 315 (define-key rmail-mode-map "\C-d" 'rmail-delete-backward)
280 (define-key rmail-mode-map "\en" 'rmail-next-message) 316 (define-key rmail-mode-map "e" 'rmail-edit-current-message)
281 (define-key rmail-mode-map "\ep" 'rmail-previous-message) 317 (define-key rmail-mode-map "f" 'rmail-forward)
282 (define-key rmail-mode-map "\e\C-n" 'rmail-next-labeled-message) 318 (define-key rmail-mode-map "g" 'rmail-get-new-mail)
283 (define-key rmail-mode-map "\e\C-p" 'rmail-previous-labeled-message) 319 (define-key rmail-mode-map "h" 'rmail-summary)
284 (define-key rmail-mode-map "a" 'rmail-add-label) 320 (define-key rmail-mode-map "i" 'rmail-input)
285 (define-key rmail-mode-map "k" 'rmail-kill-label) 321 (define-key rmail-mode-map "j" 'rmail-show-message)
286 (define-key rmail-mode-map "d" 'rmail-delete-forward) 322 (define-key rmail-mode-map "k" 'rmail-kill-label)
287 (define-key rmail-mode-map "u" 'rmail-undelete-previous-message) 323 (define-key rmail-mode-map "l" 'rmail-summary-by-labels)
288 (define-key rmail-mode-map "x" 'rmail-expunge)
289 (define-key rmail-mode-map "s" 'rmail-expunge-and-save)
290 (define-key rmail-mode-map "g" 'rmail-get-new-mail)
291 (define-key rmail-mode-map "h" 'rmail-summary)
292 (define-key rmail-mode-map "\e\C-h" 'rmail-summary) 324 (define-key rmail-mode-map "\e\C-h" 'rmail-summary)
293 (define-key rmail-mode-map "l" 'rmail-summary-by-labels)
294 (define-key rmail-mode-map "\e\C-l" 'rmail-summary-by-labels) 325 (define-key rmail-mode-map "\e\C-l" 'rmail-summary-by-labels)
295 (define-key rmail-mode-map "\e\C-r" 'rmail-summary-by-recipients) 326 (define-key rmail-mode-map "\e\C-r" 'rmail-summary-by-recipients)
296 (define-key rmail-mode-map "\e\C-s" 'rmail-summary-by-regexp) 327 (define-key rmail-mode-map "\e\C-s" 'rmail-summary-by-regexp)
297 (define-key rmail-mode-map "t" 'rmail-toggle-header) 328 (define-key rmail-mode-map "\e\C-t" 'rmail-summary-by-topic)
298 (define-key rmail-mode-map "m" 'rmail-mail) 329 (define-key rmail-mode-map "m" 'rmail-mail)
299 (define-key rmail-mode-map "r" 'rmail-reply) 330 (define-key rmail-mode-map "\em" 'rmail-retry-failure)
300 (define-key rmail-mode-map "\e\C-m" 'rmail-retry-failure) 331 (define-key rmail-mode-map "n" 'rmail-next-undeleted-message)
301 (define-key rmail-mode-map "c" 'rmail-continue) 332 (define-key rmail-mode-map "\en" 'rmail-next-message)
302 (define-key rmail-mode-map "f" 'rmail-forward) 333 (define-key rmail-mode-map "\e\C-n" 'rmail-next-labeled-message)
334 (define-key rmail-mode-map "o" 'rmail-output-to-rmail-file)
335 (define-key rmail-mode-map "\C-o" 'rmail-output)
336 (define-key rmail-mode-map "p" 'rmail-previous-undeleted-message)
337 (define-key rmail-mode-map "\ep" 'rmail-previous-message)
338 (define-key rmail-mode-map "\e\C-p" 'rmail-previous-labeled-message)
339 (define-key rmail-mode-map "q" 'rmail-quit)
340 (define-key rmail-mode-map "r" 'rmail-reply)
303;; I find I can't live without the default M-r command -- rms. 341;; I find I can't live without the default M-r command -- rms.
304;; (define-key rmail-mode-map "\er" 'rmail-search-backwards) 342;; (define-key rmail-mode-map "\er" 'rmail-search-backwards)
305 (define-key rmail-mode-map "\es" 'rmail-search) 343 (define-key rmail-mode-map "s" 'rmail-expunge-and-save)
306 (define-key rmail-mode-map "<" 'rmail-first-message) 344 (define-key rmail-mode-map "\es" 'rmail-search)
307 (define-key rmail-mode-map ">" 'rmail-last-message) 345 (define-key rmail-mode-map "t" 'rmail-toggle-header)
308 (define-key rmail-mode-map "j" 'rmail-show-message) 346 (define-key rmail-mode-map "u" 'rmail-undelete-previous-message)
309 (define-key rmail-mode-map "o" 'rmail-output-to-rmail-file) 347 (define-key rmail-mode-map "w" 'rmail-edit-current-message)
310 (define-key rmail-mode-map "\C-o" 'rmail-output) 348 (define-key rmail-mode-map "x" 'rmail-expunge)
311 (define-key rmail-mode-map "i" 'rmail-input) 349 (define-key rmail-mode-map "." 'rmail-beginning-of-message)
312 (define-key rmail-mode-map "q" 'rmail-quit) 350 (define-key rmail-mode-map "<" 'rmail-first-message)
313 (define-key rmail-mode-map "?" 'describe-mode) 351 (define-key rmail-mode-map ">" 'rmail-last-message)
314 (define-key rmail-mode-map "w" 'rmail-edit-current-message) 352 (define-key rmail-mode-map " " 'scroll-up)
315 (define-key rmail-mode-map "e" 'rmail-edit-current-message) 353 (define-key rmail-mode-map "\177" 'scroll-down)
316 (define-key rmail-mode-map "\C-d" 'rmail-delete-backward)) 354 (define-key rmail-mode-map "?" 'describe-mode)
355 )
317 356
318;; Rmail mode is suitable only for specially formatted data. 357;; Rmail mode is suitable only for specially formatted data.
319(put 'rmail-mode 'mode-class 'special) 358(put 'rmail-mode 'mode-class 'special)
@@ -339,6 +378,7 @@ Instead, these commands are available:
339\\[rmail-delete-backward] Delete this message, move to previous nondeleted. 378\\[rmail-delete-backward] Delete this message, move to previous nondeleted.
340\\[rmail-undelete-previous-message] Undelete message. Tries current message, then earlier messages 379\\[rmail-undelete-previous-message] Undelete message. Tries current message, then earlier messages
341 till a deleted message is found. 380 till a deleted message is found.
381\\[rmail-edit-current-message] Edit the current message. \\[rmail-cease-edit] to return to Rmail.
342\\[rmail-expunge] Expunge deleted messages. 382\\[rmail-expunge] Expunge deleted messages.
343\\[rmail-expunge-and-save] Expunge and save the file. 383\\[rmail-expunge-and-save] Expunge and save the file.
344\\[rmail-quit] Quit Rmail: expunge, save, then switch to another buffer. 384\\[rmail-quit] Quit Rmail: expunge, save, then switch to another buffer.
@@ -346,8 +386,8 @@ Instead, these commands are available:
346\\[rmail-get-new-mail] Move new mail from system spool directory or mbox into this file. 386\\[rmail-get-new-mail] Move new mail from system spool directory or mbox into this file.
347\\[rmail-mail] Mail a message (same as \\[mail-other-window]). 387\\[rmail-mail] Mail a message (same as \\[mail-other-window]).
348\\[rmail-continue] Continue composing outgoing message started before. 388\\[rmail-continue] Continue composing outgoing message started before.
349\\[rmail-reply] Reply to this message. Like m but initializes some fields. 389\\[rmail-reply] Reply to this message. Like \\[rmail-mail] but initializes some fields.
350\\[rmail-retry-failure] Send this message again. Used on a mailer failure message. 390\\[rmail-retry-failure] Send this message again. Used on a mailer failure message.
351\\[rmail-forward] Forward this message to another user. 391\\[rmail-forward] Forward this message to another user.
352\\[rmail-output-to-rmail-file] Output this message to an Rmail file (append it). 392\\[rmail-output-to-rmail-file] Output this message to an Rmail file (append it).
353\\[rmail-output] Output this message to a Unix-format mail file (append it). 393\\[rmail-output] Output this message to a Unix-format mail file (append it).
@@ -357,13 +397,14 @@ Instead, these commands are available:
357\\[rmail-next-labeled-message] Move to Next message with specified label 397\\[rmail-next-labeled-message] Move to Next message with specified label
358 (label defaults to last one specified). 398 (label defaults to last one specified).
359 Standard labels: filed, unseen, answered, forwarded, deleted. 399 Standard labels: filed, unseen, answered, forwarded, deleted.
360 Any other label is present only if you add it with `a'. 400 Any other label is present only if you add it with \\[rmail-add-label].
361\\[rmail-previous-labeled-message] Move to Previous message with specified label 401\\[rmail-previous-labeled-message] Move to Previous message with specified label
362\\[rmail-summary] Show headers buffer, with a one line summary of each message. 402\\[rmail-summary] Show headers buffer, with a one line summary of each message.
363\\[rmail-summary-by-labels] Like \\[rmail-summary] only just messages with particular label(s) are summarized. 403\\[rmail-summary-by-labels] Summarize only messages with particular label(s).
364\\[rmail-summary-by-recipients] Like \\[rmail-summary] only just messages with particular recipient(s) are summarized. 404\\[rmail-summary-by-recipients] Summarize only messages with particular recipient(s).
365\\[rmail-toggle-header] Toggle header, show Rmail header if unformatted or vice versa. 405\\[rmail-summary-by-regexp] Summarize only messages with particular regexp(s).
366\\[rmail-edit-current-message] Edit the current message. \\[rmail-cease-edit] to return to Rmail." 406\\[rmail-summary-by-topic] Summarize only messages with subject line regexp(s).
407\\[rmail-toggle-header] Toggle display of complete header."
367 (interactive) 408 (interactive)
368 (rmail-mode-2) 409 (rmail-mode-2)
369 (rmail-set-message-counters) 410 (rmail-set-message-counters)
@@ -393,6 +434,7 @@ Instead, these commands are available:
393 (make-local-variable 'revert-buffer-function) 434 (make-local-variable 'revert-buffer-function)
394 (setq revert-buffer-function 'rmail-revert) 435 (setq revert-buffer-function 'rmail-revert)
395 (make-local-variable 'rmail-last-label) 436 (make-local-variable 'rmail-last-label)
437 (make-local-variable 'rmail-last-regexp)
396 (make-local-variable 'rmail-deleted-vector) 438 (make-local-variable 'rmail-deleted-vector)
397 (make-local-variable 'rmail-summary-buffer) 439 (make-local-variable 'rmail-summary-buffer)
398 (make-local-variable 'rmail-summary-vector) 440 (make-local-variable 'rmail-summary-vector)
@@ -462,7 +504,7 @@ Instead, these commands are available:
462 504
463;;;###autoload 505;;;###autoload
464(defun rmail-input (filename) 506(defun rmail-input (filename)
465 "Run RMAIL on file FILENAME." 507 "Run Rmail on file FILENAME."
466 (interactive "FRun rmail on RMAIL file: ") 508 (interactive "FRun rmail on RMAIL file: ")
467 (rmail filename)) 509 (rmail filename))
468 510
@@ -546,6 +588,9 @@ argument causes us to read a file name and use that file as the inbox."
546 (progn (goto-char opoint) 588 (progn (goto-char opoint)
547 (if (or file-name rmail-inbox-list) 589 (if (or file-name rmail-inbox-list)
548 (message "(No new mail has arrived)"))) 590 (message "(No new mail has arrived)")))
591 (if (rmail-summary-exists)
592 (rmail-select-summary
593 (rmail-update-summary)))
549 (message "%d new message%s read" 594 (message "%d new message%s read"
550 new-messages (if (= 1 new-messages) "" "s")) 595 new-messages (if (= 1 new-messages) "" "s"))
551 (and (boundp 'display-time-string) 596 (and (boundp 'display-time-string)
@@ -559,7 +604,7 @@ argument causes us to read a file name and use that file as the inbox."
559 (rmail-show-message))) 604 (rmail-show-message)))
560 605
561(defun rmail-insert-inbox-text (files renamep) 606(defun rmail-insert-inbox-text (files renamep)
562 (let (file tofile delete-files movemail) 607 (let (file tofile delete-files movemail popmail)
563 (while files 608 (while files
564 (setq file (expand-file-name (substitute-in-file-name (car files))) 609 (setq file (expand-file-name (substitute-in-file-name (car files)))
565 ;;>> un*x specific << 610 ;;>> un*x specific <<
@@ -570,32 +615,42 @@ argument causes us to read a file name and use that file as the inbox."
570 ;; If getting from mail spool directory, 615 ;; If getting from mail spool directory,
571 ;; use movemail to move rather than just renaming, 616 ;; use movemail to move rather than just renaming,
572 ;; so as to interlock with the mailer. 617 ;; so as to interlock with the mailer.
573 (setq movemail (equal (file-name-directory file) rmail-spool-directory)) 618 (setq movemail (equal (file-name-directory file) rmail-spool-directory)
619 popmail (string-match "^po:" (file-name-nondirectory file)))
620 (if popmail (setq file (file-name-nondirectory file)
621 renamep t))
574 (if movemail 622 (if movemail
575 (progn 623 (progn
576 (setq tofile (expand-file-name 624 (setq tofile (expand-file-name
577 ;; Generate name to move to from inbox name, 625 ;; Generate name to move to from inbox name,
578 ;; in case of multiple inboxes that need moving. 626 ;; in case of multiple inboxes that need moving.
579 (concat ".newmail-" (file-name-nondirectory file)) 627 (concat ".newmail-" (file-name-nondirectory file))
580 (file-name-directory 628 ;; Use the directory of this rmail file
581 (expand-file-name rmail-file-name)))) 629 ;; because it's a nuisance to use the homedir
630 ;; if that is on a full disk and this rmail
631 ;; file isn't.
632 (file-name-directory
633 (expand-file-name buffer-file-name))))
582 ;; On some systems, /usr/spool/mail/foo is a directory 634 ;; On some systems, /usr/spool/mail/foo is a directory
583 ;; and the actual inbox is /usr/spool/mail/foo/foo. 635 ;; and the actual inbox is /usr/spool/mail/foo/foo.
584 (if (file-directory-p file) 636 (if (file-directory-p file)
585 (setq file (expand-file-name (user-original-login-name) 637 (setq file (expand-file-name (user-original-login-name)
586 file))))) 638 file)))))
587 (if (or (and (file-exists-p tofile) 639 (if popmail
588 (/= 0 (nth 7 (file-attributes tofile)))) 640 (message "Getting mail from post office ...")
589 (and (file-exists-p file) 641 (if (or (and (file-exists-p tofile)
590 (/= 0 (nth 7 (file-attributes file))))) 642 (/= 0 (nth 7 (file-attributes tofile))))
591 (message "Getting mail from %s..." file)) 643 (and (file-exists-p file)
644 (/= 0 (nth 7 (file-attributes file)))))
645 (message "Getting mail from %s..." file)))
592 ;; Set TOFILE if have not already done so, and 646 ;; Set TOFILE if have not already done so, and
593 ;; rename or copy the file FILE to TOFILE if and as appropriate. 647 ;; rename or copy the file FILE to TOFILE if and as appropriate.
594 (cond ((not renamep) 648 (cond ((not renamep)
595 (setq tofile file)) 649 (setq tofile file))
596 ((or (file-exists-p tofile) (not (file-exists-p file))) 650 ((or (file-exists-p tofile) (and (not popmail)
651 (not (file-exists-p file))))
597 nil) 652 nil)
598 ((not movemail) 653 ((and (not movemail) (not popmail))
599 (rename-file file tofile nil) 654 (rename-file file tofile nil)
600 ;; Make the real inbox file empty. 655 ;; Make the real inbox file empty.
601 ;; Leaving it deleted could cause lossage 656 ;; Leaving it deleted could cause lossage
@@ -704,6 +759,26 @@ argument causes us to read a file name and use that file as the inbox."
704 (setq start (point)) 759 (setq start (point))
705 (insert "\^L\n0, unseen,,\n*** EOOH ***\n") 760 (insert "\^L\n0, unseen,,\n*** EOOH ***\n")
706 (rmail-nuke-pinhead-header) 761 (rmail-nuke-pinhead-header)
762 ;; If this message has a Content-Length field,
763 ;; skip to the end of the contents.
764 (let* ((header-end (save-excursion
765 (and (re-search-forward "\n\n" nil t)
766 (point))))
767 (case-fold-search t)
768 (size
769 ;; Get the numeric value from the Content-Length field.
770 (save-excursion
771 ;; Back up to end of prev line,
772 ;; in case the Content-Length field comes first.
773 (forward-char -1)
774 (and (search-forward "\ncontent-length: "
775 header-end t)
776 (let ((beg (point))
777 (eol (progn (end-of-line) (point))))
778 (read (buffer-substring beg eol)))))))
779 (if size
780 (goto-char (+ header-end size))))
781
707 (if (re-search-forward 782 (if (re-search-forward
708 (concat "^[\^_]?\\(" 783 (concat "^[\^_]?\\("
709 rmail-unix-mail-delimiter 784 rmail-unix-mail-delimiter
@@ -1070,7 +1145,8 @@ change the invisible header text."
1070 (rmail-show-message rmail-current-message)) 1145 (rmail-show-message rmail-current-message))
1071 1146
1072(defun rmail-show-message (&optional n) 1147(defun rmail-show-message (&optional n)
1073 "Show message number N (prefix argument), counting from start of file." 1148 "Show message number N (prefix argument), counting from start of file.
1149If summary buffer is currently displayed, update current message there also."
1074 (interactive "p") 1150 (interactive "p")
1075 (rmail-maybe-set-message-counters) 1151 (rmail-maybe-set-message-counters)
1076 (widen) 1152 (widen)
@@ -1104,6 +1180,13 @@ change the invisible header text."
1104 (goto-char (point-min)) 1180 (goto-char (point-min))
1105 (rmail-display-labels) 1181 (rmail-display-labels)
1106 (run-hooks 'rmail-show-message-hook) 1182 (run-hooks 'rmail-show-message-hook)
1183 ;; If there is a summary buffer, try to move to this message
1184 ;; in that buffer. But don't complain if this message
1185 ;; is not mentioned in the summary.
1186 (if (rmail-summary-exists)
1187 (let ((curr-msg rmail-current-message))
1188 (rmail-select-summary
1189 (rmail-summary-goto-msg curr-msg t t))))
1107 (if blurb 1190 (if blurb
1108 (message blurb)))))) 1191 (message blurb))))))
1109 1192
@@ -1174,6 +1257,24 @@ or forward if N is negative."
1174 (setq mid (+ low (/ (- high low) 2)))) 1257 (setq mid (+ low (/ (- high low) 2))))
1175 (if (>= where (rmail-msgbeg high)) high low))) 1258 (if (>= where (rmail-msgbeg high)) high low)))
1176 1259
1260(defun rmail-message-recipients-p (msg recipients &optional primary-only)
1261 (save-restriction
1262 (goto-char (rmail-msgbeg msg))
1263 (search-forward "\n*** EOOH ***\n")
1264 (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
1265 (or (string-match recipients (or (mail-fetch-field "To") ""))
1266 (string-match recipients (or (mail-fetch-field "From") ""))
1267 (if (not primary-only)
1268 (string-match recipients (or (mail-fetch-field "Cc") ""))))))
1269
1270(defun rmail-message-regexp-p (msg regexp)
1271 "Return t, if for message number MSG, regexp REGEXP matches in the header."
1272 (goto-char (rmail-msgbeg msg))
1273 (let ((end
1274 (save-excursion
1275 (search-forward "*** EOOH ***" (point-max)) (point))))
1276 (re-search-forward regexp end t)))
1277
1177(defvar rmail-search-last-regexp nil) 1278(defvar rmail-search-last-regexp nil)
1178(defun rmail-search (regexp &optional n) 1279(defun rmail-search (regexp &optional n)
1179 "Show message containing next match for REGEXP. 1280 "Show message containing next match for REGEXP.
@@ -1307,7 +1408,12 @@ Interactively, empty argument means use same regexp used last time."
1307 (error "No previous deleted message") 1408 (error "No previous deleted message")
1308 (if (/= msg rmail-current-message) 1409 (if (/= msg rmail-current-message)
1309 (rmail-show-message msg)) 1410 (rmail-show-message msg))
1310 (rmail-set-attribute "deleted" nil)))) 1411 (rmail-set-attribute "deleted" nil)
1412 (if (rmail-summary-exists)
1413 (save-excursion
1414 (set-buffer rmail-summary-buffer)
1415 (rmail-summary-mark-undeleted msg)))
1416 (rmail-maybe-display-summary))))
1311 1417
1312(defun rmail-delete-forward (&optional backward) 1418(defun rmail-delete-forward (&optional backward)
1313 "Delete this message and move to next nondeleted one. 1419 "Delete this message and move to next nondeleted one.
@@ -1315,7 +1421,13 @@ Deleted messages stay in the file until the \\[rmail-expunge] command is given.
1315With prefix argument, delete and move backward." 1421With prefix argument, delete and move backward."
1316 (interactive "P") 1422 (interactive "P")
1317 (rmail-set-attribute "deleted" t) 1423 (rmail-set-attribute "deleted" t)
1318 (rmail-next-undeleted-message (if backward -1 1))) 1424 (let ((del-msg rmail-current-message))
1425 (if (rmail-summary-exists)
1426 (save-excursion
1427 (set-buffer rmail-summary-buffer)
1428 (rmail-summary-mark-deleted del-msg)))
1429 (rmail-next-undeleted-message (if backward -1 1))
1430 (rmail-maybe-display-summary)))
1319 1431
1320(defun rmail-delete-backward () 1432(defun rmail-delete-backward ()
1321 "Delete this message and move to previous nondeleted one. 1433 "Delete this message and move to previous nondeleted one.
@@ -1323,7 +1435,7 @@ Deleted messages stay in the file until the \\[rmail-expunge] command is given."
1323 (interactive) 1435 (interactive)
1324 (rmail-delete-forward t)) 1436 (rmail-delete-forward t))
1325 1437
1326(defun rmail-expunge () 1438(defun rmail-only-expunge ()
1327 "Actually erase all deleted messages in the file." 1439 "Actually erase all deleted messages in the file."
1328 (interactive) 1440 (interactive)
1329 (message "Expunging deleted messages...") 1441 (message "Expunging deleted messages...")
@@ -1392,12 +1504,21 @@ Deleted messages stay in the file until the \\[rmail-expunge] command is given."
1392 (rmail-show-message 1504 (rmail-show-message
1393 (if (zerop rmail-current-message) 1 nil)) 1505 (if (zerop rmail-current-message) 1 nil))
1394 (forward-char opoint)))) 1506 (forward-char opoint))))
1507
1508(defun rmail-expunge ()
1509 "Erase deleted messages from Rmail file and summary buffer."
1510 (interactive)
1511 (rmail-only-expunge)
1512 (if (rmail-summary-exists)
1513 (rmail-select-summary
1514 (rmail-update-summary))))
1395 1515
1396;;;; *** Rmail Mailing Commands *** 1516;;;; *** Rmail Mailing Commands ***
1397 1517
1398(defun rmail-mail () 1518(defun rmail-mail ()
1399 "Send mail in another window. While composing the message, use 1519 "Send mail in another window.
1400\\[mail-yank-original] to yank the original message into it." 1520While composing the message, use \\[mail-yank-original] to yank the
1521original message into it."
1401 (interactive) 1522 (interactive)
1402 (mail-other-window nil nil nil nil nil (current-buffer))) 1523 (mail-other-window nil nil nil nil nil (current-buffer)))
1403 1524
@@ -1450,9 +1571,10 @@ use \\[mail-yank-original] to yank the original message into it."
1450 message-id (cond (resent-reply-to 1571 message-id (cond (resent-reply-to
1451 (mail-fetch-field "resent-message-id" t)) 1572 (mail-fetch-field "resent-message-id" t))
1452 ((mail-fetch-field "message-id")))))) 1573 ((mail-fetch-field "message-id"))))))
1453 (and subject 1574 (and (stringp subject)
1454 (string-match "\\`Re: " subject) 1575 (or (string-match (concat "\\`" (regexp-quote rmail-reply-prefix))
1455 (setq subject (substring subject 4))) 1576 subject)
1577 (setq subject (concat rmail-reply-prefix subject))))
1456 (mail-other-window nil 1578 (mail-other-window nil
1457 (mail-strip-quoted-names reply-to) 1579 (mail-strip-quoted-names reply-to)
1458 subject 1580 subject
@@ -1528,8 +1650,13 @@ use \\[mail-yank-original] to yank the original message into it."
1528 (interactive) 1650 (interactive)
1529 (let ((forward-buffer (current-buffer)) 1651 (let ((forward-buffer (current-buffer))
1530 (subject (concat "[" 1652 (subject (concat "["
1531 (mail-strip-quoted-names (mail-fetch-field "From")) 1653 (let ((from (or (mail-fetch-field "From")
1532 ": " (or (mail-fetch-field "Subject") "") "]"))) 1654 (mail-fetch-field ">From"))))
1655 (if from
1656 (concat (mail-strip-quoted-names from) ": ")
1657 ""))
1658 (or (mail-fetch-field "Subject") "")
1659 "]")))
1533 ;; Turn off the usual actions for initializing the message body 1660 ;; Turn off the usual actions for initializing the message body
1534 ;; because we want to get only the text from the failure message. 1661 ;; because we want to get only the text from the failure message.
1535 (let (mail-signature mail-setup-hook) 1662 (let (mail-signature mail-setup-hook)
@@ -1544,7 +1671,8 @@ use \\[mail-yank-original] to yank the original message into it."
1544 (list (list (function (lambda (buf msgnum) 1671 (list (list (function (lambda (buf msgnum)
1545 (save-excursion 1672 (save-excursion
1546 (set-buffer buf) 1673 (set-buffer buf)
1547 (rmail-set-attribute "forwarded" t msgnum)))) 1674 (rmail-set-attribute
1675 "forwarded" t msgnum))))
1548 (current-buffer) 1676 (current-buffer)
1549 rmail-current-message))) 1677 rmail-current-message)))
1550 (save-excursion 1678 (save-excursion
@@ -1646,6 +1774,38 @@ the body of the original message; otherwise copy the current message."
1646 (insert orig-message) 1774 (insert orig-message)
1647 (goto-char (point-min)) 1775 (goto-char (point-min))
1648 (end-of-line)))))) 1776 (end-of-line))))))
1777
1778(defun rmail-bury ()
1779 "Bury current Rmail buffer and its summary buffer."
1780 (interactive)
1781 (let ((rmail-buffer (current-buffer)))
1782 (if (rmail-summary-exists)
1783 (let (window)
1784 (while (setq window (get-buffer-window rmail-summary-buffer))
1785 (set-window-buffer (other-buffer rmail-summary-buffer)))
1786 (bury-buffer rmail-summary-buffer)))
1787 (switch-to-buffer (other-buffer (current-buffer)))
1788 (bury-buffer rmail-buffer)))
1789
1790(defun rmail-summary-exists ()
1791 "Non-nil iff in an RMAIL buffer and an associated summary buffer exists.
1792Non-nil value returned is the summary buffer."
1793 (and rmail-summary-buffer (buffer-name rmail-summary-buffer)
1794 rmail-summary-buffer))
1795
1796(defun rmail-summary-displayed ()
1797 "t iff in RMAIL buffer and an associated summary buffer is displayed."
1798 (and rmail-summary-buffer (get-buffer-window rmail-summary-buffer)))
1799
1800(defvar rmail-redisplay-summary nil
1801 "*Non-nil means Rmail should show the summary when it changes.
1802This has an effect only if a summary buffer exists.")
1803
1804;; Put the summary buffer back on the screen, if user wants that.
1805(defun rmail-maybe-display-summary ()
1806 (and rmail-summary-buffer (buffer-name rmail-summary-buffer)
1807 rmail-redisplay-summary
1808 (display-buffer rmail-summary-buffer)))
1649 1809
1650;;;; *** Rmail Specify Inbox Files *** 1810;;;; *** Rmail Specify Inbox Files ***
1651 1811
@@ -1677,6 +1837,10 @@ With prefix argument N moves forward N messages with this label."
1677With prefix argument N moves backward N messages with this label." 1837With prefix argument N moves backward N messages with this label."
1678 t) 1838 t)
1679 1839
1840(autoload 'rmail-read-label "rmailkwd"
1841 "PROMPT and read with completion an Rmail message label."
1842 t)
1843
1680;;;; *** Rmail Edit Mode *** 1844;;;; *** Rmail Edit Mode ***
1681 1845
1682(autoload 'rmail-edit-current-message "rmailedit" 1846(autoload 'rmail-edit-current-message "rmailedit"
@@ -1698,7 +1862,22 @@ LABELS should be a string containing the desired labels, separated by commas."
1698 "Display a summary of all messages with the given RECIPIENTS. 1862 "Display a summary of all messages with the given RECIPIENTS.
1699Normally checks the To, From and Cc fields of headers; but if PRIMARY-ONLY 1863Normally checks the To, From and Cc fields of headers; but if PRIMARY-ONLY
1700is non-nil (prefix arg given), only look in the To and From fields. 1864is non-nil (prefix arg given), only look in the To and From fields.
1701RECIPIENTS is a string of names separated by commas." 1865RECIPIENTS is a string of regexps separated by commas."
1866 t)
1867
1868(autoload 'rmail-summary-by-regexp "rmailsum"
1869 "Display a summary of all messages according to regexp REGEXP.
1870If the regular expression is found in the header of the message
1871\(including in the date and other lines, as well as the subject line),
1872Emacs will list the header line in the RMAIL-summary."
1873 t)
1874
1875(autoload 'rmail-summary-by-topic "rmailsum"
1876 "Display a summary of all messages with the given SUBJECT.
1877Normally checks the Subject field of headers;
1878but if WHOLE-MESSAGE is non-nil (prefix arg given),
1879 look in the whole message.
1880SUBJECT is a string of regexps separated by commas."
1702 t) 1881 t)
1703 1882
1704;;;; *** Rmail output messages to files *** 1883;;;; *** Rmail output messages to files ***