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