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