0
|
1 ;;; rmailsum.el --- make summary buffers for the mail reader
|
|
2
|
|
3 ;; Copyright (C) 1985, 1993 Free Software Foundation, Inc.
|
|
4
|
|
5 ;; Maintainer: FSF
|
|
6 ;; Keywords: mail
|
|
7
|
|
8 ;; This file is part of XEmacs.
|
|
9
|
|
10 ;; XEmacs is free software; you can redistribute it and/or modify it
|
|
11 ;; under the terms of the GNU General Public License as published by
|
|
12 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
13 ;; any later version.
|
|
14
|
|
15 ;; XEmacs is distributed in the hope that it will be useful, but
|
|
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
18 ;; General Public License for more details.
|
|
19
|
|
20 ;; You should have received a copy of the GNU General Public License
|
|
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
|
|
22 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
23
|
|
24 ;;; Commentary:
|
|
25
|
|
26 ;; Extended by Bob Weiner of Motorola
|
|
27 ;; Provided all commands from rmail-mode in rmail-summary-mode and made key
|
|
28 ;; bindings in both modes wholly compatible.
|
|
29
|
|
30 ;;; Code:
|
|
31
|
|
32 ;; Entry points for making a summary buffer.
|
|
33
|
|
34 (defvar rmail-summary-redo)
|
|
35 (defvar rmail-buffer)
|
|
36 (defvar rmail-summary-mode-map nil)
|
|
37
|
|
38 ;; Regenerate the contents of the summary
|
|
39 ;; using the same selection criterion as last time.
|
|
40 ;; M-x revert-buffer in a summary buffer calls this function.
|
|
41 (defun rmail-update-summary (&rest ignore)
|
|
42 (apply (car rmail-summary-redo) (cdr rmail-summary-redo)))
|
|
43
|
|
44 (defun rmail-summary ()
|
|
45 "Display a summary of all messages, one line per message."
|
|
46 (interactive)
|
|
47 (rmail-new-summary "All" '(rmail-summary) nil))
|
|
48
|
|
49 (defun rmail-summary-by-labels (labels)
|
|
50 "Display a summary of all messages with one or more LABELS.
|
|
51 LABELS should be a string containing the desired labels, separated by commas."
|
|
52 (interactive "sLabels to summarize by: ")
|
|
53 (if (string= labels "")
|
|
54 (setq labels (or rmail-last-multi-labels
|
|
55 (error "No label specified"))))
|
|
56 (setq rmail-last-multi-labels labels)
|
|
57 (rmail-new-summary (concat "labels " labels)
|
|
58 (list 'rmail-summary-by-labels labels)
|
|
59 'rmail-message-labels-p
|
|
60 (concat ", \\(" (mail-comma-list-regexp labels) "\\),")))
|
|
61
|
|
62 (defun rmail-summary-by-recipients (recipients &optional primary-only)
|
|
63 "Display a summary of all messages with the given RECIPIENTS.
|
|
64 Normally checks the To, From and Cc fields of headers;
|
|
65 but if PRIMARY-ONLY is non-nil (prefix arg given),
|
|
66 only look in the To and From fields.
|
|
67 RECIPIENTS is a string of regexps separated by commas."
|
|
68 (interactive "sRecipients to summarize by: \nP")
|
|
69 (rmail-new-summary
|
|
70 (concat "recipients " recipients)
|
|
71 (list 'rmail-summary-by-recipients recipients primary-only)
|
|
72 'rmail-message-recipients-p
|
|
73 (mail-comma-list-regexp recipients) primary-only))
|
|
74
|
|
75 (defun rmail-summary-by-regexp (regexp)
|
|
76 "Display a summary of all messages according to regexp REGEXP.
|
|
77 If the regular expression is found in the header of the message
|
|
78 \(including in the date and other lines, as well as the subject line),
|
|
79 Emacs will list the header line in the RMAIL-summary."
|
|
80 (interactive "sRegexp to summarize by: ")
|
|
81 (if (string= regexp "")
|
|
82 (setq regexp (or rmail-last-regexp
|
|
83 (error "No regexp specified."))))
|
|
84 (setq rmail-last-regexp regexp)
|
|
85 (rmail-new-summary (concat "regexp " regexp)
|
|
86 (list 'rmail-summary-by-regexp regexp)
|
|
87 'rmail-message-regexp-p
|
|
88 regexp))
|
|
89
|
|
90 ;; rmail-summary-by-topic
|
|
91 ;; 1989 R.A. Schnitzler
|
|
92
|
|
93 (defun rmail-summary-by-topic (subject &optional whole-message)
|
|
94 "Display a summary of all messages with the given SUBJECT.
|
|
95 Normally checks the Subject field of headers;
|
|
96 but if WHOLE-MESSAGE is non-nil (prefix arg given),
|
|
97 look in the whole message.
|
|
98 SUBJECT is a string of regexps separated by commas."
|
|
99 (interactive "sTopics to summarize by: \nP")
|
|
100 (rmail-new-summary
|
|
101 (concat "about " subject)
|
|
102 (list 'rmail-summary-by-topic subject whole-message)
|
|
103 'rmail-message-subject-p
|
|
104 (mail-comma-list-regexp subject) whole-message))
|
|
105
|
|
106 (defun rmail-message-subject-p (msg subject &optional whole-message)
|
|
107 (save-restriction
|
|
108 (goto-char (rmail-msgbeg msg))
|
|
109 (search-forward "\n*** EOOH ***\n")
|
|
110 (narrow-to-region
|
|
111 (point)
|
|
112 (progn (search-forward (if whole-message "\^_" "\n\n")) (point)))
|
|
113 (goto-char (point-min))
|
|
114 (if whole-message (re-search-forward subject nil t)
|
|
115 (string-match subject (or (mail-fetch-field "Subject") "")) )))
|
|
116
|
|
117 (defun rmail-summary-by-senders (senders)
|
|
118 "Display a summary of all messages with the given SENDERS.
|
|
119 SENDERS is a string of names separated by commas."
|
|
120 (interactive "sSenders to summarize by: ")
|
|
121 (rmail-new-summary
|
|
122 (concat "senders " senders)
|
|
123 'rmail-message-senders-p
|
|
124 (mail-comma-list-regexp senders)))
|
|
125
|
|
126 (defun rmail-message-senders-p (msg senders)
|
|
127 (save-restriction
|
|
128 (goto-char (rmail-msgbeg msg))
|
|
129 (search-forward "\n*** EOOH ***\n")
|
|
130 (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
|
|
131 (string-match senders (or (mail-fetch-field "From") ""))))
|
|
132
|
|
133 ;; General making of a summary buffer.
|
|
134
|
|
135 (defvar rmail-summary-symbol-number 0)
|
|
136
|
|
137 (defun rmail-new-summary (description redo-form function &rest args)
|
|
138 "Create a summary of selected messages.
|
|
139 DESCRIPTION makes part of the mode line of the summary buffer.
|
|
140 For each message, FUNCTION is applied to the message number and ARGS...
|
|
141 and if the result is non-nil, that message is included.
|
|
142 nil for FUNCTION means all messages."
|
|
143 (message "Computing summary lines...")
|
|
144 (let (sumbuf mesg was-in-summary)
|
|
145 (save-excursion
|
|
146 ;; Go to the Rmail buffer.
|
|
147 (if (eq major-mode 'rmail-summary-mode)
|
|
148 (progn
|
|
149 (setq was-in-summary t)
|
|
150 (set-buffer rmail-buffer)))
|
|
151 ;; Find its summary buffer, or make one.
|
|
152 (setq sumbuf
|
|
153 (if (and rmail-summary-buffer
|
|
154 (buffer-name rmail-summary-buffer))
|
|
155 rmail-summary-buffer
|
|
156 (generate-new-buffer (concat (buffer-name) "-summary"))))
|
|
157 (setq mesg rmail-current-message)
|
|
158 ;; Filter the messages; make or get their summary lines.
|
|
159 (let ((summary-msgs ())
|
|
160 (new-summary-line-count 0))
|
|
161 (let ((msgnum 1)
|
|
162 (buffer-read-only nil))
|
|
163 (save-restriction
|
|
164 (save-excursion
|
|
165 (widen)
|
|
166 (goto-char (point-min))
|
|
167 (while (>= rmail-total-messages msgnum)
|
|
168 (if (or (null function)
|
|
169 (apply function (cons msgnum args)))
|
|
170 (setq summary-msgs
|
|
171 (cons (cons msgnum (rmail-make-summary-line msgnum))
|
|
172 summary-msgs)))
|
|
173 (setq msgnum (1+ msgnum)))
|
|
174 (setq summary-msgs (nreverse summary-msgs)))))
|
|
175 ;; Temporarily, while summary buffer is unfinished,
|
|
176 ;; we "don't have" a summary.
|
|
177 (setq rmail-summary-buffer nil)
|
|
178 (save-excursion
|
|
179 (let ((rbuf (current-buffer))
|
|
180 (total rmail-total-messages))
|
|
181 (set-buffer sumbuf)
|
|
182 ;; Set up the summary buffer's contents.
|
|
183 (let ((buffer-read-only nil))
|
|
184 (erase-buffer)
|
|
185 (while summary-msgs
|
|
186 (princ (cdr (car summary-msgs)) sumbuf)
|
|
187 (setq summary-msgs (cdr summary-msgs)))
|
|
188 (goto-char (point-min)))
|
|
189 ;; Set up the rest of its state and local variables.
|
|
190 (setq buffer-read-only t)
|
|
191 (rmail-summary-mode)
|
|
192 (make-local-variable 'minor-mode-alist)
|
|
193 (setq minor-mode-alist (list '(t (concat ": " description))))
|
|
194 (setq rmail-buffer rbuf
|
|
195 rmail-summary-redo redo-form
|
|
196 rmail-total-messages total))))
|
|
197 (setq rmail-summary-buffer sumbuf))
|
|
198 ;; Now display the summary buffer and go to the right place in it.
|
|
199 (or was-in-summary
|
|
200 (pop-to-buffer sumbuf))
|
|
201 (rmail-summary-goto-msg mesg t t)
|
|
202 (message "Computing summary lines...done")))
|
|
203
|
|
204 ;; Low levels of generating a summary.
|
|
205
|
|
206 (defun rmail-make-summary-line (msg)
|
|
207 (let ((line (or (aref rmail-summary-vector (1- msg))
|
|
208 (progn
|
|
209 (setq new-summary-line-count
|
|
210 (1+ new-summary-line-count))
|
|
211 (if (zerop (% new-summary-line-count 10))
|
|
212 (message "Computing summary lines...%d"
|
|
213 new-summary-line-count))
|
|
214 (rmail-make-summary-line-1 msg)))))
|
|
215 ;; Fix up the part of the summary that says "deleted" or "unseen".
|
|
216 (aset line 4
|
|
217 (if (rmail-message-deleted-p msg) ?\D
|
|
218 (if (= ?0 (char-after (+ 3 (rmail-msgbeg msg))))
|
|
219 ?\- ?\ )))
|
|
220 line))
|
|
221
|
|
222 (defun rmail-make-summary-line-1 (msg)
|
|
223 (goto-char (rmail-msgbeg msg))
|
|
224 (let* (;;(lim (save-excursion (forward-line 2) (point)))
|
|
225 pos
|
|
226 (labels
|
|
227 (progn
|
|
228 (forward-char 3)
|
|
229 (concat
|
|
230 ; (if (save-excursion (re-search-forward ",answered," lim t))
|
|
231 ; "*" "")
|
|
232 ; (if (save-excursion (re-search-forward ",filed," lim t))
|
|
233 ; "!" "")
|
|
234 (if (progn (search-forward ",,") (eolp))
|
|
235 ""
|
|
236 (concat "{"
|
|
237 (buffer-substring (point)
|
|
238 (progn (end-of-line) (point)))
|
|
239 "} ")))))
|
|
240 (line
|
|
241 (progn
|
|
242 (forward-line 1)
|
|
243 (if (looking-at "Summary-line: ")
|
|
244 (progn
|
|
245 (goto-char (match-end 0))
|
|
246 (progn ;;setq line -jwz
|
|
247 (buffer-substring (point)
|
|
248 (progn (forward-line 1) (point)))))))))
|
|
249 ;; Obsolete status lines lacking a # should be flushed.
|
|
250 (and line
|
|
251 (not (string-match "#" line))
|
|
252 (progn
|
|
253 (delete-region (point)
|
|
254 (progn (forward-line -1) (point)))
|
|
255 (setq line nil)))
|
|
256 ;; If we didn't get a valid status line from the message,
|
|
257 ;; make a new one and put it in the message.
|
|
258 (or line
|
|
259 (let* ((case-fold-search t)
|
|
260 (next (rmail-msgend msg))
|
|
261 (beg (if (progn (goto-char (rmail-msgbeg msg))
|
|
262 (search-forward "\n*** EOOH ***\n" next t))
|
|
263 (point)
|
|
264 (forward-line 1)
|
|
265 (point)))
|
|
266 (end (progn (search-forward "\n\n" nil t) (point))))
|
|
267 (save-restriction
|
|
268 (narrow-to-region beg end)
|
|
269 (goto-char beg)
|
|
270 (setq line (rmail-make-basic-summary-line)))
|
|
271 (goto-char (rmail-msgbeg msg))
|
|
272 (forward-line 2)
|
|
273 (insert "Summary-line: " line)))
|
|
274 (setq pos (string-match "#" line))
|
|
275 (aset rmail-summary-vector (1- msg)
|
|
276 (concat (format "%4d " msg)
|
|
277 (substring line 0 pos)
|
|
278 labels
|
|
279 (substring line (1+ pos))))))
|
|
280
|
|
281 (defun rmail-make-basic-summary-line ()
|
|
282 (goto-char (point-min))
|
|
283 (concat (save-excursion
|
|
284 (if (not (re-search-forward "^Date:" nil t))
|
|
285 " "
|
|
286 (cond ((re-search-forward "\\([^0-9:]\\)\\([0-3]?[0-9]\\)\\([- \t_]+\\)\\([adfjmnos][aceopu][bcglnprtvy]\\)"
|
|
287 (save-excursion (end-of-line) (point)) t)
|
|
288 (format "%2d-%3s"
|
|
289 (string-to-int (buffer-substring
|
|
290 (match-beginning 2)
|
|
291 (match-end 2)))
|
|
292 (buffer-substring
|
|
293 (match-beginning 4) (match-end 4))))
|
|
294 ((re-search-forward "\\([^a-z]\\)\\([adfjmnos][acepou][bcglnprtvy]\\)\\([-a-z \t_]*\\)\\([0-9][0-9]?\\)"
|
|
295 (save-excursion (end-of-line) (point)) t)
|
|
296 (format "%2d-%3s"
|
|
297 (string-to-int (buffer-substring
|
|
298 (match-beginning 4)
|
|
299 (match-end 4)))
|
|
300 (buffer-substring
|
|
301 (match-beginning 2) (match-end 2))))
|
|
302 (t "??????"))))
|
|
303 " "
|
|
304 (save-excursion
|
|
305 (if (not (re-search-forward "^From:[ \t]*" nil t))
|
|
306 " "
|
|
307 (let* ((from (mail-strip-quoted-names
|
|
308 (buffer-substring
|
|
309 (1- (point))
|
|
310 (progn (end-of-line)
|
|
311 (skip-chars-backward " \t")
|
|
312 (point)))))
|
|
313 len mch lo)
|
|
314 (if (string-match (concat "^"
|
|
315 (regexp-quote (user-login-name))
|
|
316 "\\($\\|@\\)")
|
|
317 from)
|
|
318 (save-excursion
|
|
319 (goto-char (point-min))
|
|
320 (if (not (re-search-forward "^To:[ \t]*" nil t))
|
|
321 nil
|
|
322 (setq from
|
|
323 (concat "to: "
|
|
324 (mail-strip-quoted-names
|
|
325 (buffer-substring
|
|
326 (point)
|
|
327 (progn (end-of-line)
|
|
328 (skip-chars-backward " \t")
|
|
329 (point)))))))))
|
|
330 (setq len (length from))
|
|
331 (setq mch (string-match "[@%]" from))
|
|
332 (format "%25s"
|
|
333 (if (or (not mch) (<= len 25))
|
|
334 (substring from (max 0 (- len 25)))
|
|
335 (substring from
|
|
336 (setq lo (cond ((< (- mch 9) 0) 0)
|
|
337 ((< len (+ mch 16))
|
|
338 (- len 25))
|
|
339 (t (- mch 9))))
|
|
340 (min len (+ lo 25))))))))
|
|
341 " #"
|
|
342 (if (re-search-forward "^Subject:" nil t)
|
|
343 (progn (skip-chars-forward " \t")
|
|
344 (buffer-substring (point)
|
|
345 (progn (end-of-line)
|
|
346 (point))))
|
|
347 (re-search-forward "[\n][\n]+" nil t)
|
|
348 (buffer-substring (point) (progn (end-of-line) (point))))
|
|
349 "\n"))
|
|
350
|
|
351 ;; Simple motion in a summary buffer.
|
|
352
|
|
353 (defun rmail-summary-next-all (&optional number)
|
|
354 (interactive "p")
|
|
355 (forward-line (if number number 1))
|
|
356 (display-buffer rmail-buffer))
|
|
357
|
|
358 (defun rmail-summary-previous-all (&optional number)
|
|
359 (interactive "p")
|
|
360 (forward-line (- (if number number 1)))
|
|
361 (display-buffer rmail-buffer))
|
|
362
|
|
363 (defun rmail-summary-next-msg (&optional number)
|
|
364 "Display next non-deleted msg from rmail file.
|
|
365 With optional prefix argument NUMBER, moves forward this number of non-deleted
|
|
366 messages, or backward if NUMBER is negative."
|
|
367 (interactive "p")
|
|
368 (forward-line 0)
|
|
369 (and (> number 0) (end-of-line))
|
|
370 (let ((count (if (< number 0) (- number) number))
|
|
371 (search (if (> number 0) 're-search-forward 're-search-backward))
|
|
372 (non-del-msg-found nil))
|
|
373 (while (and (> count 0) (setq non-del-msg-found
|
|
374 (or (funcall search "^....[^D]" nil t)
|
|
375 non-del-msg-found)))
|
|
376 (setq count (1- count))))
|
|
377 (beginning-of-line)
|
|
378 (display-buffer rmail-buffer))
|
|
379
|
|
380 (defun rmail-summary-previous-msg (&optional number)
|
|
381 (interactive "p")
|
|
382 (rmail-summary-next-msg (- (if number number 1))))
|
|
383
|
|
384 (defun rmail-summary-next-labeled-message (n labels)
|
|
385 "Show next message with LABEL. Defaults to last labels used.
|
|
386 With prefix argument N moves forward N messages with these labels."
|
|
387 (interactive "p\nsMove to next msg with labels: ")
|
|
388 (save-excursion
|
|
389 (set-buffer rmail-buffer)
|
|
390 (rmail-next-labeled-message n labels)))
|
|
391
|
|
392 (defun rmail-summary-previous-labeled-message (n labels)
|
|
393 "Show previous message with LABEL. Defaults to last labels used.
|
|
394 With prefix argument N moves backward N messages with these labels."
|
|
395 (interactive "p\nsMove to previous msg with labels: ")
|
|
396 (save-excursion
|
|
397 (set-buffer rmail-buffer)
|
|
398 (rmail-previous-labeled-message n labels)))
|
|
399
|
|
400 ;; Delete and undelete summary commands.
|
|
401
|
|
402 (defun rmail-summary-delete-forward (&optional backward)
|
|
403 "Delete this message and move to next nondeleted one.
|
|
404 Deleted messages stay in the file until the \\[rmail-expunge] command is given.
|
|
405 With prefix argument, delete and move backward."
|
|
406 (interactive "P")
|
|
407 (progn ;;let (end) ;jwz
|
|
408 (rmail-summary-goto-msg)
|
|
409 (pop-to-buffer rmail-buffer)
|
|
410 (rmail-delete-forward backward)
|
|
411 (pop-to-buffer rmail-summary-buffer)))
|
|
412
|
|
413 (defun rmail-summary-delete-backward ()
|
|
414 "Delete this message and move to previous nondeleted one.
|
|
415 Deleted messages stay in the file until the \\[rmail-expunge] command is given."
|
|
416 (interactive)
|
|
417 (rmail-summary-delete-forward t))
|
|
418
|
|
419 (defun rmail-summary-mark-deleted (&optional n undel)
|
|
420 (and n (rmail-summary-goto-msg n t t))
|
|
421 (or (eobp)
|
|
422 (let ((buffer-read-only nil))
|
|
423 (skip-chars-forward " ")
|
|
424 (skip-chars-forward "[0-9]")
|
|
425 (if undel
|
|
426 (if (looking-at "D")
|
|
427 (progn (delete-char 1) (insert " ")))
|
|
428 (delete-char 1)
|
|
429 (insert "D"))))
|
|
430 (beginning-of-line))
|
|
431
|
|
432 (defun rmail-summary-mark-undeleted (n)
|
|
433 (rmail-summary-mark-deleted n t))
|
|
434
|
|
435 (defun rmail-summary-deleted-p (&optional n)
|
|
436 (save-excursion
|
|
437 (and n (rmail-summary-goto-msg n nil t))
|
|
438 (skip-chars-forward " ")
|
|
439 (skip-chars-forward "[0-9]")
|
|
440 (looking-at "D")))
|
|
441
|
|
442 (defun rmail-summary-undelete (&optional arg)
|
|
443 "Undelete current message.
|
|
444 Optional prefix ARG means undelete ARG previous messages."
|
|
445 (interactive "p")
|
|
446 (if (/= arg 1)
|
|
447 (rmail-summary-undelete-many arg)
|
|
448 (let ((buffer-read-only nil))
|
|
449 (end-of-line)
|
|
450 (cond ((re-search-backward "\\(^ *[0-9]*\\)\\(D\\)" nil t)
|
|
451 (replace-match "\\1 ")
|
|
452 (rmail-summary-goto-msg)
|
|
453 (pop-to-buffer rmail-buffer)
|
|
454 (and (rmail-message-deleted-p rmail-current-message)
|
|
455 (rmail-undelete-previous-message))
|
|
456 (pop-to-buffer rmail-summary-buffer))))))
|
|
457
|
|
458 (defun rmail-summary-undelete-many (&optional n)
|
|
459 "Undelete all deleted msgs, optional prefix arg N means undelete N prev msgs."
|
|
460 (interactive "P")
|
|
461 (save-excursion
|
|
462 (set-buffer rmail-buffer)
|
|
463 (let* ((init-msg (if n rmail-current-message rmail-total-messages))
|
|
464 (rmail-current-message init-msg)
|
|
465 (n (or n rmail-total-messages))
|
|
466 (msgs-undeled 0))
|
|
467 (while (and (> rmail-current-message 0)
|
|
468 (< msgs-undeled n))
|
|
469 (if (rmail-message-deleted-p rmail-current-message)
|
|
470 (progn (rmail-set-attribute "deleted" nil)
|
|
471 (setq msgs-undeled (1+ msgs-undeled))))
|
|
472 (setq rmail-current-message (1- rmail-current-message)))
|
|
473 (set-buffer rmail-summary-buffer)
|
|
474 (setq rmail-current-message init-msg msgs-undeled 0)
|
|
475 (while (and (> rmail-current-message 0)
|
|
476 (< msgs-undeled n))
|
|
477 (if (rmail-summary-deleted-p rmail-current-message)
|
|
478 (progn (rmail-summary-mark-undeleted rmail-current-message)
|
|
479 (setq msgs-undeled (1+ msgs-undeled))))
|
|
480 (setq rmail-current-message (1- rmail-current-message))))
|
|
481 (rmail-summary-goto-msg)))
|
|
482
|
|
483 ;; Rmail Summary mode is suitable only for specially formatted data.
|
|
484 (put 'rmail-summary-mode 'mode-class 'special)
|
|
485
|
|
486 (defun rmail-summary-mode ()
|
|
487 "Rmail Summary Mode is invoked from Rmail Mode by using \\<rmail-mode-map>\\[rmail-summary].
|
|
488 As commands are issued in the summary buffer, they are applied to the
|
|
489 corresponding mail messages in the rmail buffer.
|
|
490
|
|
491 All normal editing commands are turned off.
|
|
492 Instead, nearly all the Rmail mode commands are available,
|
|
493 though many of them move only among the messages in the summary.
|
|
494
|
|
495 These additional commands exist:
|
|
496
|
|
497 \\[rmail-summary-undelete-many] Undelete all or prefix arg deleted messages.
|
|
498 \\[rmail-summary-wipe] Delete the summary and go to the Rmail buffer.
|
|
499
|
|
500 Commands for sorting the summary:
|
|
501
|
|
502 \\[rmail-summary-sort-by-date] Sort by date.
|
|
503 \\[rmail-summary-sort-by-subject] Sort by subject.
|
|
504 \\[rmail-summary-sort-by-author] Sort by author.
|
|
505 \\[rmail-summary-sort-by-recipient] Sort by recipient.
|
|
506 \\[rmail-summary-sort-by-correspondent] Sort by correspondent.
|
|
507 \\[rmail-summary-sort-by-lines] Sort by lines."
|
|
508 (interactive)
|
|
509 (kill-all-local-variables)
|
|
510 (setq major-mode 'rmail-summary-mode)
|
|
511 (setq mode-name "RMAIL Summary")
|
|
512 (use-local-map rmail-summary-mode-map)
|
|
513 (setq truncate-lines t)
|
|
514 (setq buffer-read-only t)
|
|
515 (set-syntax-table text-mode-syntax-table)
|
|
516 (make-local-variable 'rmail-buffer)
|
|
517 (make-local-variable 'rmail-total-messages)
|
|
518 (make-local-variable 'rmail-current-message)
|
|
519 (setq rmail-current-message nil)
|
|
520 (make-local-variable 'rmail-summary-redo)
|
|
521 (setq rmail-summary-redo nil)
|
|
522 (make-local-variable 'revert-buffer-function)
|
|
523 (setq revert-buffer-function 'rmail-update-summary)
|
|
524 (make-local-hook 'post-command-hook)
|
|
525 (add-hook 'post-command-hook 'rmail-summary-rmail-update nil t)
|
|
526 (run-hooks 'rmail-summary-mode-hook))
|
|
527
|
|
528 ;; Show in Rmail the message described by the summary line that point is on,
|
|
529 ;; but only if the Rmail buffer is already visible.
|
|
530 ;; This is a post-command-hook in summary buffers.
|
|
531 (defun rmail-summary-rmail-update ()
|
|
532 (if (get-buffer-window rmail-buffer)
|
|
533 (let (buffer-read-only)
|
|
534 (save-excursion
|
|
535 (beginning-of-line)
|
|
536 (skip-chars-forward " ")
|
|
537 (let ((beg (point))
|
|
538 msg-num
|
|
539 ;;(buf rmail-buffer)
|
|
540 )
|
|
541 (skip-chars-forward "0-9")
|
|
542 (setq msg-num (string-to-int (buffer-substring beg (point))))
|
|
543 (or (eq rmail-current-message msg-num)
|
|
544 (let (;;go-where
|
|
545 window (owin (selected-window)))
|
|
546 (setq rmail-current-message msg-num)
|
|
547 (if (= (following-char) ?-)
|
|
548 (progn
|
|
549 (delete-char 1)
|
|
550 (insert " ")))
|
|
551 (setq window (display-buffer rmail-buffer))
|
|
552 ;; Using save-window-excursion caused the new value
|
|
553 ;; of point to get lost.
|
|
554 (unwind-protect
|
|
555 (progn
|
|
556 (select-window window)
|
|
557 (rmail-show-message msg-num))
|
|
558 (select-window owin)))))))))
|
|
559
|
|
560 (if rmail-summary-mode-map
|
|
561 nil
|
|
562 (setq rmail-summary-mode-map (make-keymap))
|
|
563 (suppress-keymap rmail-summary-mode-map)
|
|
564 (define-key rmail-summary-mode-map "a" 'rmail-summary-add-label)
|
|
565 (define-key rmail-summary-mode-map "c" 'rmail-summary-continue)
|
|
566 (define-key rmail-summary-mode-map "d" 'rmail-summary-delete-forward)
|
|
567 (define-key rmail-summary-mode-map "\C-d" 'rmail-summary-delete-backward)
|
|
568 (define-key rmail-summary-mode-map "e" 'rmail-summary-edit-current-message)
|
|
569 (define-key rmail-summary-mode-map "f" 'rmail-summary-forward)
|
|
570 (define-key rmail-summary-mode-map "g" 'rmail-summary-get-new-mail)
|
|
571 (define-key rmail-summary-mode-map "h" 'rmail-summary)
|
|
572 (define-key rmail-summary-mode-map "i" 'rmail-summary-input)
|
|
573 (define-key rmail-summary-mode-map "j" 'rmail-summary-goto-msg)
|
|
574 (define-key rmail-summary-mode-map "k" 'rmail-summary-kill-label)
|
|
575 (define-key rmail-summary-mode-map "l" 'rmail-summary-by-labels)
|
|
576 (define-key rmail-summary-mode-map "\e\C-h" 'rmail-summary)
|
|
577 (define-key rmail-summary-mode-map "\e\C-l" 'rmail-summary-by-labels)
|
|
578 (define-key rmail-summary-mode-map "\e\C-r" 'rmail-summary-by-recipients)
|
|
579 (define-key rmail-summary-mode-map "\e\C-s" 'rmail-summary-by-regexp)
|
|
580 (define-key rmail-summary-mode-map "\e\C-t" 'rmail-summary-by-topic)
|
|
581 (define-key rmail-summary-mode-map "m" 'rmail-summary-mail)
|
|
582 (define-key rmail-summary-mode-map "\M-m" 'rmail-summary-retry-failure)
|
|
583 (define-key rmail-summary-mode-map "n" 'rmail-summary-next-msg)
|
|
584 (define-key rmail-summary-mode-map "\en" 'rmail-summary-next-all)
|
|
585 (define-key rmail-summary-mode-map "\e\C-n" 'rmail-summary-next-labeled-message)
|
|
586 (define-key rmail-summary-mode-map "o" 'rmail-summary-output-to-rmail-file)
|
|
587 (define-key rmail-summary-mode-map "\C-o" 'rmail-summary-output)
|
|
588 (define-key rmail-summary-mode-map "p" 'rmail-summary-previous-msg)
|
|
589 (define-key rmail-summary-mode-map "\ep" 'rmail-summary-previous-all)
|
|
590 (define-key rmail-summary-mode-map "\e\C-p" 'rmail-summary-previous-labeled-message)
|
|
591 (define-key rmail-summary-mode-map "q" 'rmail-summary-quit)
|
|
592 (define-key rmail-summary-mode-map "r" 'rmail-summary-reply)
|
|
593 (define-key rmail-summary-mode-map "s" 'rmail-summary-expunge-and-save)
|
|
594 (define-key rmail-summary-mode-map "\es" 'rmail-summary-search)
|
|
595 (define-key rmail-summary-mode-map "t" 'rmail-summary-toggle-header)
|
|
596 (define-key rmail-summary-mode-map "u" 'rmail-summary-undelete)
|
|
597 (define-key rmail-summary-mode-map "\M-u" 'rmail-summary-undelete-many)
|
|
598 (define-key rmail-summary-mode-map "w" 'rmail-summary-wipe)
|
|
599 (define-key rmail-summary-mode-map "x" 'rmail-summary-expunge)
|
|
600 (define-key rmail-summary-mode-map "." 'rmail-summary-beginning-of-message)
|
|
601 (define-key rmail-summary-mode-map "<" 'rmail-summary-first-message)
|
|
602 (define-key rmail-summary-mode-map ">" 'rmail-summary-last-message)
|
|
603 (define-key rmail-summary-mode-map " " 'rmail-summary-scroll-msg-up)
|
|
604 (define-key rmail-summary-mode-map "\177" 'rmail-summary-scroll-msg-down)
|
|
605 (define-key rmail-summary-mode-map "?" 'describe-mode)
|
|
606 (define-key rmail-summary-mode-map "\C-c\C-s\C-d"
|
|
607 'rmail-summary-sort-by-date)
|
|
608 (define-key rmail-summary-mode-map "\C-c\C-s\C-s"
|
|
609 'rmail-summary-sort-by-subject)
|
|
610 (define-key rmail-summary-mode-map "\C-c\C-s\C-a"
|
|
611 'rmail-summary-sort-by-author)
|
|
612 (define-key rmail-summary-mode-map "\C-c\C-s\C-r"
|
|
613 'rmail-summary-sort-by-recipient)
|
|
614 (define-key rmail-summary-mode-map "\C-c\C-s\C-c"
|
|
615 'rmail-summary-sort-by-correspondent)
|
|
616 (define-key rmail-summary-mode-map "\C-c\C-s\C-l"
|
|
617 'rmail-summary-sort-by-lines)
|
|
618 )
|
|
619
|
|
620 ;;; Menu bar bindings.
|
|
621 ;
|
|
622 ;(define-key rmail-summary-mode-map [menu-bar] (make-sparse-keymap))
|
|
623 ;
|
|
624 ;(define-key rmail-summary-mode-map [menu-bar classify]
|
|
625 ; (cons "Classify" (make-sparse-keymap "Classify")))
|
|
626 ;
|
|
627 ;(define-key rmail-summary-mode-map [menu-bar classify output-inbox]
|
|
628 ; '("Output (inbox)" . rmail-summary-output))
|
|
629 ;
|
|
630 ;(define-key rmail-summary-mode-map [menu-bar classify output]
|
|
631 ; '("Output (Rmail)" . rmail-summary-output-to-rmail-file))
|
|
632 ;
|
|
633 ;(define-key rmail-summary-mode-map [menu-bar classify kill-label]
|
|
634 ; '("Kill Label" . rmail-summary-kill-label))
|
|
635 ;
|
|
636 ;(define-key rmail-summary-mode-map [menu-bar classify add-label]
|
|
637 ; '("Add Label" . rmail-summary-add-label))
|
|
638 ;
|
|
639 ;(define-key rmail-summary-mode-map [menu-bar summary]
|
|
640 ; (cons "Summary" (make-sparse-keymap "Summary")))
|
|
641 ;
|
|
642 ;(define-key rmail-summary-mode-map [menu-bar summary labels]
|
|
643 ; '("By Labels" . rmail-summary-by-labels))
|
|
644 ;
|
|
645 ;(define-key rmail-summary-mode-map [menu-bar summary recipients]
|
|
646 ; '("By Recipients" . rmail-summary-by-recipients))
|
|
647 ;
|
|
648 ;(define-key rmail-summary-mode-map [menu-bar summary topic]
|
|
649 ; '("By Topic" . rmail-summary-by-topic))
|
|
650 ;
|
|
651 ;(define-key rmail-summary-mode-map [menu-bar summary regexp]
|
|
652 ; '("By Regexp" . rmail-summary-by-regexp))
|
|
653 ;
|
|
654 ;(define-key rmail-summary-mode-map [menu-bar summary all]
|
|
655 ; '("All" . rmail-summary))
|
|
656 ;
|
|
657 ;(define-key rmail-summary-mode-map [menu-bar mail]
|
|
658 ; (cons "Mail" (make-sparse-keymap "Mail")))
|
|
659 ;
|
|
660 ;(define-key rmail-summary-mode-map [menu-bar mail continue]
|
|
661 ; '("Continue" . rmail-summary-continue))
|
|
662 ;
|
|
663 ;(define-key rmail-summary-mode-map [menu-bar mail forward]
|
|
664 ; '("Forward" . rmail-summary-forward))
|
|
665 ;
|
|
666 ;(define-key rmail-summary-mode-map [menu-bar mail retry]
|
|
667 ; '("Retry" . rmail-summary-retry-failure))
|
|
668 ;
|
|
669 ;(define-key rmail-summary-mode-map [menu-bar mail reply]
|
|
670 ; '("Reply" . rmail-summary-reply))
|
|
671 ;
|
|
672 ;(define-key rmail-summary-mode-map [menu-bar mail mail]
|
|
673 ; '("Mail" . rmail-summary-mail))
|
|
674 ;
|
|
675 ;(define-key rmail-summary-mode-map [menu-bar delete]
|
|
676 ; (cons "Delete" (make-sparse-keymap "Delete")))
|
|
677 ;
|
|
678 ;(define-key rmail-summary-mode-map [menu-bar delete expunge/save]
|
|
679 ; '("Expunge/Save" . rmail-summary-expunge-and-save))
|
|
680 ;
|
|
681 ;(define-key rmail-summary-mode-map [menu-bar delete expunge]
|
|
682 ; '("Expunge" . rmail-summary-expunge))
|
|
683 ;
|
|
684 ;(define-key rmail-summary-mode-map [menu-bar delete undelete]
|
|
685 ; '("Undelete" . rmail-summary-undelete))
|
|
686 ;
|
|
687 ;(define-key rmail-summary-mode-map [menu-bar delete delete]
|
|
688 ; '("Delete" . rmail-summary-delete-forward))
|
|
689 ;
|
|
690 ;(define-key rmail-summary-mode-map [menu-bar move]
|
|
691 ; (cons "Move" (make-sparse-keymap "Move")))
|
|
692 ;
|
|
693 ;(define-key rmail-summary-mode-map [menu-bar move search-back]
|
|
694 ; '("Search Back" . rmail-summary-search-backward))
|
|
695 ;
|
|
696 ;(define-key rmail-summary-mode-map [menu-bar move search]
|
|
697 ; '("Search" . rmail-summary-search))
|
|
698 ;
|
|
699 ;(define-key rmail-summary-mode-map [menu-bar move previous]
|
|
700 ; '("Previous Nondeleted" . rmail-summary-previous-msg))
|
|
701 ;
|
|
702 ;(define-key rmail-summary-mode-map [menu-bar move next]
|
|
703 ; '("Next Nondeleted" . rmail-summary-next-msg))
|
|
704 ;
|
|
705 ;(define-key rmail-summary-mode-map [menu-bar move last]
|
|
706 ; '("Last" . rmail-summary-last-message))
|
|
707 ;
|
|
708 ;(define-key rmail-summary-mode-map [menu-bar move first]
|
|
709 ; '("First" . rmail-summary-first-message))
|
|
710 ;
|
|
711 ;(define-key rmail-summary-mode-map [menu-bar move previous]
|
|
712 ; '("Previous" . rmail-summary-previous-all))
|
|
713 ;
|
|
714 ;(define-key rmail-summary-mode-map [menu-bar move next]
|
|
715 ; '("Next" . rmail-summary-next-all))
|
|
716
|
|
717 (defun rmail-summary-goto-msg (&optional n nowarn skip-rmail)
|
|
718 (interactive "P")
|
|
719 (if (consp n) (setq n (prefix-numeric-value n)))
|
|
720 (if (eobp) (forward-line -1))
|
|
721 (beginning-of-line)
|
|
722 (let ((buf rmail-buffer)
|
|
723 (cur (point))
|
|
724 (curmsg (string-to-int
|
|
725 (buffer-substring (point)
|
|
726 (min (point-max) (+ 5 (point)))))))
|
|
727 (if (not n)
|
|
728 (setq n curmsg)
|
|
729 (if (< n 1)
|
|
730 (progn (message "No preceding message")
|
|
731 (setq n 1)))
|
|
732 (if (> n rmail-total-messages)
|
|
733 (progn (message "No following message")
|
|
734 (goto-char (point-max))
|
|
735 (rmail-summary-goto-msg)))
|
|
736 (goto-char (point-min))
|
|
737 (if (not (re-search-forward (concat "^ *" (int-to-string n)) nil t))
|
|
738 (progn (or nowarn (message "Message %d not found" n))
|
|
739 (setq n curmsg)
|
|
740 (goto-char cur))))
|
|
741 (beginning-of-line)
|
|
742 (skip-chars-forward " ")
|
|
743 (skip-chars-forward "0-9")
|
|
744 (save-excursion (if (= (following-char) ?-)
|
|
745 (let ((buffer-read-only nil))
|
|
746 (delete-char 1)
|
|
747 (insert " "))))
|
|
748 (beginning-of-line)
|
|
749 (if skip-rmail
|
|
750 nil
|
|
751 (pop-to-buffer buf)
|
|
752 (rmail-show-message n)
|
|
753 (pop-to-buffer rmail-summary-buffer))))
|
|
754
|
|
755 (defun rmail-summary-scroll-msg-up (&optional dist)
|
|
756 "Scroll other window forward."
|
|
757 (interactive "P")
|
|
758 (scroll-other-window dist))
|
|
759
|
|
760 (defun rmail-summary-scroll-msg-down (&optional dist)
|
|
761 "Scroll other window backward."
|
|
762 (interactive "P")
|
|
763 (scroll-other-window
|
|
764 (cond ((eq dist '-) nil)
|
|
765 ((null dist) '-)
|
|
766 (t (- (prefix-numeric-value dist))))))
|
|
767
|
|
768 (defun rmail-summary-beginning-of-message ()
|
|
769 "Show current message from the beginning."
|
|
770 (interactive)
|
|
771 (pop-to-buffer rmail-buffer)
|
|
772 (beginning-of-buffer)
|
|
773 (pop-to-buffer rmail-summary-buffer))
|
|
774
|
|
775 (defun rmail-summary-quit ()
|
|
776 "Quit out of Rmail and Rmail summary."
|
|
777 (interactive)
|
|
778 (rmail-summary-wipe)
|
|
779 (rmail-quit))
|
|
780
|
|
781 (defun rmail-summary-wipe ()
|
|
782 "Kill and wipe away Rmail summary, remaining within Rmail."
|
|
783 (interactive)
|
|
784 (save-excursion (set-buffer rmail-buffer) (setq rmail-summary-buffer nil))
|
|
785 (let ((local-rmail-buffer rmail-buffer))
|
|
786 (kill-buffer (current-buffer))
|
|
787 ;; Delete window if not only one.
|
|
788 (if (not (eq (selected-window) (next-window nil 'no-minibuf)))
|
|
789 (delete-window))
|
|
790 ;; Switch windows to the rmail buffer, or switch to it in this window.
|
|
791 (pop-to-buffer local-rmail-buffer)))
|
|
792
|
|
793 (defun rmail-summary-expunge ()
|
|
794 "Actually erase all deleted messages and recompute summary headers."
|
|
795 (interactive)
|
|
796 (save-excursion
|
|
797 (set-buffer rmail-buffer)
|
|
798 (rmail-only-expunge))
|
|
799 (rmail-update-summary))
|
|
800
|
|
801 (defun rmail-summary-expunge-and-save ()
|
|
802 "Expunge and save RMAIL file."
|
|
803 (interactive)
|
|
804 (save-excursion
|
|
805 (set-buffer rmail-buffer)
|
|
806 (rmail-only-expunge))
|
|
807 (rmail-update-summary)
|
|
808 (save-excursion
|
|
809 (set-buffer rmail-buffer)
|
|
810 (save-buffer)))
|
|
811
|
|
812 (defun rmail-summary-get-new-mail ()
|
|
813 "Get new mail and recompute summary headers."
|
|
814 (interactive)
|
|
815 (let (msg)
|
|
816 (save-excursion
|
|
817 (set-buffer rmail-buffer)
|
|
818 (rmail-get-new-mail)
|
|
819 ;; Get the proper new message number.
|
|
820 (setq msg rmail-current-message))
|
|
821 ;; Make sure that message is displayed.
|
|
822 (rmail-summary-goto-msg msg)))
|
|
823
|
|
824 (defun rmail-summary-input (filename)
|
|
825 "Run Rmail on file FILENAME."
|
|
826 (interactive "FRun rmail on RMAIL file: ")
|
|
827 ;; We switch windows here, then display the other Rmail file there.
|
|
828 (pop-to-buffer rmail-buffer)
|
|
829 (rmail filename))
|
|
830
|
|
831 (defun rmail-summary-first-message ()
|
|
832 "Show first message in Rmail file from summary buffer."
|
|
833 (interactive)
|
|
834 (beginning-of-buffer))
|
|
835
|
|
836 (defun rmail-summary-last-message ()
|
|
837 "Show last message in Rmail file from summary buffer."
|
|
838 (interactive)
|
|
839 (end-of-buffer)
|
|
840 (forward-line -1))
|
|
841
|
|
842 (defvar rmail-summary-edit-map nil)
|
|
843 (if rmail-summary-edit-map
|
|
844 nil
|
|
845 (setq rmail-summary-edit-map (make-sparse-keymap))
|
|
846 (set-keymap-parent rmail-summary-edit-map text-mode-map)
|
|
847 (set-keymap-name rmail-summary-edit-map 'rmail-summary-edit-map)
|
|
848 (define-key rmail-summary-edit-map "\C-c\C-c" 'rmail-cease-edit)
|
|
849 (define-key rmail-summary-edit-map "\C-c\C-]" 'rmail-abort-edit))
|
|
850
|
|
851 (defun rmail-summary-edit-current-message ()
|
|
852 "Edit the contents of this message."
|
|
853 (interactive)
|
|
854 (pop-to-buffer rmail-buffer)
|
|
855 (rmail-edit-current-message)
|
|
856 (use-local-map rmail-summary-edit-map))
|
|
857
|
|
858 (defun rmail-summary-cease-edit ()
|
|
859 "Finish editing message, then go back to Rmail summary buffer."
|
|
860 (interactive)
|
|
861 (rmail-cease-edit)
|
|
862 (pop-to-buffer rmail-summary-buffer))
|
|
863
|
|
864 (defun rmail-summary-abort-edit ()
|
|
865 "Abort edit of current message; restore original contents.
|
|
866 Go back to summary buffer."
|
|
867 (interactive)
|
|
868 (rmail-abort-edit)
|
|
869 (pop-to-buffer rmail-summary-buffer))
|
|
870
|
|
871 (defun rmail-summary-search-backward (regexp &optional n)
|
|
872 "Show message containing next match for REGEXP.
|
|
873 Prefix argument gives repeat count; negative argument means search
|
|
874 backwards (through earlier messages).
|
|
875 Interactively, empty argument means use same regexp used last time."
|
|
876 (interactive
|
|
877 (let* ((reversep (>= (prefix-numeric-value current-prefix-arg) 0))
|
|
878 (prompt
|
|
879 (concat (if reversep "Reverse " "") "Rmail search (regexp): "))
|
|
880 regexp)
|
|
881 (if rmail-search-last-regexp
|
|
882 (setq prompt (concat prompt
|
|
883 "(default "
|
|
884 rmail-search-last-regexp
|
|
885 ") ")))
|
|
886 (setq regexp (read-string prompt))
|
|
887 (cond ((not (equal regexp ""))
|
|
888 (setq rmail-search-last-regexp regexp))
|
|
889 ((not rmail-search-last-regexp)
|
|
890 (error "No previous Rmail search string")))
|
|
891 (list rmail-search-last-regexp
|
|
892 (prefix-numeric-value current-prefix-arg))))
|
|
893 ;; Don't use save-excursion because that prevents point from moving
|
|
894 ;; properly in the summary buffer.
|
|
895 (let ((buffer (current-buffer)))
|
|
896 (unwind-protect
|
|
897 (progn
|
|
898 (set-buffer rmail-buffer)
|
|
899 (rmail-search regexp (- n)))
|
|
900 (set-buffer buffer))))
|
|
901
|
|
902 (defun rmail-summary-search (regexp &optional n)
|
|
903 "Show message containing next match for REGEXP.
|
|
904 Prefix argument gives repeat count; negative argument means search
|
|
905 backwards (through earlier messages).
|
|
906 Interactively, empty argument means use same regexp used last time."
|
|
907 (interactive
|
|
908 (let* ((reversep (< (prefix-numeric-value current-prefix-arg) 0))
|
|
909 (prompt
|
|
910 (concat (if reversep "Reverse " "") "Rmail search (regexp): "))
|
|
911 regexp)
|
|
912 (if rmail-search-last-regexp
|
|
913 (setq prompt (concat prompt
|
|
914 "(default "
|
|
915 rmail-search-last-regexp
|
|
916 ") ")))
|
|
917 (setq regexp (read-string prompt))
|
|
918 (cond ((not (equal regexp ""))
|
|
919 (setq rmail-search-last-regexp regexp))
|
|
920 ((not rmail-search-last-regexp)
|
|
921 (error "No previous Rmail search string")))
|
|
922 (list rmail-search-last-regexp
|
|
923 (prefix-numeric-value current-prefix-arg))))
|
|
924 ;; Don't use save-excursion because that prevents point from moving
|
|
925 ;; properly in the summary buffer.
|
|
926 (let ((buffer (current-buffer)))
|
|
927 (unwind-protect
|
|
928 (progn
|
|
929 (set-buffer rmail-buffer)
|
|
930 (rmail-search regexp n))
|
|
931 (set-buffer buffer))))
|
|
932
|
|
933 (defun rmail-summary-toggle-header ()
|
|
934 "Show original message header if pruned header currently shown, or vice versa."
|
|
935 (interactive)
|
|
936 (save-excursion
|
|
937 (set-buffer rmail-buffer)
|
|
938 (rmail-toggle-header)))
|
|
939
|
|
940 (defun rmail-summary-add-label (label)
|
|
941 "Add LABEL to labels associated with current Rmail message.
|
|
942 Completion is performed over known labels when reading."
|
|
943 (interactive (list (save-excursion
|
|
944 (set-buffer rmail-buffer)
|
|
945 (rmail-read-label "Add label"))))
|
|
946 (save-excursion
|
|
947 (set-buffer rmail-buffer)
|
|
948 (rmail-add-label label)))
|
|
949
|
|
950 (defun rmail-summary-kill-label (label)
|
|
951 "Remove LABEL from labels associated with current Rmail message.
|
|
952 Completion is performed over known labels when reading."
|
|
953 (interactive (list (save-excursion
|
|
954 (set-buffer rmail-buffer)
|
|
955 (rmail-read-label "Kill label"))))
|
|
956 (save-excursion
|
|
957 (set-buffer rmail-buffer)
|
|
958 (rmail-set-label label nil)))
|
|
959
|
|
960 ;;;; *** Rmail Summary Mailing Commands ***
|
|
961
|
|
962 (defun rmail-summary-mail ()
|
|
963 "Send mail in another window.
|
|
964 While composing the message, use \\[mail-yank-original] to yank the
|
|
965 original message into it."
|
|
966 (interactive)
|
|
967 (mail-other-window nil nil nil nil nil rmail-buffer)
|
|
968 (use-local-map (copy-keymap (current-local-map)))
|
|
969 (define-key (current-local-map)
|
|
970 "\C-c\C-c" 'rmail-summary-send-and-exit))
|
|
971
|
|
972 (defun rmail-summary-continue ()
|
|
973 "Continue composing outgoing message previously being composed."
|
|
974 (interactive)
|
|
975 (mail-other-window t))
|
|
976
|
|
977 (defun rmail-summary-reply (just-sender)
|
|
978 "Reply to the current message.
|
|
979 Normally include CC: to all other recipients of original message;
|
|
980 prefix argument means ignore them.
|
|
981 While composing the reply, use \\[mail-yank-original] to yank the
|
|
982 original message into it."
|
|
983 (interactive "P")
|
|
984 (let (mailbuf)
|
|
985 (save-window-excursion
|
|
986 (set-buffer rmail-buffer)
|
|
987 (rmail-reply just-sender)
|
|
988 (setq mailbuf (current-buffer)))
|
|
989 (pop-to-buffer mailbuf)
|
|
990 (use-local-map (copy-keymap (current-local-map)))
|
|
991 (define-key (current-local-map)
|
|
992 "\C-c\C-c" 'rmail-summary-send-and-exit)))
|
|
993
|
|
994 (defun rmail-summary-retry-failure ()
|
|
995 "Edit a mail message which is based on the contents of the current message.
|
|
996 For a message rejected by the mail system, extract the interesting headers and
|
|
997 the body of the original message; otherwise copy the current message."
|
|
998 (interactive)
|
|
999 (let (mailbuf)
|
|
1000 (save-window-excursion
|
|
1001 (set-buffer rmail-buffer)
|
|
1002 (rmail-retry-failure)
|
|
1003 (setq mailbuf (current-buffer)))
|
|
1004 (pop-to-buffer mailbuf)
|
|
1005 (use-local-map (copy-keymap (current-local-map)))
|
|
1006 (define-key (current-local-map)
|
|
1007 "\C-c\C-c" 'rmail-summary-send-and-exit)))
|
|
1008
|
|
1009 (defun rmail-summary-send-and-exit ()
|
|
1010 "Send mail reply and return to summary buffer."
|
|
1011 (interactive)
|
|
1012 (mail-send-and-exit t))
|
|
1013
|
|
1014 (defun rmail-summary-forward (resend)
|
|
1015 "Forward the current message to another user.
|
|
1016 With prefix argument, \"resend\" the message instead of forwarding it;
|
|
1017 see the documentation of `rmail-resend'."
|
|
1018 (interactive "P")
|
|
1019 (save-excursion
|
|
1020 (set-buffer rmail-buffer)
|
|
1021 (rmail-forward resend)
|
|
1022 (use-local-map (copy-keymap (current-local-map)))
|
|
1023 (define-key (current-local-map)
|
|
1024 "\C-c\C-c" 'rmail-summary-send-and-exit)))
|
|
1025
|
|
1026 ;; Summary output commands.
|
|
1027
|
|
1028 (defun rmail-summary-output-to-rmail-file ()
|
|
1029 "Append the current message to an Rmail file named FILE-NAME.
|
|
1030 If the file does not exist, ask if it should be created.
|
|
1031 If file is being visited, the message is appended to the Emacs
|
|
1032 buffer visiting that file."
|
|
1033 (interactive)
|
|
1034 (save-excursion
|
|
1035 (set-buffer rmail-buffer)
|
|
1036 (call-interactively 'rmail-output-to-rmail-file)))
|
|
1037
|
|
1038 (defun rmail-summary-output ()
|
|
1039 "Append this message to Unix mail file named FILE-NAME."
|
|
1040 (interactive)
|
|
1041 (save-excursion
|
|
1042 (set-buffer rmail-buffer)
|
|
1043 (call-interactively 'rmail-output)))
|
|
1044
|
|
1045 ;; Sorting messages in Rmail Summary buffer.
|
|
1046
|
|
1047 (defun rmail-summary-sort-by-date (reverse)
|
|
1048 "Sort messages of current Rmail summary by date.
|
|
1049 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1050 (interactive "P")
|
|
1051 (rmail-sort-from-summary (function rmail-sort-by-date) reverse))
|
|
1052
|
|
1053 (defun rmail-summary-sort-by-subject (reverse)
|
|
1054 "Sort messages of current Rmail summary by subject.
|
|
1055 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1056 (interactive "P")
|
|
1057 (rmail-sort-from-summary (function rmail-sort-by-subject) reverse))
|
|
1058
|
|
1059 (defun rmail-summary-sort-by-author (reverse)
|
|
1060 "Sort messages of current Rmail summary by author.
|
|
1061 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1062 (interactive "P")
|
|
1063 (rmail-sort-from-summary (function rmail-sort-by-author) reverse))
|
|
1064
|
|
1065 (defun rmail-summary-sort-by-recipient (reverse)
|
|
1066 "Sort messages of current Rmail summary by recipient.
|
|
1067 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1068 (interactive "P")
|
|
1069 (rmail-sort-from-summary (function rmail-sort-by-recipient) reverse))
|
|
1070
|
|
1071 (defun rmail-summary-sort-by-correspondent (reverse)
|
|
1072 "Sort messages of current Rmail summary by other correspondent.
|
|
1073 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1074 (interactive "P")
|
|
1075 (rmail-sort-from-summary (function rmail-sort-by-correspondent) reverse))
|
|
1076
|
|
1077 (defun rmail-summary-sort-by-lines (reverse)
|
|
1078 "Sort messages of current Rmail summary by lines of the message.
|
|
1079 If prefix argument REVERSE is non-nil, sort them in reverse order."
|
|
1080 (interactive "P")
|
|
1081 (rmail-sort-from-summary (function rmail-sort-by-lines) reverse))
|
|
1082
|
|
1083 (defun rmail-sort-from-summary (sortfun reverse)
|
|
1084 "Sort Rmail messages from Summary buffer and update it after sorting."
|
|
1085 (require 'rmailsort)
|
|
1086 (pop-to-buffer rmail-buffer)
|
|
1087 (funcall sortfun reverse)
|
|
1088 (rmail-summary))
|
|
1089
|
|
1090 ;;; rmailsum.el ends here
|