Mercurial > hg > xemacs-beta
comparison lisp/tm/tmh-comp.el @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | |
children | 4b173ad71786 |
comparison
equal
deleted
inserted
replaced
3:30df88044ec6 | 4:b82b59fe008d |
---|---|
1 ;;; tm-mh-e.el --- tm-mh-e functions for composing messages | |
2 | |
3 ;; Copyright (C) 1993,1994,1995,1996 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp> | |
6 ;; OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp> | |
7 ;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp> | |
8 ;; Created: 1996/2/29 (separated from tm-mh-e.el) | |
9 ;; Version: $Id: tmh-comp.el,v 1.1.1.1 1996/12/18 03:55:32 steve Exp $ | |
10 ;; Keywords: mail, MH, MIME, multimedia, encoded-word, multilingual | |
11 | |
12 ;; This file is part of tm (Tools for MIME). | |
13 | |
14 ;; This program is free software; you can redistribute it and/or | |
15 ;; modify it under the terms of the GNU General Public License as | |
16 ;; published by the Free Software Foundation; either version 2, or (at | |
17 ;; your option) any later version. | |
18 | |
19 ;; This program is distributed in the hope that it will be useful, but | |
20 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 ;; General Public License for more details. | |
23 | |
24 ;; You should have received a copy of the GNU General Public License | |
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
27 ;; Boston, MA 02111-1307, USA. | |
28 | |
29 ;;; Code: | |
30 | |
31 (require 'mh-comp) | |
32 (require 'tm-edit) | |
33 | |
34 | |
35 ;;; @ variable | |
36 ;;; | |
37 | |
38 (defvar tm-mh-e/forwcomps "forwcomps" | |
39 "Name of file to be used as a skeleton for forwarding messages. | |
40 Default is \"forwcomps\". If not a complete path name, the file | |
41 is searched for first in the user's MH directory, then in the | |
42 system MH lib directory.") | |
43 | |
44 (defvar tm-mh-e/message-yank-function 'mh-yank-cur-msg) | |
45 | |
46 | |
47 ;;; @ for tm-edit | |
48 ;;; | |
49 | |
50 (defun tm-mh-e::make-message (folder number) | |
51 (vector folder number) | |
52 ) | |
53 | |
54 (defun tm-mh-e::message/folder (message) | |
55 (elt message 0) | |
56 ) | |
57 | |
58 (defun tm-mh-e::message/number (message) | |
59 (elt message 1) | |
60 ) | |
61 | |
62 (defun tm-mh-e::message/file-name (message) | |
63 (expand-file-name | |
64 (tm-mh-e::message/number message) | |
65 (mh-expand-file-name (tm-mh-e::message/folder message)) | |
66 )) | |
67 | |
68 ;;; modified by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp> | |
69 ;;; 1995/11/14 (cf. [tm-ja:1096]) | |
70 (defun tm-mh-e/prompt-for-message (prompt folder &optional default) | |
71 (let* ((files | |
72 (directory-files (mh-expand-file-name folder) nil "^[0-9]+$") | |
73 ) | |
74 (folder-buf (get-buffer folder)) | |
75 (default | |
76 (if folder-buf | |
77 (save-excursion | |
78 (set-buffer folder-buf) | |
79 (let* ((show-buffer (get-buffer mh-show-buffer)) | |
80 (show-buffer-file-name | |
81 (buffer-file-name show-buffer))) | |
82 (if show-buffer-file-name | |
83 (file-name-nondirectory show-buffer-file-name))))))) | |
84 (if (or (null default) | |
85 (not (string-match "^[0-9]+$" default))) | |
86 (setq default | |
87 (if (and (string= folder mh-sent-from-folder) | |
88 mh-sent-from-msg) | |
89 (int-to-string mh-sent-from-msg) | |
90 (save-excursion | |
91 (let (cur-msg) | |
92 (if (and | |
93 (= 0 (mh-exec-cmd-quiet nil "pick" folder "cur")) | |
94 (set-buffer mh-temp-buffer) | |
95 (setq cur-msg (buffer-string)) | |
96 (string-match "^[0-9]+$" cur-msg)) | |
97 (substring cur-msg 0 (match-end 0)) | |
98 (car files))))))) | |
99 (completing-read prompt | |
100 (let ((i 0)) | |
101 (mapcar (function | |
102 (lambda (file) | |
103 (setq i (+ i 1)) | |
104 (list file i) | |
105 )) | |
106 files) | |
107 ) nil nil default) | |
108 )) | |
109 | |
110 ;;; modified by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp> | |
111 ;;; 1995/11/14 (cf. [tm-ja:1096]) | |
112 (defun tm-mh-e/query-message (&optional message) | |
113 (let (folder number) | |
114 (if message | |
115 (progn | |
116 (setq folder (tm-mh-e::message/folder message)) | |
117 (setq number (tm-mh-e::message/number message)) | |
118 )) | |
119 (or (stringp folder) | |
120 (setq folder (mh-prompt-for-folder | |
121 "Message from" | |
122 (if (and (stringp mh-sent-from-folder) | |
123 (string-match "^\\+" mh-sent-from-folder)) | |
124 mh-sent-from-folder "+inbox") | |
125 nil))) | |
126 (setq number | |
127 (if (numberp number) | |
128 (number-to-string number) | |
129 (tm-mh-e/prompt-for-message "Message number: " folder) | |
130 )) | |
131 (tm-mh-e::make-message folder number) | |
132 )) | |
133 | |
134 (defun tm-mh-e/insert-message (&optional message) | |
135 ;; always ignores message | |
136 (let ((article-buffer | |
137 (if (not (and (stringp mh-sent-from-folder) | |
138 (numberp mh-sent-from-msg) | |
139 )) | |
140 (cond ((and (boundp 'gnus-original-article-buffer) | |
141 (bufferp mh-sent-from-folder) | |
142 (get-buffer gnus-original-article-buffer) | |
143 ) | |
144 gnus-original-article-buffer) | |
145 ((and (boundp 'gnus-article-buffer) | |
146 (get-buffer gnus-article-buffer) | |
147 (bufferp mh-sent-from-folder) | |
148 ) | |
149 (save-excursion | |
150 (set-buffer gnus-article-buffer) | |
151 (if (eq major-mode 'mime/viewer-mode) | |
152 mime::preview/article-buffer | |
153 (current-buffer) | |
154 ))) | |
155 )))) | |
156 (if (null article-buffer) | |
157 (tm-mh-e/insert-mail | |
158 (tm-mh-e::make-message mh-sent-from-folder mh-sent-from-msg) | |
159 ) | |
160 (insert-buffer article-buffer) | |
161 (mime-editor/inserted-message-filter) | |
162 ) | |
163 )) | |
164 | |
165 (defun tm-mh-e/insert-mail (&optional message) | |
166 (save-excursion | |
167 (save-restriction | |
168 (let ((message-file | |
169 (tm-mh-e::message/file-name (tm-mh-e/query-message message)))) | |
170 (narrow-to-region (point) (point)) | |
171 (insert-file-contents message-file) | |
172 (push-mark (point-max)) | |
173 (mime-editor/inserted-message-filter) | |
174 )))) | |
175 | |
176 (set-alist 'mime-editor/message-inserter-alist | |
177 'mh-letter-mode (function tm-mh-e/insert-message)) | |
178 (set-alist 'mime-editor/mail-inserter-alist | |
179 'mh-letter-mode (function tm-mh-e/insert-mail)) | |
180 (set-alist 'mime-editor/mail-inserter-alist | |
181 'news-reply-mode (function tm-mh-e/insert-mail)) | |
182 (set-alist | |
183 'mime-editor/split-message-sender-alist | |
184 'mh-letter-mode | |
185 (function | |
186 (lambda (&optional arg) | |
187 (interactive "P") | |
188 (write-region (point-min) (point-max) | |
189 mime-editor/draft-file-name nil 'no-message) | |
190 (cond (arg | |
191 (pop-to-buffer "MH mail delivery") | |
192 (erase-buffer) | |
193 (mh-exec-cmd-output mh-send-prog t "-watch" "-nopush" | |
194 "-nodraftfolder" | |
195 mh-send-args | |
196 mime-editor/draft-file-name) | |
197 (goto-char (point-max)) ; show the interesting part | |
198 (recenter -1) | |
199 (sit-for 1)) | |
200 (t | |
201 (apply 'mh-exec-cmd-quiet t mh-send-prog | |
202 (mh-list-to-string | |
203 (list "-nopush" "-nodraftfolder" | |
204 "-noverbose" "-nowatch" | |
205 mh-send-args mime-editor/draft-file-name))))) | |
206 ))) | |
207 | |
208 | |
209 ;;; @ commands using tm-edit features | |
210 ;;; | |
211 | |
212 (defun tm-mh-e/edit-again (msg) | |
213 "Clean-up a draft or a message previously sent and make it resendable. | |
214 Default is the current message. | |
215 The variable mh-new-draft-cleaned-headers specifies the headers to remove. | |
216 See also documentation for `\\[mh-send]' function." | |
217 (interactive (list (mh-get-msg-num t))) | |
218 (catch 'tag | |
219 (let* ((from-folder mh-current-folder) | |
220 (config (current-window-configuration)) | |
221 code-conversion | |
222 (draft | |
223 (cond ((and mh-draft-folder (equal from-folder mh-draft-folder)) | |
224 (let ((name (format "draft-%d" msg))) | |
225 (if (get-buffer name) | |
226 (throw 'tag (pop-to-buffer name)) | |
227 ) | |
228 (let ((file-coding-system-for-read *noconv*) | |
229 (filename | |
230 (mh-msg-filename msg mh-draft-folder) | |
231 )) | |
232 (set-buffer (get-buffer-create name)) | |
233 (insert-file-contents filename) | |
234 (setq buffer-file-name filename) | |
235 (setq code-conversion t) | |
236 ) | |
237 (pop-to-buffer name) | |
238 (if (re-search-forward "^-+$" nil t) | |
239 (replace-match "") | |
240 ) | |
241 name)) | |
242 (t | |
243 (prog1 | |
244 (let ((file-coding-system-for-read *noconv*)) | |
245 (mh-read-draft "clean-up" (mh-msg-filename msg) nil) | |
246 ) | |
247 (setq code-conversion t) | |
248 )))) | |
249 ) | |
250 (goto-char (point-min)) | |
251 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil) | |
252 (if code-conversion | |
253 (let ((cs (detect-coding-region (point-min)(point-max)))) | |
254 (set-buffer-file-coding-system | |
255 (if (listp cs) | |
256 (car cs) | |
257 cs)) | |
258 )) | |
259 (save-buffer) | |
260 (mime/edit-again code-conversion t t) | |
261 (goto-char (point-min)) | |
262 (mh-compose-and-send-mail draft "" from-folder nil nil nil nil nil nil | |
263 config) | |
264 ))) | |
265 | |
266 ;;; by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp> | |
267 ;;; 1996/2/29 (cf. [tm-ja:1643]) | |
268 (defun tm-mh-e/extract-rejected-mail (msg) | |
269 "Extract a letter returned by the mail system and make it re-editable. | |
270 Default is the current message. The variable mh-new-draft-cleaned-headers | |
271 gives the headers to clean out of the original message." | |
272 (interactive (list (mh-get-msg-num t))) | |
273 (let ((from-folder mh-current-folder) | |
274 (config (current-window-configuration)) | |
275 (draft (mh-read-draft "extraction" (mh-msg-filename msg) nil))) | |
276 (setq buffer-read-only nil) | |
277 (goto-char (point-min)) | |
278 (cond | |
279 ((and | |
280 (re-search-forward | |
281 (concat "^\\($\\|[Cc]ontent-[Tt]ype:[ \t]+multipart/\\)") nil t) | |
282 (not (bolp)) | |
283 (re-search-forward "boundary=\"\\([^\"]+\\)\"" nil t)) | |
284 (let ((case-fold-search t) | |
285 (boundary (buffer-substring (match-beginning 1) (match-end 1)))) | |
286 (cond | |
287 ((re-search-forward | |
288 (concat "^--" boundary "\n" | |
289 "content-type:[ \t]+" | |
290 "\\(message/rfc822\\|text/rfc822-headers\\)\n" | |
291 "\\(.+\n\\)*\n") nil t) | |
292 (delete-region (point-min) (point)) | |
293 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil) | |
294 (search-forward | |
295 (concat "\n--" boundary "--\n") nil t) | |
296 (delete-region (match-beginning 0) (point-max))) | |
297 (t | |
298 (message "Seems no message/rfc822 part."))))) | |
299 ((re-search-forward mh-rejected-letter-start nil t) | |
300 (skip-chars-forward " \t\n") | |
301 (delete-region (point-min) (point)) | |
302 (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil)) | |
303 (t | |
304 (message "Does not appear to be a rejected letter."))) | |
305 (goto-char (point-min)) | |
306 (if (re-search-forward "^-+$" nil t) | |
307 (replace-match "") | |
308 ) | |
309 (mime/edit-again nil t t) | |
310 (goto-char (point-min)) | |
311 (set-buffer-modified-p nil) | |
312 (mh-compose-and-send-mail draft "" from-folder msg | |
313 (mh-get-header-field "To:") | |
314 (mh-get-header-field "From:") | |
315 (mh-get-header-field "Cc:") | |
316 nil nil config))) | |
317 | |
318 ;;; by OKABE Yasuo <okabe@kudpc.kyoto-u.ac.jp> | |
319 ;;; 1995/11/14 (cf. [tm-ja:1099]) | |
320 (defun tm-mh-e/forward (to cc &optional msg-or-seq) | |
321 "Forward a message or message sequence as MIME message/rfc822. | |
322 Defaults to displayed message. If optional prefix argument provided, | |
323 then prompt for the message sequence. See also documentation for | |
324 `\\[mh-send]' function." | |
325 (interactive (list (mh-read-address "To: ") | |
326 (mh-read-address "Cc: ") | |
327 (if current-prefix-arg | |
328 (mh-read-seq-default "Forward" t) | |
329 (mh-get-msg-num t) | |
330 ))) | |
331 (or msg-or-seq | |
332 (setq msg-or-seq (mh-get-msg-num t))) | |
333 (let* ((folder mh-current-folder) | |
334 (config (current-window-configuration)) | |
335 ;; uses "draft" for compatibility with forw. | |
336 ;; forw always leaves file in "draft" since it doesn't have -draft | |
337 (draft-name (expand-file-name "draft" mh-user-path)) | |
338 (draft (cond ((or (not (file-exists-p draft-name)) | |
339 (y-or-n-p "The file `draft' exists. Discard it? ")) | |
340 (mh-exec-cmd "comp" | |
341 "-noedit" "-nowhatnowproc" | |
342 "-form" tm-mh-e/forwcomps | |
343 "-nodraftfolder") | |
344 (prog1 | |
345 (mh-read-draft "" draft-name t) | |
346 (mh-insert-fields "To:" to "Cc:" cc) | |
347 (set-buffer-modified-p nil))) | |
348 (t | |
349 (mh-read-draft "" draft-name nil))))) | |
350 (let ((msubtype "digest") | |
351 orig-from orig-subject multipart-flag | |
352 (tag-regexp | |
353 (concat "^" | |
354 (regexp-quote (mime-make-tag "message" "rfc822")))) | |
355 ) | |
356 (goto-char (point-min)) | |
357 (save-excursion | |
358 (save-restriction | |
359 (goto-char (point-max)) | |
360 (if (not (bolp)) (insert "\n")) | |
361 (let ((beg (point))) | |
362 (narrow-to-region beg beg) | |
363 (mh-exec-cmd-output "pick" nil folder msg-or-seq) | |
364 (if (> (count-lines (point) (point-max)) 1) | |
365 (setq multipart-flag t) | |
366 ) | |
367 (while (re-search-forward "^\\([0-9]+\\)\n" nil t) | |
368 (let ((forw-msg | |
369 (buffer-substring (match-beginning 1) (match-end 1))) | |
370 (beg (match-beginning 0)) | |
371 (end (match-end 0)) | |
372 ) | |
373 (save-restriction | |
374 (narrow-to-region beg end) | |
375 ;; modified for Emacs 18 | |
376 (delete-region beg end) | |
377 (insert-file-contents | |
378 (mh-expand-file-name forw-msg | |
379 (mh-expand-file-name folder)) | |
380 ) | |
381 (save-excursion | |
382 (push-mark (point-max)) | |
383 (mime-editor/inserted-message-filter)) | |
384 (goto-char (point-max)) | |
385 ) | |
386 (save-excursion | |
387 (goto-char beg) | |
388 (mime-editor/insert-tag "message" "rfc822") | |
389 ))) | |
390 (delete-region (point) (point-max)) | |
391 (if multipart-flag | |
392 (mime-editor/enclose-region "digest" beg (point)) | |
393 )))) | |
394 (re-search-forward tag-regexp) | |
395 (forward-line 1) | |
396 (save-restriction | |
397 (narrow-to-region (point) (point-max)) | |
398 (setq orig-from (mime-eword/decode-string | |
399 (mh-get-header-field "From:"))) | |
400 (setq orig-subject (mime-eword/decode-string | |
401 (mh-get-header-field "Subject:"))) | |
402 ) | |
403 (let ((forw-subject | |
404 (mh-forwarded-letter-subject orig-from orig-subject))) | |
405 (mh-insert-fields "Subject:" forw-subject) | |
406 (goto-char (point-min)) | |
407 (re-search-forward tag-regexp) | |
408 (forward-line -1) | |
409 (delete-other-windows) | |
410 (if (numberp msg-or-seq) | |
411 (mh-add-msgs-to-seq msg-or-seq 'forwarded t) | |
412 (mh-add-msgs-to-seq (mh-seq-to-msgs msg-or-seq) 'forwarded t)) | |
413 (mh-compose-and-send-mail draft "" folder msg-or-seq | |
414 to forw-subject cc | |
415 mh-note-forw "Forwarded:" | |
416 config))))) | |
417 | |
418 (cond ((not (featurep 'mh-utils)) | |
419 (defun tm-mh-e::insert-letter (folder number verbatim) | |
420 (mh-insert-letter verbatim folder number) | |
421 ) | |
422 ) | |
423 ((and (boundp 'mh-e-version) | |
424 (string-lessp mh-e-version "5")) | |
425 (defun tm-mh-e::insert-letter (folder number verbatim) | |
426 (mh-insert-letter number folder verbatim) | |
427 ) | |
428 ) | |
429 (t | |
430 (defalias 'tm-mh-e::insert-letter 'mh-insert-letter) | |
431 )) | |
432 | |
433 (defun tm-mh-e/insert-letter (verbatim) | |
434 "Interface to mh-insert-letter." | |
435 (interactive "P") | |
436 (let* | |
437 ((folder (mh-prompt-for-folder | |
438 "Message from" | |
439 (if (and (stringp mh-sent-from-folder) | |
440 (string-match "^\\+" mh-sent-from-folder)) | |
441 mh-sent-from-folder "+inbox") | |
442 nil)) | |
443 (number (tm-mh-e/prompt-for-message "Message number: " folder))) | |
444 (tm-mh-e::insert-letter folder number verbatim))) | |
445 | |
446 (defun tm-mh-e/yank-cur-msg-with-no-filter () | |
447 "Insert the current message into the draft buffer. | |
448 This function makes new show-buffer from article-buffer to disable | |
449 variable `mime-viewer/plain-text-preview-hook'. If you don't want to | |
450 use text filters for replying message, please set it to | |
451 `tm-mh-e/message-yank-function'. | |
452 Prefix each non-blank line in the message with the string in | |
453 `mh-ins-buf-prefix'. The entire message will be inserted if | |
454 `mh-yank-from-start-of-msg' is non-nil. If this variable is nil, the | |
455 portion of the message following the point will be yanked. If | |
456 `mh-delete-yanked-msg-window' is non-nil, any window displaying the | |
457 yanked message will be deleted." | |
458 (interactive) | |
459 (if (and mh-sent-from-folder mh-sent-from-msg) | |
460 (let ((to-point (point)) | |
461 (to-buffer (current-buffer))) | |
462 (set-buffer mh-sent-from-folder) | |
463 (if mh-delete-yanked-msg-window | |
464 (delete-windows-on mh-show-buffer)) | |
465 (set-buffer mh-show-buffer) ; Find displayed message | |
466 (let ((mh-ins-str | |
467 (let (mime-viewer/plain-text-preview-hook buf) | |
468 (prog1 | |
469 (save-window-excursion | |
470 (set-buffer mime::preview/article-buffer) | |
471 (setq buf (mime/viewer-mode)) | |
472 (buffer-string) | |
473 ) | |
474 (kill-buffer buf))))) | |
475 (set-buffer to-buffer) | |
476 (save-restriction | |
477 (narrow-to-region to-point to-point) | |
478 (push-mark) | |
479 (insert mh-ins-str) | |
480 (mh-insert-prefix-string mh-ins-buf-prefix) | |
481 (insert "\n")))) | |
482 (error "There is no current message"))) | |
483 | |
484 (defun tm-mh-e/yank-current-message () | |
485 "Insert the current message into the draft buffer. | |
486 It uses variable `tm-mh-e/message-yank-function' | |
487 to select message yanking function." | |
488 (interactive) | |
489 (let ((mh-sent-from-folder mh-sent-from-folder) | |
490 (mh-sent-from-msg mh-sent-from-msg)) | |
491 (if (and (not (stringp mh-sent-from-folder)) | |
492 (boundp 'gnus-article-buffer) | |
493 (get-buffer gnus-article-buffer) | |
494 (bufferp mh-sent-from-folder) | |
495 ) ; might be called from GNUS | |
496 (if (boundp 'gnus-article-copy) ; might be sgnus | |
497 (save-excursion | |
498 (gnus-copy-article-buffer) | |
499 (setq mh-sent-from-folder gnus-article-copy) | |
500 (set-buffer mh-sent-from-folder) | |
501 (setq mh-show-buffer gnus-article-copy) | |
502 ) | |
503 (save-excursion | |
504 (setq mh-sent-from-folder gnus-article-buffer) | |
505 (set-buffer gnus-article-buffer) | |
506 (setq mh-show-buffer (current-buffer)) | |
507 ))) | |
508 (funcall tm-mh-e/message-yank-function) | |
509 )) | |
510 | |
511 (substitute-key-definition | |
512 'mh-yank-cur-msg 'tm-mh-e/yank-current-message mh-letter-mode-map) | |
513 (substitute-key-definition | |
514 'mh-insert-letter 'tm-mh-e/insert-letter mh-letter-mode-map) | |
515 | |
516 | |
517 ;;; @ end | |
518 ;;; | |
519 | |
520 (provide 'tmh-comp) | |
521 (require 'tm-mh-e) | |
522 | |
523 ;;; tmh-comp.el ends here |