Mercurial > emacs
comparison lisp/mail/rmailout.el @ 4056:419e92a78e6f
(rmail-output): If file is an Rmail file,
use rmail-output-to-rmail-file.
(rmail-output-to-rmail-file): If file exists
and is not an Rmail file, use rmail-output.
If we find an element in rmail-output-file-alist, eval it.
(rmail-file-p): New function.
(rmail-output-file-alist): Now contains expressions to eval.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 09 Jul 1993 20:46:42 +0000 |
parents | ea6739f778a5 |
children | af785cbe489a |
comparison
equal
deleted
inserted
replaced
4055:e5d455b14d82 | 4056:419e92a78e6f |
---|---|
1 ;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file. | 1 ;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file. |
2 | 2 |
3 ;; Copyright (C) 1985, 1987 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1985, 1987, 1993 Free Software Foundation, Inc. |
4 | 4 |
5 ;; Maintainer: FSF | 5 ;; Maintainer: FSF |
6 ;; Keywords: mail | 6 ;; Keywords: mail |
7 | 7 |
8 ;; This file is part of GNU Emacs. | 8 ;; This file is part of GNU Emacs. |
27 (defvar rmail-delete-after-output nil | 27 (defvar rmail-delete-after-output nil |
28 "*Non-nil means automatically delete a message that is copied to a file.") | 28 "*Non-nil means automatically delete a message that is copied to a file.") |
29 | 29 |
30 (defvar rmail-output-file-alist nil | 30 (defvar rmail-output-file-alist nil |
31 "*Alist matching regexps to suggested output Rmail files. | 31 "*Alist matching regexps to suggested output Rmail files. |
32 This is a list of elements of the form (REGEXP . FILENAME).") | 32 This is a list of elements of the form (REGEXP . NAME-EXP). |
33 NAME-EXP may be a string constant giving the file name to use, | |
34 or more generally it may be any kind of expression that returns | |
35 a file name as a string.") | |
33 | 36 |
34 ;;; There are functions elsewhere in Emacs that use this function; check | 37 ;;; There are functions elsewhere in Emacs that use this function; check |
35 ;;; them out before you change the calling method. | 38 ;;; them out before you change the calling method. |
36 (defun rmail-output-to-rmail-file (file-name &optional count) | 39 (defun rmail-output-to-rmail-file (file-name &optional count) |
37 "Append the current message to an Rmail file named FILE-NAME. | 40 "Append the current message to an Rmail file named FILE-NAME. |
38 If the file does not exist, ask if it should be created. | 41 If the file does not exist, ask if it should be created. |
39 If file is being visited, the message is appended to the Emacs | 42 If file is being visited, the message is appended to the Emacs |
40 buffer visiting that file. | 43 buffer visiting that file. |
44 If the file exists and is not an Rmail file, | |
45 the message is appended in inbox format. | |
46 | |
41 A prefix argument N says to output N consecutive messages | 47 A prefix argument N says to output N consecutive messages |
42 starting with the current one. Deleted messages are skipped and don't count." | 48 starting with the current one. Deleted messages are skipped and don't count." |
43 (interactive | 49 (interactive |
44 (let ((default-file | 50 (let ((default-file |
45 (let (answer tail) | 51 (let (answer tail) |
47 ;; Suggest a file based on a pattern match. | 53 ;; Suggest a file based on a pattern match. |
48 (while (and tail (not answer)) | 54 (while (and tail (not answer)) |
49 (save-excursion | 55 (save-excursion |
50 (goto-char (point-min)) | 56 (goto-char (point-min)) |
51 (if (re-search-forward (car (car tail)) nil t) | 57 (if (re-search-forward (car (car tail)) nil t) |
52 (setq answer (cdr (car tail)))) | 58 (setq answer (eval (cdr (car tail))))) |
53 (setq tail (cdr tail)))) | 59 (setq tail (cdr tail)))) |
54 ;; If not suggestions, use same file as last time. | 60 ;; If not suggestions, use same file as last time. |
55 (or answer rmail-last-rmail-file)))) | 61 (or answer rmail-last-rmail-file)))) |
56 (list (read-file-name | 62 (list (read-file-name |
57 (concat "Output message to Rmail file: (default " | 63 (concat "Output message to Rmail file: (default " |
62 (prefix-numeric-value current-prefix-arg)))) | 68 (prefix-numeric-value current-prefix-arg)))) |
63 (or count (setq count 1)) | 69 (or count (setq count 1)) |
64 (setq file-name | 70 (setq file-name |
65 (expand-file-name file-name | 71 (expand-file-name file-name |
66 (file-name-directory rmail-last-rmail-file))) | 72 (file-name-directory rmail-last-rmail-file))) |
67 (setq rmail-last-rmail-file file-name) | 73 (if (and (file-readable-p file-name) (not (rmail-file-p file-name))) |
68 (rmail-maybe-set-message-counters) | 74 (rmail-output file-name count) |
69 (setq file-name (abbreviate-file-name file-name)) | 75 (setq rmail-last-rmail-file file-name) |
70 (or (get-file-buffer file-name) | 76 (rmail-maybe-set-message-counters) |
71 (file-exists-p file-name) | 77 (setq file-name (abbreviate-file-name file-name)) |
72 (if (yes-or-no-p | 78 (or (get-file-buffer file-name) |
73 (concat "\"" file-name "\" does not exist, create it? ")) | 79 (file-exists-p file-name) |
74 (let ((file-buffer (create-file-buffer file-name))) | 80 (if (yes-or-no-p |
75 (save-excursion | 81 (concat "\"" file-name "\" does not exist, create it? ")) |
76 (set-buffer file-buffer) | 82 (let ((file-buffer (create-file-buffer file-name))) |
77 (rmail-insert-rmail-file-header) | |
78 (let ((require-final-newline nil)) | |
79 (write-region (point-min) (point-max) file-name t 1))) | |
80 (kill-buffer file-buffer)) | |
81 (error "Output file does not exist"))) | |
82 (while (> count 0) | |
83 (let (redelete) | |
84 (unwind-protect | |
85 (progn | |
86 (save-restriction | |
87 (widen) | |
88 (if (rmail-message-deleted-p rmail-current-message) | |
89 (progn (setq redelete t) | |
90 (rmail-set-attribute "deleted" nil))) | |
91 ;; Decide whether to append to a file or to an Emacs buffer. | |
92 (save-excursion | 83 (save-excursion |
93 (let ((buf (get-file-buffer file-name)) | 84 (set-buffer file-buffer) |
94 (cur (current-buffer)) | 85 (rmail-insert-rmail-file-header) |
95 (beg (1+ (rmail-msgbeg rmail-current-message))) | 86 (let ((require-final-newline nil)) |
96 (end (1+ (rmail-msgend rmail-current-message)))) | 87 (write-region (point-min) (point-max) file-name t 1))) |
97 (if (not buf) | 88 (kill-buffer file-buffer)) |
98 (append-to-file beg end file-name) | 89 (error "Output file does not exist"))) |
99 (if (eq buf (current-buffer)) | 90 (while (> count 0) |
100 (error "Can't output message to same file it's already in")) | 91 (let (redelete) |
101 ;; File has been visited, in buffer BUF. | 92 (unwind-protect |
102 (set-buffer buf) | 93 (progn |
103 (let ((buffer-read-only nil) | 94 (save-restriction |
104 (msg (and (boundp 'rmail-current-message) | 95 (widen) |
105 rmail-current-message))) | 96 (if (rmail-message-deleted-p rmail-current-message) |
106 ;; If MSG is non-nil, buffer is in RMAIL mode. | 97 (progn (setq redelete t) |
107 (if msg | 98 (rmail-set-attribute "deleted" nil))) |
108 (progn | 99 ;; Decide whether to append to a file or to an Emacs buffer. |
109 (rmail-maybe-set-message-counters) | 100 (save-excursion |
110 (widen) | 101 (let ((buf (get-file-buffer file-name)) |
111 (narrow-to-region (point-max) (point-max)) | 102 (cur (current-buffer)) |
112 (insert-buffer-substring cur beg end) | 103 (beg (1+ (rmail-msgbeg rmail-current-message))) |
113 (goto-char (point-min)) | 104 (end (1+ (rmail-msgend rmail-current-message)))) |
114 (widen) | 105 (if (not buf) |
115 (search-backward "\n\^_") | 106 (append-to-file beg end file-name) |
116 (narrow-to-region (point) (point-max)) | 107 (if (eq buf (current-buffer)) |
117 (rmail-count-new-messages t) | 108 (error "Can't output message to same file it's already in")) |
118 (rmail-show-message msg)) | 109 ;; File has been visited, in buffer BUF. |
119 ;; Output file not in rmail mode => just insert at the end. | 110 (set-buffer buf) |
120 (narrow-to-region (point-min) (1+ (buffer-size))) | 111 (let ((buffer-read-only nil) |
121 (goto-char (point-max)) | 112 (msg (and (boundp 'rmail-current-message) |
122 (insert-buffer-substring cur beg end))))))) | 113 rmail-current-message))) |
123 (rmail-set-attribute "filed" t)) | 114 ;; If MSG is non-nil, buffer is in RMAIL mode. |
124 (if redelete (rmail-set-attribute "deleted" t)))) | 115 (if msg |
125 (setq count (1- count)) | 116 (progn |
126 (if rmail-delete-after-output | 117 (rmail-maybe-set-message-counters) |
127 (rmail-delete-forward) | 118 (widen) |
128 (if (> count 0) | 119 (narrow-to-region (point-max) (point-max)) |
129 (rmail-next-undeleted-message 1))))) | 120 (insert-buffer-substring cur beg end) |
121 (goto-char (point-min)) | |
122 (widen) | |
123 (search-backward "\n\^_") | |
124 (narrow-to-region (point) (point-max)) | |
125 (rmail-count-new-messages t) | |
126 (rmail-show-message msg)) | |
127 ;; Output file not in rmail mode => just insert at the end. | |
128 (narrow-to-region (point-min) (1+ (buffer-size))) | |
129 (goto-char (point-max)) | |
130 (insert-buffer-substring cur beg end))))))) | |
131 (rmail-set-attribute "filed" t)) | |
132 (if redelete (rmail-set-attribute "deleted" t)))) | |
133 (setq count (1- count)) | |
134 (if rmail-delete-after-output | |
135 (rmail-delete-forward) | |
136 (if (> count 0) | |
137 (rmail-next-undeleted-message 1)))))) | |
138 | |
139 ;; Returns t if file FILE is an Rmail file. | |
140 (defun rmail-file-p (file) | |
141 (let ((buf (generate-new-buffer " *rmail-file-p*"))) | |
142 (unwind-protect | |
143 (save-excursion | |
144 (set-buffer buf) | |
145 (insert-file-contents file nil 0 100) | |
146 (looking-at "BABYL OPTIONS:")) | |
147 (kill-buffer buf)))) | |
130 | 148 |
131 ;;; There are functions elsewhere in Emacs that use this function; check | 149 ;;; There are functions elsewhere in Emacs that use this function; check |
132 ;;; them out before you change the calling method. | 150 ;;; them out before you change the calling method. |
133 (defun rmail-output (file-name &optional count) | 151 (defun rmail-output (file-name &optional count) |
134 "Append this message to Unix mail file named FILE-NAME. | 152 "Append this message to Unix mail file named FILE-NAME. |
149 (or count (setq count 1)) | 167 (or count (setq count 1)) |
150 (setq file-name | 168 (setq file-name |
151 (expand-file-name file-name | 169 (expand-file-name file-name |
152 (and rmail-last-file | 170 (and rmail-last-file |
153 (file-name-directory rmail-last-file)))) | 171 (file-name-directory rmail-last-file)))) |
154 (setq rmail-last-file file-name) | 172 (if (and (file-readable-p file) (rmail-file-p file-name)) |
155 (while (> count 0) | 173 (rmail-output-to-rmail-file file-name count) |
156 (let ((rmailbuf (current-buffer)) | 174 (setq rmail-last-file file-name) |
157 (tembuf (get-buffer-create " rmail-output")) | 175 (while (> count 0) |
158 (case-fold-search t)) | 176 (let ((rmailbuf (current-buffer)) |
159 (save-excursion | 177 (tembuf (get-buffer-create " rmail-output")) |
160 (set-buffer tembuf) | 178 (case-fold-search t)) |
161 (erase-buffer) | 179 (save-excursion |
162 ;; If we can do it, read a little of the file | 180 (set-buffer tembuf) |
163 ;; to check whether it is an RMAIL file. | 181 (erase-buffer) |
164 ;; If it is, don't mess it up. | 182 (insert-buffer-substring rmailbuf) |
165 (and (file-readable-p file-name) | 183 (insert "\n") |
166 (progn (insert-file-contents file-name nil 0 20) | 184 (goto-char (point-min)) |
167 (looking-at "BABYL OPTIONS:\n")) | 185 (insert "From " |
168 (error (save-excursion | 186 (mail-strip-quoted-names (or (mail-fetch-field "from") |
169 (set-buffer rmailbuf) | 187 (mail-fetch-field "really-from") |
170 (substitute-command-keys | 188 (mail-fetch-field "sender") |
171 "Use \\[rmail-output-to-rmail-file] to output to Rmail file `%s'")) | 189 "unknown")) |
172 (file-name-nondirectory file-name))) | 190 " " (current-time-string) "\n") |
173 (erase-buffer) | 191 ;; ``Quote'' "\nFrom " as "\n>From " |
174 (insert-buffer-substring rmailbuf) | 192 ;; (note that this isn't really quoting, as there is no requirement |
175 (insert "\n") | 193 ;; that "\n[>]+From " be quoted in the same transparent way.) |
176 (goto-char (point-min)) | 194 (while (search-forward "\nFrom " nil t) |
177 (insert "From " | 195 (forward-char -5) |
178 (mail-strip-quoted-names (or (mail-fetch-field "from") | 196 (insert ?>)) |
179 (mail-fetch-field "really-from") | 197 (append-to-file (point-min) (point-max) file-name)) |
180 (mail-fetch-field "sender") | 198 (kill-buffer tembuf)) |
181 "unknown")) | 199 (if (equal major-mode 'rmail-mode) |
182 " " (current-time-string) "\n") | 200 (rmail-set-attribute "filed" t)) |
183 ;; ``Quote'' "\nFrom " as "\n>From " | 201 (setq count (1- count)) |
184 ;; (note that this isn't really quoting, as there is no requirement | 202 (if rmail-delete-after-output |
185 ;; that "\n[>]+From " be quoted in the same transparent way.) | 203 (rmail-delete-forward) |
186 (while (search-forward "\nFrom " nil t) | 204 (if (> count 0) |
187 (forward-char -5) | 205 (rmail-next-undeleted-message 1))))) |
188 (insert ?>)) | |
189 (append-to-file (point-min) (point-max) file-name)) | |
190 (kill-buffer tembuf)) | |
191 (if (equal major-mode 'rmail-mode) | |
192 (rmail-set-attribute "filed" t)) | |
193 (setq count (1- count)) | |
194 (if rmail-delete-after-output | |
195 (rmail-delete-forward) | |
196 (if (> count 0) | |
197 (rmail-next-undeleted-message 1))))) | |
198 | 206 |
199 ;;; rmailout.el ends here | 207 ;;; rmailout.el ends here |