comparison lisp/mail/rmailsum.el @ 88130:363419a0d27c

Commentary: Add text. History: Add header and mbox item. Overhaul summary buffer movement. (rmail-summary-font-lock-keywords): Compress the attribute character display field by one character. (rmail-new-summary): Rewrite. (rmail-make-summary-line-1): Slight rewrite to deal with small changes in the summary format. (rmail-make-basic-summary-line): Use the rmail message vector. (rmail-summary-next-msg): Rewrite. (rmail-summary-next-labeled-message): Set the summary buffer copy of the rmail-current-message to force the display to show it. (rmail-summary-next-same-subject): Rewrite. (rmail-summary-delete-forward): Remove some questionable code and make summary buffer movement explicit. (rmail-summary-mark-deleted): Make sure to reflect the deletion for the Rmail buffer. (rmail-summary-deleted-p): Rewrite. (rmail-summary-undelete-many): Set the summary buffer copy of the rmail-current-message to force the display to show it. (rmail-summary-rmail-update): Rewrite. (rmail-summary-mode-map): Use "B" to send the message body to a browser; use (rmail-summary-output) instead of (rmail-summary-output-to-rmail-file). Similarly for the menu item. (rmail-summary-mouse-goto-msg): Set the summary buffer copy of the rmail-current-message to force the display to show it. (rmail-summary-get-message-at-point): New function. (rmail-summary-goto-msg): Rewrite. (rmail-summary-expunge, rmail-summary-expunge-and-save, rmail-summary-get-new-mail, rmail-summary-toggle-header): Rewrite. (rmail-summary-get-line-count, rmail-summary-get-summary-attributes, rmail-summary-get-summary, rmail-summary-update-attribute, rmail-summary-browse-body): New functions.
author Paul Reilly <pmr@pajato.com>
date Sat, 15 Feb 2003 17:13:03 +0000
parents 32bf542aaf1c
children 31edc813b710
comparison
equal deleted inserted replaced
88129:89e63d46028b 88130:363419a0d27c
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA. 24 ;; Boston, MA 02111-1307, USA.
25 25
26 ;;; Commentary: 26 ;;; Commentary:
27 27
28 ;; All commands run from the summary buffer update the buffer local
29 ;; variable `rmail-current-message'. As part of the post command
30 ;; processing point is moved to the beginning of the line describing
31 ;; the current message.
32
33 ;;; History:
34
28 ;; Extended by Bob Weiner of Motorola 35 ;; Extended by Bob Weiner of Motorola
29 ;; Provided all commands from rmail-mode in rmail-summary-mode and made key 36 ;; Provided all commands from rmail-mode in rmail-summary-mode and made key
30 ;; bindings in both modes wholly compatible. 37 ;; bindings in both modes wholly compatible.
38
39 ;; Overhauled by Paul Reilly to support mbox format.
31 40
32 ;;; Code: 41 ;;; Code:
33 42
34 ;; For rmail-select-summary 43 ;; For rmail-select-summary
35 (require 'rmail) 44 (require 'rmail)
40 :type 'boolean 49 :type 'boolean
41 :group 'rmail-summary) 50 :group 'rmail-summary)
42 51
43 ;;;###autoload 52 ;;;###autoload
44 (defcustom rmail-summary-line-count-flag t 53 (defcustom rmail-summary-line-count-flag t
45 "*Non-nil means Rmail summary should show the number of lines in each message." 54 "*Non-nil if Rmail summary should show the number of lines in each message."
46 :type 'boolean 55 :type 'boolean
47 :group 'rmail-summary) 56 :group 'rmail-summary)
48 57
49 (defvar rmail-summary-font-lock-keywords 58 (defvar rmail-summary-font-lock-keywords
50 '(("^.....D.*" . font-lock-string-face) ; Deleted. 59 '(("^....D.*" . font-lock-string-face) ; Deleted.
51 ("^.....-.*" . font-lock-type-face) ; Unread. 60 ("^....-.*" . font-lock-type-face) ; Unread.
52 ;; Neither of the below will be highlighted if either of the above are: 61 ;; Neither of the below will be highlighted if either of the above are:
53 ("^.....[^D-] \\(......\\)" 1 font-lock-keyword-face) ; Date. 62 ("^....[^D-]....\\(......\\)" 1 font-lock-keyword-face) ; Date.
54 ("{ \\([^\n}]+\\),}" 1 font-lock-comment-face)) ; Labels. 63 ("{ \\([^\n}]+\\),}" 1 font-lock-comment-face)) ; Labels.
55 "Additional expressions to highlight in Rmail Summary mode.") 64 "Additional expressions to highlight in Rmail Summary mode.")
65
66 (defvar rmail-summary-redo nil
67 "Private storage for Rmail summary history.")
68
69 (defvar rmail-summary-overlay nil
70 "Private storage for an Rmail summary overlay cache")
71 (put 'rmail-summary-overlay 'permanent-local t)
72
73 (defvar rmail-summary-mode-map nil
74 "Storage for the Ramil summary mode keymap.")
56 75
57 ;; Entry points for making a summary buffer. 76 ;; Entry points for making a summary buffer.
58 77
59 ;; Regenerate the contents of the summary 78 ;; Regenerate the contents of the summary
60 ;; using the same selection criterion as last time. 79 ;; using the same selection criterion as last time.
159 (goto-char (rmail-msgbeg msg)) 178 (goto-char (rmail-msgbeg msg))
160 (search-forward "\n*** EOOH ***\n") 179 (search-forward "\n*** EOOH ***\n")
161 (narrow-to-region (point) (progn (search-forward "\n\n") (point))) 180 (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
162 (string-match senders (or (mail-fetch-field "From") "")))) 181 (string-match senders (or (mail-fetch-field "From") ""))))
163 182
164 ;; General making of a summary buffer. 183 ;;;; General making of a summary buffer.
165 184
166 (defvar rmail-summary-symbol-number 0) 185 (defvar rmail-summary-symbol-number 0)
167 186
187 ;;; mbox: ready
168 (defun rmail-new-summary (description redo-form function &rest args) 188 (defun rmail-new-summary (description redo-form function &rest args)
169 "Create a summary of selected messages. 189 "Create a summary of selected messages.
170 DESCRIPTION makes part of the mode line of the summary buffer. 190 DESCRIPTION makes part of the mode line of the summary buffer.
171 For each message, FUNCTION is applied to the message number and ARGS... 191 For each message, FUNCTION is applied to the message number and ARGS...
172 and if the result is non-nil, that message is included. 192 and if the result is non-nil, that message is included.
173 nil for FUNCTION means all messages." 193 nil for FUNCTION means all messages."
174 (message "Computing summary lines...") 194 (message "Computing summary lines...")
175 (let (sumbuf mesg was-in-summary) 195 (let ((summary-msgs ())
196 (new-summary-line-count 0)
197 (msgnum 1)
198 current-message sumbuf was-in-summary)
199
200 ;; Go to the Rmail buffer.
201 (if (eq major-mode 'rmail-summary-mode)
202 (progn
203 (setq was-in-summary t)
204 (set-buffer rmail-buffer)))
205
206 ;; Find its summary buffer, or make one.
207 (setq current-message rmail-current-message
208 sumbuf
209 (if (and rmail-summary-buffer
210 (buffer-name rmail-summary-buffer))
211 rmail-summary-buffer
212 (generate-new-buffer (concat (buffer-name) "-summary"))))
213
214 ;; Collect the message summaries based on the filtering
215 ;; argument (FUNCTION).
216 (while (>= rmail-total-messages msgnum)
217 (if (or (null function)
218 (apply function (cons msgnum args)))
219 (setq summary-msgs
220 (cons (cons msgnum (rmail-summary-get-summary msgnum))
221 summary-msgs)))
222 (setq msgnum (1+ msgnum)))
223 (setq summary-msgs (nreverse summary-msgs))
224
225 ;; Place the collected summaries into the summary buffer.
226 (setq rmail-summary-buffer nil)
176 (save-excursion 227 (save-excursion
177 ;; Go to the Rmail buffer. 228 (let ((rbuf (current-buffer))
178 (if (eq major-mode 'rmail-summary-mode) 229 (vbuf rmail-view-buffer)
179 (setq was-in-summary t)) 230 (total rmail-total-messages))
180 (set-buffer rmail-buffer) 231 (set-buffer sumbuf)
181 ;; Find its summary buffer, or make one. 232 ;; Set up the summary buffer's contents.
182 (setq sumbuf 233 (let ((buffer-read-only nil))
183 (if (and rmail-summary-buffer 234 (erase-buffer)
184 (buffer-name rmail-summary-buffer)) 235 (while summary-msgs
185 rmail-summary-buffer 236 (princ (cdr (car summary-msgs)) sumbuf)
186 (generate-new-buffer (concat (buffer-name) "-summary")))) 237 (setq summary-msgs (cdr summary-msgs)))
187 (setq mesg rmail-current-message) 238 (goto-char (point-min)))
188 ;; Filter the messages; make or get their summary lines. 239 ;; Set up the rest of its state and local variables.
189 (let ((summary-msgs ()) 240 (setq buffer-read-only t)
190 (new-summary-line-count 0)) 241 (rmail-summary-mode)
191 (let ((msgnum 1) 242 (make-local-variable 'minor-mode-alist)
192 (buffer-read-only nil) 243 (setq minor-mode-alist (list (list t (concat ": " description))))
193 (old-min (point-min-marker)) 244 (setq rmail-buffer rbuf
194 (old-max (point-max-marker))) 245 rmail-view-buffer vbuf
195 ;; Can't use save-restriction here; that doesn't work if we 246 rmail-summary-redo redo-form
196 ;; plan to modify text outside the original restriction. 247 rmail-total-messages total
197 (save-excursion 248 rmail-current-message current-message)))
198 (widen) 249 (setq rmail-summary-buffer sumbuf)
199 (goto-char (point-min)) 250
200 (while (>= rmail-total-messages msgnum) 251 (set-buffer rmail-summary-buffer)
201 (if (or (null function) 252 (rmail-summary-goto-msg current-message nil t)
202 (apply function (cons msgnum args))) 253 (rmail-summary-construct-io-menu)
203 (setq summary-msgs 254
204 (cons (cons msgnum (rmail-make-summary-line msgnum))
205 summary-msgs)))
206 (setq msgnum (1+ msgnum)))
207 (setq summary-msgs (nreverse summary-msgs)))
208 (narrow-to-region old-min old-max))
209 ;; Temporarily, while summary buffer is unfinished,
210 ;; we "don't have" a summary.
211 (setq rmail-summary-buffer nil)
212 (if rmail-enable-mime
213 (with-current-buffer rmail-view-buffer
214 (setq rmail-summary-buffer nil)))
215 (save-excursion
216 (let ((rbuf (current-buffer))
217 (vbuf rmail-view-buffer)
218 (total rmail-total-messages))
219 (set-buffer sumbuf)
220 ;; Set up the summary buffer's contents.
221 (let ((buffer-read-only nil))
222 (erase-buffer)
223 (while summary-msgs
224 (princ (cdr (car summary-msgs)) sumbuf)
225 (setq summary-msgs (cdr summary-msgs)))
226 (goto-char (point-min)))
227 ;; Set up the rest of its state and local variables.
228 (setq buffer-read-only t)
229 (rmail-summary-mode)
230 (make-local-variable 'minor-mode-alist)
231 (setq minor-mode-alist (list (list t (concat ": " description))))
232 (setq rmail-buffer rbuf
233 rmail-view-buffer vbuf
234 rmail-summary-redo redo-form
235 rmail-total-messages total))))
236 (setq rmail-summary-buffer sumbuf))
237 ;; Now display the summary buffer and go to the right place in it. 255 ;; Now display the summary buffer and go to the right place in it.
238 (or was-in-summary 256 (or was-in-summary
239 (progn 257 (progn
240 (if (and (one-window-p) 258 (if (and (one-window-p)
241 pop-up-windows (not pop-up-frames)) 259 pop-up-windows (not pop-up-frames))
242 ;; If there is just one window, put the summary on the top. 260 ;; If there is just one window, put the summary on the top.
243 (progn 261 (progn
244 (split-window (selected-window) rmail-summary-window-size) 262 (split-window (selected-window) rmail-summary-window-size)
245 (select-window (next-window (frame-first-window))) 263 (select-window (next-window (frame-first-window)))
246 (pop-to-buffer sumbuf) 264 (pop-to-buffer sumbuf)
247 ;; If pop-to-buffer did not use that window, delete that 265 ;; If pop-to-buffer did not use that window, delete that
248 ;; window. (This can happen if it uses another frame.) 266 ;; window. (This can happen if it uses another frame.)
249 (if (not (eq sumbuf (window-buffer (frame-first-window)))) 267 (if (not (eq sumbuf (window-buffer (frame-first-window))))
250 (delete-other-windows))) 268 (delete-other-windows))))
251 (pop-to-buffer sumbuf)) 269 ;;(pop-to-buffer sumbuf))
252 (set-buffer rmail-buffer) 270 (set-buffer rmail-buffer)
253 ;; This is how rmail makes the summary buffer reappear. 271 ;; This is how rmail makes the summary buffer reappear.
254 ;; We do this here to make the window the proper size. 272 ;; We do this here to make the window the proper size.
255 (rmail-select-summary nil) 273 (rmail-select-summary nil)))
256 (set-buffer rmail-summary-buffer)))
257 (rmail-summary-goto-msg mesg t t)
258 (rmail-summary-construct-io-menu)
259 (message "Computing summary lines...done"))) 274 (message "Computing summary lines...done")))
260 275
261 ;; Low levels of generating a summary. 276 ;;;; Low levels of generating a summary.
262 277
278 ;;; mbox: deprecated
263 (defun rmail-make-summary-line (msg) 279 (defun rmail-make-summary-line (msg)
264 (let ((line (or (aref rmail-summary-vector (1- msg)) 280 (let* ((new-summary-line-count 0)
265 (progn 281 (line (or (aref rmail-summary-vector (1- msg))
266 (setq new-summary-line-count 282 (progn
267 (1+ new-summary-line-count)) 283 (setq new-summary-line-count
268 (if (zerop (% new-summary-line-count 10)) 284 (1+ new-summary-line-count))
269 (message "Computing summary lines...%d" 285 (if (zerop (% new-summary-line-count 10))
270 new-summary-line-count)) 286 (message "Computing summary lines...%d"
271 (rmail-make-summary-line-1 msg))))) 287 new-summary-line-count))
288 (rmail-make-summary-line-1 msg)))))
272 ;; Fix up the part of the summary that says "deleted" or "unseen". 289 ;; Fix up the part of the summary that says "deleted" or "unseen".
273 (aset line 5 290 (aset line 5
274 (if (rmail-message-deleted-p msg) ?\D 291 (if (rmail-message-deleted-p msg) ?\D
275 (if (= ?0 (char-after (+ 3 (rmail-msgbeg msg)))) 292 (if (= ?0 (char-after (+ 3 (rmail-msgbeg msg))))
276 ?\- ?\ ))) 293 ?\- ?\ )))
285 :group 'rmail-summary) 302 :group 'rmail-summary)
286 303
287 (defun rmail-make-summary-line-1 (msg) 304 (defun rmail-make-summary-line-1 (msg)
288 (goto-char (rmail-msgbeg msg)) 305 (goto-char (rmail-msgbeg msg))
289 (let* ((lim (save-excursion (forward-line 2) (point))) 306 (let* ((lim (save-excursion (forward-line 2) (point)))
290 pos 307 (labels
291 (labels 308 (progn
292 (progn 309 (forward-char 3)
293 (forward-char 3) 310 (concat
294 (concat
295 ; (if (save-excursion (re-search-forward ",answered," lim t)) 311 ; (if (save-excursion (re-search-forward ",answered," lim t))
296 ; "*" "") 312 ; "*" "")
297 ; (if (save-excursion (re-search-forward ",filed," lim t)) 313 ; (if (save-excursion (re-search-forward ",filed," lim t))
298 ; "!" "") 314 ; "!" "")
299 (if (progn (search-forward ",,") (eolp)) 315 (if (progn (search-forward ",,") (eolp))
306 (progn 322 (progn
307 (forward-line 1) 323 (forward-line 1)
308 (if (looking-at "Summary-line: ") 324 (if (looking-at "Summary-line: ")
309 (progn 325 (progn
310 (goto-char (match-end 0)) 326 (goto-char (match-end 0))
311 (setq line 327 (buffer-substring (point)
312 (buffer-substring (point) 328 (progn (forward-line 1) (point)))))))
313 (progn (forward-line 1) (point))))))))) 329 pos)
330
314 ;; Obsolete status lines lacking a # should be flushed. 331 ;; Obsolete status lines lacking a # should be flushed.
315 (and line 332 (and line
316 (not (string-match "#" line)) 333 (not (string-match "#" line))
317 (progn 334 (progn
318 (delete-region (point) 335 (delete-region (point)
411 (forward-char -1) 428 (forward-char -1)
412 (skip-chars-backward " \t") 429 (skip-chars-backward " \t")
413 (point))))) 430 (point)))))
414 len mch lo) 431 len mch lo)
415 (if (string-match 432 (if (string-match
416 (or rmail-user-mail-address-regexp 433 (or rmail-user-mail-address-regexp
417 (concat "^\\(" 434 (concat "^\\("
418 (regexp-quote (user-login-name)) 435 (regexp-quote (user-login-name))
419 "\\($\\|@\\)\\|" 436 "\\($\\|@\\)\\|"
420 (regexp-quote 437 (regexp-quote
421 ;; Don't lose if run from init file 438 ;; Don't lose if run from init file
452 (min len (+ lo 25)))))))) 469 (min len (+ lo 25))))))))
453 (if rmail-summary-line-count-flag 470 (if rmail-summary-line-count-flag
454 (save-excursion 471 (save-excursion
455 (save-restriction 472 (save-restriction
456 (widen) 473 (widen)
457 (let ((beg (rmail-msgbeg msgnum)) 474 (let ((beg (rmail-msgbeg rmail-current-message))
458 (end (rmail-msgend msgnum)) 475 (end (rmail-msgend rmail-current-message))
459 lines) 476 lines)
460 (save-excursion 477 (save-excursion
461 (goto-char beg) 478 (goto-char beg)
462 ;; Count only lines in the reformatted header, 479 ;; Count only lines in the reformatted header,
463 ;; if we have reformatted it. 480 ;; if we have reformatted it.
478 (point)))) 495 (point))))
479 (re-search-forward "[\n][\n]+" nil t) 496 (re-search-forward "[\n][\n]+" nil t)
480 (buffer-substring (point) (progn (end-of-line) (point)))) 497 (buffer-substring (point) (progn (end-of-line) (point))))
481 "\n")) 498 "\n"))
482 499
483 ;; Simple motion in a summary buffer. 500 ;;;; Simple motion in a summary buffer.
484 501
485 (defun rmail-summary-next-all (&optional number) 502 (defun rmail-summary-next-all (&optional number)
503 "Move to an nearby message.
504 If NUMBER is positive then move forward NUMBER messages. If NUMBER is
505 negative then move backwards NUMBER messages. If NUMBER is nil then
506 move forward one message."
486 (interactive "p") 507 (interactive "p")
487 (forward-line (if number number 1)) 508 (forward-line (if number number 1))
488 ;; It doesn't look nice to move forward past the last message line. 509 ;; It doesn't look nice to move forward past the last message line.
489 (and (eobp) (> number 0) 510 (and (eobp) (> number 0)
490 (forward-line -1)) 511 (forward-line -1))
496 ;; It doesn't look nice to move forward past the last message line. 517 ;; It doesn't look nice to move forward past the last message line.
497 (and (eobp) (< number 0) 518 (and (eobp) (< number 0)
498 (forward-line -1)) 519 (forward-line -1))
499 (display-buffer rmail-buffer)) 520 (display-buffer rmail-buffer))
500 521
522 ;;; mbox: ready
501 (defun rmail-summary-next-msg (&optional number) 523 (defun rmail-summary-next-msg (&optional number)
502 "Display next non-deleted msg from rmail file. 524 "Display next non-deleted msg from rmail file.
503 With optional prefix argument NUMBER, moves forward this number of non-deleted 525 With optional prefix argument NUMBER, moves forward this number of non-deleted
504 messages, or backward if NUMBER is negative." 526 messages, or backward if NUMBER is negative."
505 (interactive "p") 527 (interactive "p")
506 (forward-line 0) 528 (let (msg)
507 (and (> number 0) (end-of-line)) 529 (with-current-buffer rmail-buffer
508 (let ((count (if (< number 0) (- number) number)) 530 (rmail-next-undeleted-message number)
509 (search (if (> number 0) 're-search-forward 're-search-backward)) 531 (setq msg rmail-current-message))
510 (non-del-msg-found nil)) 532 (rmail-summary-goto-msg msg)))
511 (while (and (> count 0) (setq non-del-msg-found 533
512 (or (funcall search "^....[^D]" nil t) 534 ;;; mbox: ready
513 non-del-msg-found)))
514 (setq count (1- count))))
515 (beginning-of-line)
516 (display-buffer rmail-view-buffer))
517
518 (defun rmail-summary-previous-msg (&optional number) 535 (defun rmail-summary-previous-msg (&optional number)
519 "Display previous non-deleted msg from rmail file.
520 With optional prefix argument NUMBER, moves backward this number of
521 non-deleted messages."
522 (interactive "p") 536 (interactive "p")
523 (rmail-summary-next-msg (- (if number number 1)))) 537 (rmail-summary-next-msg (- (if number number 1))))
524 538
525 (defun rmail-summary-next-labeled-message (n labels) 539 (defun rmail-summary-next-labeled-message (n labels)
526 "Show next message with LABELS. Defaults to last labels used. 540 "Show next message with LABEL. Defaults to last labels used.
527 With prefix argument N moves forward N messages with these labels." 541 With prefix argument N moves forward N messages with these labels."
528 (interactive "p\nsMove to next msg with labels: ") 542 (interactive "p\nsMove to next msg with labels: ")
529 (let (msg) 543 (let (msg)
530 (save-excursion 544 (save-excursion
531 (set-buffer rmail-buffer) 545 (set-buffer rmail-buffer)
532 (rmail-next-labeled-message n labels) 546 (rmail-next-labeled-message n labels)
533 (setq msg rmail-current-message)) 547 (setq msg rmail-current-message))
534 (rmail-summary-goto-msg msg))) 548 (setq rmail-current-message msg)))
535 549
536 (defun rmail-summary-previous-labeled-message (n labels) 550 (defun rmail-summary-previous-labeled-message (n labels)
537 "Show previous message with LABELS. Defaults to last labels used. 551 "Show previous message with LABEL. Defaults to last labels used.
538 With prefix argument N moves backward N messages with these labels." 552 With prefix argument N moves backward N messages with these labels."
539 (interactive "p\nsMove to previous msg with labels: ") 553 (interactive "p\nsMove to previous msg with labels: ")
540 (let (msg) 554 (let (msg)
541 (save-excursion 555 (save-excursion
542 (set-buffer rmail-buffer) 556 (set-buffer rmail-buffer)
543 (rmail-previous-labeled-message n labels) 557 (rmail-previous-labeled-message n labels)
544 (setq msg rmail-current-message)) 558 (setq msg rmail-current-message))
545 (rmail-summary-goto-msg msg))) 559 (setq rmail-current-message msg)))
546 560
561 ;;; mbox: ready
547 (defun rmail-summary-next-same-subject (n) 562 (defun rmail-summary-next-same-subject (n)
548 "Go to the next message in the summary having the same subject. 563 "Go to the next message in the summary having the same subject.
549 With prefix argument N, do this N times. 564 With prefix argument N, do this N times.
550 If N is negative, go backwards." 565 If N is negative, go backwards."
551 (interactive "p") 566 (interactive "p")
552 (let (subject search-regexp i found 567 (let (found)
553 (forward (> n 0))) 568 (with-current-buffer rmail-buffer
554 (save-excursion 569 (rmail-next-same-subject n)
555 (set-buffer rmail-buffer) 570 (setq found rmail-current-message))
556 (setq subject (mail-fetch-field "Subject")) 571
557 (setq i rmail-current-message))
558 (if (string-match "Re:[ \t]*" subject)
559 (setq subject (substring subject (match-end 0))))
560 (setq search-regexp (concat "^Subject: *\\(Re: *\\)?"
561 (regexp-quote subject)
562 "\n"))
563 (save-excursion
564 (while (and (/= n 0)
565 (if forward
566 (not (eobp))
567 (not (bobp))))
568 (let (done)
569 (while (and (not done)
570 (if forward
571 (not (eobp))
572 (not (bobp))))
573 ;; Advance thru summary.
574 (forward-line (if forward 1 -1))
575 ;; Get msg number of this line.
576 (setq i (string-to-int
577 (buffer-substring (point)
578 (min (point-max) (+ 6 (point))))))
579 ;; See if that msg has desired subject.
580 (save-excursion
581 (set-buffer rmail-buffer)
582 (save-restriction
583 (widen)
584 (goto-char (rmail-msgbeg i))
585 (search-forward "\n*** EOOH ***\n")
586 (let ((beg (point)) end)
587 (search-forward "\n\n")
588 (setq end (point))
589 (goto-char beg)
590 (setq done (re-search-forward search-regexp end t))))))
591 (if done (setq found i)))
592 (setq n (if forward (1- n) (1+ n)))))
593 (if found 572 (if found
594 (rmail-summary-goto-msg found) 573 (setq rmail-current-message found
595 (error "No %s message with same subject" 574 rmail-summary-skip-rmail t))))
596 (if forward "following" "previous"))))) 575
597 576 ;;; mbox: ready
598 (defun rmail-summary-previous-same-subject (n) 577 (defun rmail-summary-previous-same-subject (n)
599 "Go to the previous message in the summary having the same subject. 578 "Go to the previous message in the summary having the same subject.
600 With prefix argument N, do this N times. 579 With prefix argument N, do this N times.
601 If N is negative, go forwards instead." 580 If N is negative, go forwards instead."
602 (interactive "p") 581 (interactive "p")
603 (rmail-summary-next-same-subject (- n))) 582 (rmail-summary-next-same-subject (- n)))
604 583
605 ;; Delete and undelete summary commands. 584 ;; Delete and undelete summary commands.
606 585
586 ;;; mbox: ready
607 (defun rmail-summary-delete-forward (&optional count) 587 (defun rmail-summary-delete-forward (&optional count)
608 "Delete this message and move to next nondeleted one. 588 "Delete this message and move to next nondeleted one.
609 Deleted messages stay in the file until the \\[rmail-expunge] command is given. 589 Deleted messages stay in the file until the \\[rmail-expunge] command is given.
610 A prefix argument serves as a repeat count; 590 A prefix argument serves as a repeat count;
611 a negative argument means to delete and move backward." 591 a negative argument means to delete and move backward."
621 (rmail-summary-mark-deleted del-msg) 601 (rmail-summary-mark-deleted del-msg)
622 (while (and (not (if backward (bobp) (eobp))) 602 (while (and (not (if backward (bobp) (eobp)))
623 (save-excursion (beginning-of-line) 603 (save-excursion (beginning-of-line)
624 (looking-at " *[0-9]+D"))) 604 (looking-at " *[0-9]+D")))
625 (forward-line (if backward -1 1))) 605 (forward-line (if backward -1 1)))
626 ;; It looks ugly to move to the empty line at end of buffer.
627 (and (eobp) (not backward)
628 (forward-line -1))
629 (setq count 606 (setq count
630 (if (> count 0) (1- count) (1+ count)))))) 607 (if (> count 0) (1- count) (1+ count))))
608
609 ;; Update the summary buffer current message counter and show the
610 ;; message in the Rmail buffer.
611 (rmail-summary-goto-msg (rmail-summary-get-message-at-point))))
631 612
632 (defun rmail-summary-delete-backward (&optional count) 613 (defun rmail-summary-delete-backward (&optional count)
633 "Delete this message and move to previous nondeleted one. 614 "Delete this message and move to previous nondeleted one.
634 Deleted messages stay in the file until the \\[rmail-expunge] command is given. 615 Deleted messages stay in the file until the \\[rmail-expunge] command is given.
635 A prefix argument serves as a repeat count; 616 A prefix argument serves as a repeat count;
637 (interactive "p") 618 (interactive "p")
638 (rmail-summary-delete-forward (- count))) 619 (rmail-summary-delete-forward (- count)))
639 620
640 (defun rmail-summary-mark-deleted (&optional n undel) 621 (defun rmail-summary-mark-deleted (&optional n undel)
641 ;; Since third arg is t, this only alters the summary, not the Rmail buf. 622 ;; Since third arg is t, this only alters the summary, not the Rmail buf.
642 (and n (rmail-summary-goto-msg n t t)) 623 (and n (rmail-summary-goto-msg n t))
643 (or (eobp) 624 (or (eobp)
644 (not (overlay-get rmail-summary-overlay 'face)) 625 (not (overlay-get rmail-summary-overlay 'face))
645 (let ((buffer-read-only nil)) 626 (let ((buffer-read-only nil))
646 (skip-chars-forward " ") 627 (skip-chars-forward " ")
647 (skip-chars-forward "[0-9]") 628 (skip-chars-forward "[0-9]")
653 (beginning-of-line)) 634 (beginning-of-line))
654 635
655 (defun rmail-summary-mark-undeleted (n) 636 (defun rmail-summary-mark-undeleted (n)
656 (rmail-summary-mark-deleted n t)) 637 (rmail-summary-mark-deleted n t))
657 638
639 ;;; mbox: ready
658 (defun rmail-summary-deleted-p (&optional n) 640 (defun rmail-summary-deleted-p (&optional n)
659 (save-excursion 641 (unless n
660 (and n (rmail-summary-goto-msg n nil t)) 642 (setq n rmail-current-message)
661 (skip-chars-forward " ") 643 (with-current-buffer rmail-buffer
662 (skip-chars-forward "[0-9]") 644 (rmail-desc-deleted-p n))))
663 (looking-at "D"))) 645
664 646 ;;; mbox: not sure.
665 (defun rmail-summary-undelete (&optional arg) 647 (defun rmail-summary-undelete (&optional arg)
666 "Undelete current message. 648 "Undelete current message.
667 Optional prefix ARG means undelete ARG previous messages." 649 Optional prefix ARG means undelete ARG previous messages."
668 (interactive "p") 650 (interactive "p")
669 (if (/= arg 1) 651 (if (/= arg 1)
682 (if rmail-enable-mime 664 (if rmail-enable-mime
683 (pop-to-buffer rmail-view-buffer)) 665 (pop-to-buffer rmail-view-buffer))
684 (pop-to-buffer rmail-summary-buffer)) 666 (pop-to-buffer rmail-summary-buffer))
685 (t (goto-char opoint)))))) 667 (t (goto-char opoint))))))
686 668
669 ;;; mbox: ready for testing
687 (defun rmail-summary-undelete-many (&optional n) 670 (defun rmail-summary-undelete-many (&optional n)
688 "Undelete all deleted msgs, optional prefix arg N means undelete N prev msgs." 671 "Undelete all deleted msgs, optional prefix arg N means undelete N prev msgs."
689 (interactive "P") 672 (interactive "P")
690 (save-excursion 673 (save-excursion
691 (set-buffer rmail-buffer) 674 (set-buffer rmail-buffer)
704 (while (and (> rmail-current-message 0) 687 (while (and (> rmail-current-message 0)
705 (< msgs-undeled n)) 688 (< msgs-undeled n))
706 (if (rmail-summary-deleted-p rmail-current-message) 689 (if (rmail-summary-deleted-p rmail-current-message)
707 (progn (rmail-summary-mark-undeleted rmail-current-message) 690 (progn (rmail-summary-mark-undeleted rmail-current-message)
708 (setq msgs-undeled (1+ msgs-undeled)))) 691 (setq msgs-undeled (1+ msgs-undeled))))
709 (setq rmail-current-message (1- rmail-current-message)))) 692 (setq rmail-current-message (1- rmail-current-message))))))
710 (rmail-summary-goto-msg)))
711 693
712 ;; Rmail Summary mode is suitable only for specially formatted data. 694 ;; Rmail Summary mode is suitable only for specially formatted data.
713 (put 'rmail-summary-mode 'mode-class 'special) 695 (put 'rmail-summary-mode 'mode-class 'special)
714 696
715 (defun rmail-summary-mode () 697 (defun rmail-summary-mode ()
775 757
776 ;; Show in Rmail the message described by the summary line that point is on, 758 ;; Show in Rmail the message described by the summary line that point is on,
777 ;; but only if the Rmail buffer is already visible. 759 ;; but only if the Rmail buffer is already visible.
778 ;; This is a post-command-hook in summary buffers. 760 ;; This is a post-command-hook in summary buffers.
779 (defun rmail-summary-rmail-update () 761 (defun rmail-summary-rmail-update ()
780 (let (buffer-read-only) 762 "Update the Rmail summary buffer.
781 (save-excursion 763 Put the cursor on the beginning of the line containing the current
782 ;; If at end of buffer, pretend we are on the last text line. 764 message and highlight the buffer."
783 (if (eobp) 765
784 (forward-line -1)) 766 (let (buffer-read-only)
785 (beginning-of-line) 767 (save-excursion
786 (skip-chars-forward " ") 768 ;; If at end of buffer, pretend we are on the last text line.
787 (let ((msg-num (string-to-int (buffer-substring 769 (if (eobp)
788 (point) 770 (forward-line -1))
789 (progn (skip-chars-forward "0-9") 771
790 (point)))))) 772 ;; Determine the message number correpsonding to line point is on.
791 ;; Always leave `unseen' removed 773 (beginning-of-line)
792 ;; if we get out of isearch mode. 774 (skip-chars-forward " ")
793 ;; Don't let a subsequent isearch restore that `unseen'. 775 (let ((msg-num (string-to-int (buffer-substring
794 (if (not isearch-mode) 776 (point)
795 (setq rmail-summary-put-back-unseen nil)) 777 (progn (skip-chars-forward "0-9")
796 778 (point))))))
797 (or (eq rmail-current-message msg-num) 779
798 (let ((window (get-buffer-window rmail-view-buffer t)) 780 ;; Always leave `unseen' removed if we get out of isearch mode.
799 (owin (selected-window))) 781 ;; Don't let a subsequent isearch restore `unseen'.
800 (if isearch-mode 782 (if (not isearch-mode)
801 (save-excursion 783 (setq rmail-summary-put-back-unseen nil))
802 (set-buffer rmail-buffer) 784
803 ;; If we first saw the previous message in this search, 785 (or (eq rmail-current-message msg-num)
804 ;; and we have gone to a different message while searching, 786 (let ((window (get-buffer-window rmail-view-buffer t))
805 ;; put back `unseen' on the former one. 787 (owin (selected-window)))
806 (if rmail-summary-put-back-unseen 788 (if isearch-mode
807 (rmail-set-attribute "unseen" t 789 (save-excursion
808 rmail-current-message)) 790 (set-buffer rmail-buffer)
809 ;; Arrange to do that later, for the new current message, 791 ;; If we first saw the previous message in this search,
810 ;; if it still has `unseen'. 792 ;; and we have gone to a different message while searching,
811 (setq rmail-summary-put-back-unseen 793 ;; put back `unseen' on the former one.
812 (rmail-message-labels-p msg-num ", ?\\(unseen\\),"))) 794 (if rmail-summary-put-back-unseen
813 (setq rmail-summary-put-back-unseen nil)) 795 (rmail-set-attribute "unseen" t
814 796 rmail-current-message))
815 ;; Go to the desired message. 797 ;; Arrange to do that later, for the new current message,
816 (setq rmail-current-message msg-num) 798 ;; if it still has `unseen'.
817 799 (setq rmail-summary-put-back-unseen
818 ;; Update the summary to show the message has been seen. 800 (rmail-message-labels-p msg-num ", ?\\(unseen\\),")))
819 (if (= (following-char) ?-) 801 (setq rmail-summary-put-back-unseen nil))
820 (progn 802
821 (delete-char 1) 803 ;; Go to the desired message.
822 (insert " "))) 804 (setq rmail-current-message msg-num)
823 805
824 (if window 806 ;; Update the summary to show the message has been seen.
825 ;; Using save-window-excursion would cause the new value 807 (if (= (following-char) ?-)
826 ;; of point to get lost. 808 (progn
827 (unwind-protect 809 (delete-char 1)
828 (progn 810 (insert " ")))
829 (select-window window) 811
830 (rmail-show-message msg-num t)) 812 (if window
831 (select-window owin)) 813 ;; Using save-window-excursion would cause the new value
832 (if (buffer-name rmail-buffer) 814 ;; of point to get lost.
833 (save-excursion 815 (unwind-protect
834 (set-buffer rmail-buffer) 816 (progn
835 (rmail-show-message msg-num t)))))) 817 (select-window window)
836 (rmail-summary-update-highlight nil))))) 818 (rmail-show-message msg-num t))
819 (select-window owin))
820 (if (buffer-name rmail-buffer)
821 (save-excursion
822 (set-buffer rmail-buffer)
823 (rmail-show-message msg-num t))))))
824 (rmail-summary-update-highlight nil)))))
837 825
838 (defvar rmail-summary-mode-map nil)
839
840 (if rmail-summary-mode-map 826 (if rmail-summary-mode-map
841 nil 827 nil
842 (setq rmail-summary-mode-map (make-keymap)) 828 (setq rmail-summary-mode-map (make-keymap))
843 (suppress-keymap rmail-summary-mode-map) 829 (suppress-keymap rmail-summary-mode-map)
844 830
845 (define-key rmail-summary-mode-map [mouse-2] 'rmail-summary-mouse-goto-message) 831 (define-key rmail-summary-mode-map [mouse-2] 'rmail-summary-mouse-goto-message)
846 (define-key rmail-summary-mode-map "a" 'rmail-summary-add-label) 832 (define-key rmail-summary-mode-map "a" 'rmail-summary-add-label)
847 (define-key rmail-summary-mode-map "b" 'rmail-summary-bury) 833 (define-key rmail-summary-mode-map "b" 'rmail-summary-bury)
834 (define-key rmail-summary-mode-map "B" 'rmail-summary-browse-body)
848 (define-key rmail-summary-mode-map "c" 'rmail-summary-continue) 835 (define-key rmail-summary-mode-map "c" 'rmail-summary-continue)
849 (define-key rmail-summary-mode-map "d" 'rmail-summary-delete-forward) 836 (define-key rmail-summary-mode-map "d" 'rmail-summary-delete-forward)
850 (define-key rmail-summary-mode-map "\C-d" 'rmail-summary-delete-backward) 837 (define-key rmail-summary-mode-map "\C-d" 'rmail-summary-delete-backward)
851 (define-key rmail-summary-mode-map "e" 'rmail-summary-edit-current-message) 838 (define-key rmail-summary-mode-map "e" 'rmail-summary-edit-current-message)
852 (define-key rmail-summary-mode-map "f" 'rmail-summary-forward) 839 (define-key rmail-summary-mode-map "f" 'rmail-summary-forward)
865 (define-key rmail-summary-mode-map "m" 'rmail-summary-mail) 852 (define-key rmail-summary-mode-map "m" 'rmail-summary-mail)
866 (define-key rmail-summary-mode-map "\M-m" 'rmail-summary-retry-failure) 853 (define-key rmail-summary-mode-map "\M-m" 'rmail-summary-retry-failure)
867 (define-key rmail-summary-mode-map "n" 'rmail-summary-next-msg) 854 (define-key rmail-summary-mode-map "n" 'rmail-summary-next-msg)
868 (define-key rmail-summary-mode-map "\en" 'rmail-summary-next-all) 855 (define-key rmail-summary-mode-map "\en" 'rmail-summary-next-all)
869 (define-key rmail-summary-mode-map "\e\C-n" 'rmail-summary-next-labeled-message) 856 (define-key rmail-summary-mode-map "\e\C-n" 'rmail-summary-next-labeled-message)
870 (define-key rmail-summary-mode-map "o" 'rmail-summary-output-to-rmail-file) 857 (define-key rmail-summary-mode-map "o" 'rmail-summary-output)
871 (define-key rmail-summary-mode-map "\C-o" 'rmail-summary-output) 858 (define-key rmail-summary-mode-map "\C-o" 'rmail-summary-output)
872 (define-key rmail-summary-mode-map "p" 'rmail-summary-previous-msg) 859 (define-key rmail-summary-mode-map "p" 'rmail-summary-previous-msg)
873 (define-key rmail-summary-mode-map "\ep" 'rmail-summary-previous-all) 860 (define-key rmail-summary-mode-map "\ep" 'rmail-summary-previous-all)
874 (define-key rmail-summary-mode-map "\e\C-p" 'rmail-summary-previous-labeled-message) 861 (define-key rmail-summary-mode-map "\e\C-p" 'rmail-summary-previous-labeled-message)
875 (define-key rmail-summary-mode-map "q" 'rmail-summary-quit) 862 (define-key rmail-summary-mode-map "q" 'rmail-summary-quit)
930 917
931 (define-key rmail-summary-mode-map [menu-bar classify output-inbox] 918 (define-key rmail-summary-mode-map [menu-bar classify output-inbox]
932 '("Output (inbox)..." . rmail-summary-output)) 919 '("Output (inbox)..." . rmail-summary-output))
933 920
934 (define-key rmail-summary-mode-map [menu-bar classify output] 921 (define-key rmail-summary-mode-map [menu-bar classify output]
935 '("Output (Rmail)..." . rmail-summary-output-to-rmail-file)) 922 '("Output (Rmail)..." . rmail-summary-output))
936 923
937 (define-key rmail-summary-mode-map [menu-bar classify kill-label] 924 (define-key rmail-summary-mode-map [menu-bar classify kill-label]
938 '("Kill Label..." . rmail-summary-kill-label)) 925 '("Kill Label..." . rmail-summary-kill-label))
939 926
940 (define-key rmail-summary-mode-map [menu-bar classify add-label] 927 (define-key rmail-summary-mode-map [menu-bar classify add-label]
1028 '("Previous" . rmail-summary-previous-all)) 1015 '("Previous" . rmail-summary-previous-all))
1029 1016
1030 (define-key rmail-summary-mode-map [menu-bar move next] 1017 (define-key rmail-summary-mode-map [menu-bar move next]
1031 '("Next" . rmail-summary-next-all)) 1018 '("Next" . rmail-summary-next-all))
1032 1019
1033 (defvar rmail-summary-overlay nil)
1034 (put 'rmail-summary-overlay 'permanent-local t)
1035
1036 (defun rmail-summary-mouse-goto-message (event) 1020 (defun rmail-summary-mouse-goto-message (event)
1037 "Select the message whose summary line you click on." 1021 "Select the message whose summary line you click on."
1038 (interactive "@e") 1022 (interactive "@e")
1039 (goto-char (posn-point (event-end event))) 1023 (goto-char (posn-point (event-end event)))
1040 (rmail-summary-goto-msg)) 1024 (setq rmail-current-message (rmail-summary-get-message-at-point))
1041 1025 (rmail-summary-rmail-update))
1026
1027 (defun rmail-summary-get-message-at-point ()
1028 "Return the message number corresponding to the line containing point.
1029 If the summary buffer contains no messages, nil is returned."
1030 (save-excursion
1031
1032 ;; Position point at the beginning of a line.
1033 (if (eobp)
1034 (forward-line -1)
1035 (forward-line 0))
1036
1037 ;; Parse the message number.
1038 (string-to-int
1039 (buffer-substring (point) (min (point-max) (+ 4 (point)))))))
1040
1042 (defun rmail-summary-goto-msg (&optional n nowarn skip-rmail) 1041 (defun rmail-summary-goto-msg (&optional n nowarn skip-rmail)
1043 "Go to message N in the summary buffer and the Rmail buffer. 1042 "Go to message N in the summary buffer and the Rmail buffer.
1044 If N is nil, use the message corresponding to point in the summary 1043 If N is nil, use the message corresponding to point in the summary
1045 and move to that message in the Rmail buffer. 1044 buffer and move to that message in the Rmail buffer.
1046 1045
1047 If NOWARN, don't say anything if N is out of range. 1046 If NOWARN, don't say anything if N is out of range.
1048 If SKIP-RMAIL, don't do anything to the Rmail buffer." 1047 If SKIP-RMAIL, don't do anything to the Rmail buffer."
1049 (interactive "P") 1048 (interactive "P")
1050 (if (consp n) (setq n (prefix-numeric-value n))) 1049 (if (consp n) (setq n (prefix-numeric-value n)))
1050
1051 ;; Do the end of buffer adjustment.
1051 (if (eobp) (forward-line -1)) 1052 (if (eobp) (forward-line -1))
1052 (beginning-of-line) 1053 (beginning-of-line)
1053 (let* ((obuf (current-buffer)) 1054
1054 (buf rmail-buffer) 1055 ;; Set N to the current message unless it was already set by the
1055 (cur (point)) 1056 ;; caller.
1056 message-not-found 1057 (unless n
1057 (curmsg (string-to-int 1058 (setq n (rmail-summary-get-message-at-point)))
1058 (buffer-substring (point) 1059
1059 (min (point-max) (+ 6 (point)))))) 1060 (let* ((obuf (current-buffer))
1060 (total (save-excursion (set-buffer buf) rmail-total-messages))) 1061 (buf rmail-buffer)
1061 ;; If message number N was specified, find that message's line 1062 (cur (point))
1062 ;; or set message-not-found. 1063 message-not-found
1063 ;; If N wasn't specified or that message can't be found. 1064 (curmsg (string-to-int
1064 ;; set N by default. 1065 (buffer-substring (point)
1065 (if (not n) 1066 (min (point-max) (+ 6 (point))))))
1066 (setq n curmsg) 1067 (total (save-excursion (set-buffer buf) rmail-total-messages)))
1068
1069 ;; Do a validity check on N. If it is valid then set the current
1070 ;; summary message to N. `rmail-summary-rmail-update' will then
1071 ;; actually move point to the selected message.
1067 (if (< n 1) 1072 (if (< n 1)
1068 (progn (message "No preceding message") 1073 (progn (message "No preceding message")
1069 (setq n 1))) 1074 (setq n 1)))
1070 (if (> n total) 1075 (if (> n total)
1071 (progn (message "No following message") 1076 (progn (message "No following message")
1072 (goto-char (point-max)) 1077 (goto-char (point-max))
1073 (rmail-summary-goto-msg nil nowarn skip-rmail))) 1078 (rmail-summary-goto-msg nil nowarn skip-rmail)))
1074 (goto-char (point-min)) 1079 (goto-char (point-min))
1075 (if (not (re-search-forward (format "^%5d[^0-9]" n) nil t)) 1080 (if (not (re-search-forward (format "^%4d[^0-9]" n) nil t))
1076 (progn (or nowarn (message "Message %d not found" n)) 1081 (progn (or nowarn (message "Message %d not found" n))
1077 (setq n curmsg) 1082 (setq n curmsg)
1078 (setq message-not-found t) 1083 (setq message-not-found t)
1079 (goto-char cur)))) 1084 (goto-char cur)))
1080 (beginning-of-line) 1085 (beginning-of-line)
1081 (skip-chars-forward " ") 1086 (skip-chars-forward " ")
1082 (skip-chars-forward "0-9") 1087 (skip-chars-forward "0-9")
1083 (save-excursion (if (= (following-char) ?-) 1088 (save-excursion (if (= (following-char) ?-)
1084 (let ((buffer-read-only nil)) 1089 (let ((buffer-read-only nil))
1085 (delete-char 1) 1090 (delete-char 1)
1086 (insert " ")))) 1091 (insert " "))))
1087 (rmail-summary-update-highlight message-not-found) 1092 (rmail-summary-update-highlight message-not-found)
1088 (beginning-of-line) 1093 (beginning-of-line)
1089 (if skip-rmail 1094
1090 nil 1095 ;; Determine if the Rmail buffer needs to be processed.
1091 (let ((selwin (selected-window))) 1096 (if skip-rmail
1092 (unwind-protect 1097 nil
1093 (progn (pop-to-buffer buf) 1098
1094 (rmail-show-message n)) 1099 ;; It does.
1095 (select-window selwin) 1100 (let ((selwin (selected-window)))
1096 ;; The actions above can alter the current buffer. Preserve it. 1101 (unwind-protect
1097 (set-buffer obuf)))))) 1102 (progn (pop-to-buffer buf)
1103 (rmail-show-message n))
1104 (select-window selwin)
1105 ;; The actions above can alter the current buffer. Preserve it.
1106 (set-buffer obuf))))))
1098 1107
1099 ;; Update the highlighted line in an rmail summary buffer. 1108 ;; Update the highlighted line in an rmail summary buffer.
1100 ;; That should be current. We highlight the line point is on. 1109 ;; That should be current. We highlight the line point is on.
1101 ;; If NOT-FOUND is non-nil, we turn off highlighting. 1110 ;; If NOT-FOUND is non-nil, we turn off highlighting.
1102 (defun rmail-summary-update-highlight (not-found) 1111 (defun rmail-summary-update-highlight (not-found)
1213 (if (not (eq (selected-window) (next-window nil 'no-minibuf))) 1222 (if (not (eq (selected-window) (next-window nil 'no-minibuf)))
1214 (delete-window)) 1223 (delete-window))
1215 ;; Switch windows to the rmail buffer, or switch to it in this window. 1224 ;; Switch windows to the rmail buffer, or switch to it in this window.
1216 (pop-to-buffer local-rmail-buffer))) 1225 (pop-to-buffer local-rmail-buffer)))
1217 1226
1227 ;;; mbox: ready
1218 (defun rmail-summary-expunge () 1228 (defun rmail-summary-expunge ()
1219 "Actually erase all deleted messages and recompute summary headers." 1229 "Actually erase all deleted messages and recompute summary headers."
1220 (interactive) 1230 (interactive)
1221 (save-excursion 1231 (set-buffer rmail-buffer)
1222 (set-buffer rmail-buffer) 1232 (rmail-expunge)
1223 (when (rmail-expunge-confirmed) 1233 (set-buffer rmail-summary-buffer))
1224 (rmail-only-expunge))) 1234
1225 (rmail-update-summary)) 1235 ;;; mbox: ready
1226
1227 (defun rmail-summary-expunge-and-save () 1236 (defun rmail-summary-expunge-and-save ()
1228 "Expunge and save RMAIL file." 1237 "Expunge and save RMAIL file."
1229 (interactive) 1238 (interactive)
1230 (save-excursion 1239 (set-buffer rmail-buffer)
1231 (set-buffer rmail-buffer) 1240 (rmail-expunge)
1232 (when (rmail-expunge-confirmed) 1241 (save-buffer)
1233 (rmail-only-expunge))) 1242 (set-buffer rmail-summary-buffer)
1234 (rmail-update-summary)
1235 (save-excursion
1236 (set-buffer rmail-buffer)
1237 (save-buffer))
1238 (set-buffer-modified-p nil)) 1243 (set-buffer-modified-p nil))
1239 1244
1245 ;;; mbox: ready
1240 (defun rmail-summary-get-new-mail (&optional file-name) 1246 (defun rmail-summary-get-new-mail (&optional file-name)
1241 "Get new mail and recompute summary headers. 1247 "Get new mail and recompute summary headers.
1242 1248
1243 Optionally you can specify the file to get new mail from. In this case, 1249 Optionally you can specify the file to get new mail from. In this case,
1244 the file of new mail is not changed or deleted. Noninteractively, you can 1250 the file of new mail is not changed or deleted. Noninteractively, you can
1245 pass the inbox file name as an argument. Interactively, a prefix 1251 pass the inbox file name as an argument. Interactively, a prefix
1246 argument says to read a file name and use that file as the inbox." 1252 argument says to read a file name and use that file as the inbox."
1247 (interactive 1253 (interactive
1248 (list (if current-prefix-arg 1254 (list (if current-prefix-arg
1249 (read-file-name "Get new mail from file: ")))) 1255 (read-file-name "Get new mail from file: "))))
1250 (let (msg) 1256 (let (current-message)
1251 (save-excursion 1257 (with-current-buffer rmail-buffer
1252 (set-buffer rmail-buffer)
1253 (rmail-get-new-mail file-name) 1258 (rmail-get-new-mail file-name)
1254 ;; Get the proper new message number. 1259 (setq current-message rmail-current-message))
1255 (setq msg rmail-current-message)) 1260 (rmail-summary-goto-msg current-message nil t)))
1256 ;; Make sure that message is displayed.
1257 (or (zerop msg)
1258 (rmail-summary-goto-msg msg))))
1259 1261
1260 (defun rmail-summary-input (filename) 1262 (defun rmail-summary-input (filename)
1261 "Run Rmail on file FILENAME." 1263 "Run Rmail on file FILENAME."
1262 (interactive "FRun rmail on RMAIL file: ") 1264 (interactive "FRun rmail on RMAIL file: ")
1263 ;; We switch windows here, then display the other Rmail file there. 1265 ;; We switch windows here, then display the other Rmail file there.
1363 (progn 1365 (progn
1364 (set-buffer rmail-buffer) 1366 (set-buffer rmail-buffer)
1365 (rmail-search regexp n)) 1367 (rmail-search regexp n))
1366 (set-buffer buffer)))) 1368 (set-buffer buffer))))
1367 1369
1370 ;;; mbox: ready
1368 (defun rmail-summary-toggle-header () 1371 (defun rmail-summary-toggle-header ()
1369 "Show original message header if pruned header currently shown, or vice versa." 1372 "Show original message header if pruned header currently shown, or vice versa."
1370 (interactive) 1373 (interactive)
1371 (save-window-excursion 1374 (save-excursion
1372 (set-buffer rmail-buffer) 1375 (set-buffer rmail-buffer)
1373 (rmail-toggle-header)) 1376 (rmail-toggle-header)))
1374 ;; Inside save-excursion, some changes to point in the RMAIL buffer are lost. 1377
1375 ;; Set point to point-min in the RMAIL buffer, if it is visible. 1378 ;;; mbox: ready
1376 (let ((window (get-buffer-window rmail-view-buffer)))
1377 (if window
1378 ;; Using save-window-excursion would lose the new value of point.
1379 (let ((owin (selected-window)))
1380 (unwind-protect
1381 (progn
1382 (select-window window)
1383 (goto-char (point-min)))
1384 (select-window owin))))))
1385
1386
1387 (defun rmail-summary-add-label (label) 1379 (defun rmail-summary-add-label (label)
1388 "Add LABEL to labels associated with current Rmail message. 1380 "Add LABEL to labels associated with current Rmail message.
1389 Completion is performed over known labels when reading." 1381 Completion is performed over known labels when reading."
1390 (interactive (list (save-excursion 1382 (interactive (list (save-excursion
1391 (set-buffer rmail-buffer) 1383 (set-buffer rmail-buffer)
1405 (rmail-set-label label nil))) 1397 (rmail-set-label label nil)))
1406 1398
1407 ;;;; *** Rmail Summary Mailing Commands *** 1399 ;;;; *** Rmail Summary Mailing Commands ***
1408 1400
1409 (defun rmail-summary-override-mail-send-and-exit () 1401 (defun rmail-summary-override-mail-send-and-exit ()
1410 "Replace bindings to `mail-send-and-exit' with `rmail-summary-send-and-exit'." 1402 "Replace bindings to 'mail-send-and-exit with 'rmail-summary-send-and-exit"
1411 (use-local-map (copy-keymap (current-local-map))) 1403 (use-local-map (copy-keymap (current-local-map)))
1412 (dolist (key (where-is-internal 'mail-send-and-exit)) 1404 (dolist (key (where-is-internal 'mail-send-and-exit))
1413 (define-key (current-local-map) key 'rmail-summary-send-and-exit))) 1405 (define-key (current-local-map) key 'rmail-summary-send-and-exit)))
1414 1406
1415 (defun rmail-summary-mail () 1407 (defun rmail-summary-mail ()
1431 (if window 1423 (if window
1432 (select-window window) 1424 (select-window window)
1433 (set-buffer rmail-buffer))) 1425 (set-buffer rmail-buffer)))
1434 (rmail-start-mail t)) 1426 (rmail-start-mail t))
1435 1427
1428 ;;; mbox: ready
1436 (defun rmail-summary-reply (just-sender) 1429 (defun rmail-summary-reply (just-sender)
1437 "Reply to the current message. 1430 "Reply to the current message.
1438 Normally include CC: to all other recipients of original message; 1431 Normally include CC: to all other recipients of original message;
1439 prefix argument means ignore them. While composing the reply, 1432 prefix argument means ignore them. While composing the reply,
1440 use \\[mail-yank-original] to yank the original message into it." 1433 use \\[mail-yank-original] to yank the original message into it."
1484 (if window 1477 (if window
1485 (select-window window) 1478 (select-window window)
1486 (set-buffer rmail-buffer))) 1479 (set-buffer rmail-buffer)))
1487 (call-interactively 'rmail-resend))) 1480 (call-interactively 'rmail-resend)))
1488 1481
1489 ;; Summary output commands. 1482 ;;;; Summary output commands.
1490 1483
1484 ;;; mbox: ready for testing
1491 (defun rmail-summary-output-to-rmail-file (&optional file-name n) 1485 (defun rmail-summary-output-to-rmail-file (&optional file-name n)
1492 "Append the current message to an Rmail file named FILE-NAME. 1486 "Append the current message to an Rmail file named FILE-NAME.
1493 If the file does not exist, ask if it should be created. 1487 If the file does not exist, ask if it should be created.
1494 If file is being visited, the message is appended to the Emacs 1488 If file is being visited, the message is appended to the Emacs
1495 buffer visiting that file. 1489 buffer visiting that file.
1515 (if rmail-delete-after-output 1509 (if rmail-delete-after-output
1516 (rmail-summary-delete-forward nil) 1510 (rmail-summary-delete-forward nil)
1517 (if (< i n) 1511 (if (< i n)
1518 (rmail-summary-next-msg 1)))))) 1512 (rmail-summary-next-msg 1))))))
1519 1513
1514 ;;; mbox: ready
1520 (defun rmail-summary-output (&optional file-name n) 1515 (defun rmail-summary-output (&optional file-name n)
1521 "Append this message to Unix mail file named FILE-NAME. 1516 "Append this message to Unix mail file named FILE-NAME.
1522 1517
1523 A prefix argument N says to output N consecutive messages 1518 A prefix argument N says to output N consecutive messages
1524 starting with the current one. Deleted messages are skipped and don't count." 1519 starting with the current one. Deleted messages are skipped and don't count."
1643 (unwind-protect 1638 (unwind-protect
1644 (progn (pop-to-buffer rmail-buffer) 1639 (progn (pop-to-buffer rmail-buffer)
1645 (funcall sortfun reverse)) 1640 (funcall sortfun reverse))
1646 (select-window selwin)))) 1641 (select-window selwin))))
1647 1642
1643 (defun rmail-summary-get-line-count (n)
1644 "Return a string containing the count of lines in message N for the
1645 summary buffer if the User has enabled line counts, otherwise return
1646 an empty string."
1647 (if rmail-summary-line-count-flag
1648 (format "[%s]" (rmail-desc-get-line-count n))
1649 ""))
1650
1651 (defun rmail-summary-get-summary-attributes (n)
1652 "Return the attribute character codes to use in the summary buffer
1653 for message N: `-' for an unseen message, `D' for a message marked
1654 for deletion."
1655 (format "%s%s%s%s%s"
1656 (cond ((rmail-desc-attr-p rmail-desc-unseen-index n) "-")
1657 ((rmail-desc-attr-p rmail-desc-deleted-index n) "D")
1658 (t " "))
1659 (or (rmail-desc-get-attr-code rmail-desc-answered-index n) " ")
1660 (or (rmail-desc-get-attr-code rmail-desc-filed-index n) " ")
1661 (or (rmail-desc-get-attr-code rmail-desc-edited-index n) " ")
1662 (or (rmail-desc-get-attr-code rmail-desc-stored-index n) " ")))
1663
1664 (defun rmail-summary-get-summary (n)
1665 "Return a summary line for message N."
1666 (format "%4s%s%6s %25s %s %s\n"
1667 n
1668 (rmail-summary-get-summary-attributes n)
1669 (concat (rmail-desc-get-day-number n) "-"
1670 (rmail-desc-get-month n))
1671 (rmail-desc-get-sender n)
1672 (rmail-summary-get-line-count n)
1673 (rmail-desc-get-subject n)))
1674
1675 (defun rmail-summary-update-attribute (attr-index n)
1676 "Update the attribute denoted by ATTR-INDEX in message N."
1677 (save-excursion
1678 (let (offset)
1679
1680 ;; Position point at the beginning of the attributes.
1681 (rmail-summary-goto-msg n)
1682 (skip-chars-forward " ")
1683 (skip-chars-forward "0-9")
1684
1685 ;; Determine if the attribute is represented on the summary
1686 ;; line.
1687 (setq offset (rmail-desc-get-summary-offset attr-index))
1688 (if offset
1689
1690 ;; It is. If necessary, replace the character code
1691 ;; corresponding to ATTR-INDEX.
1692 (let ((char (rmail-desc-get-attr-code attr-index n))
1693 (buffer-read-only nil))
1694 (goto-char (+ (point) offset))
1695 (unless (looking-at char)
1696 (delete-char 1)
1697 (insert char)))))))
1698
1699 ;;;; Browser related functions.
1700
1701 (defun rmail-summary-browse-body ()
1702 "Send the message body to the browser."
1703 (interactive)
1704 (save-excursion
1705 (set-buffer rmail-buffer)
1706 (rmail-browse-body)))
1707
1648 (provide 'rmailsum) 1708 (provide 'rmailsum)
1649 1709
1650 ;;; rmailsum.el ends here 1710 ;;; rmailsum.el ends here