X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=mh-e%2Ftm-mh-e.el;h=22ed96a28991a571bcdeb0b8b69e980edc0bdbb8;hb=416390ffbb6dd1cc5d4c836e4e02244afeed7a73;hp=48d700ff7b2e2b088def3893d60d62b2b73f5533;hpb=ef0035d27cdabdbcd3c17bdcd442e33f336ee09e;p=elisp%2Ftm.git diff --git a/mh-e/tm-mh-e.el b/mh-e/tm-mh-e.el index 48d700f..22ed96a 100644 --- a/mh-e/tm-mh-e.el +++ b/mh-e/tm-mh-e.el @@ -1,66 +1,305 @@ ;;; -;;; A MIME extender for mh-e +;;; tm-mh-e.el --- MIME extender for mh-e ;;; -;;; by Morioka Tomohiko, 1993/11/21 +;;; Copyright (C) 1995 Free Software Foundation, Inc. +;;; Copyright (C) 1993,1994,1995 MORIOKA Tomohiko +;;; +;;; Author: MORIOKA Tomohiko +;;; OKABE Yasuo ;;; modified by YAMAOKA Katsumi +;;; Maintainer: MORIOKA Tomohiko +;;; Created: 1993/11/21 (obsolete mh-e-mime.el) +;;; Version: $Revision: 7.50 $ +;;; Keywords: mail, MH, MIME, multimedia, encoded-word, multilingual ;;; - - -;;; @ require modules +;;; This file is part of tm (Tools for MIME). +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 2, or +;;; (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with This program. If not, write to the Free Software +;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ;;; +;;; Code: + (require 'tl-str) (require 'tl-misc) -(require 'tm-misc) (require 'mh-e) (if (not (boundp 'mh-e-version)) (require 'tm-mh-e3) ) -(autoload 'mime/viewer-mode "tm-view" "View MIME message." t) +(require 'tm-view) + +(or (fboundp 'mh-get-header-field) + (defalias 'mh-get-header-field 'mh-get-field) + ) ;;; @ version ;;; + (defconst tm-mh-e/RCS-ID - "$Id: tm-mh-e.el,v 6.3 1995/04/23 20:59:27 morioka Exp $") + "$Id: tm-mh-e.el,v 7.50 1996/02/26 08:41:56 morioka Exp $") (defconst tm-mh-e/version (get-version-string tm-mh-e/RCS-ID)) -;;; @ MIME header decoding mode +;;; @ variable +;;; + +(defvar tm-mh-e/automatic-mime-preview t + "*If non-nil, show MIME processed message.") + +(defvar tm-mh-e/decode-encoded-word t + "*If non-nil, decode encoded-word when it is not MIME preview mode.") + +(defvar tm-mh-e/forwcomps "forwcomps" + "Name of file to be used as a skeleton for forwarding messages. +Default is \"forwcomps\". If not a complete path name, the file +is searched for first in the user's MH directory, then in the +system MH lib directory.") + + +;;; @ functions +;;; + +(if (not (fboundp 'tm-mh-e/original-mh-display-msg)) + (fset 'tm-mh-e/original-mh-display-msg + (symbol-function 'mh-display-msg)) + ) + +(defun mh-display-msg (msg-num folder &optional show-buffer mode) + (or mode + (setq mode tm-mh-e/automatic-mime-preview) + ) + ;; Display message NUMBER of FOLDER. + ;; Sets the current buffer to the show buffer. + (set-buffer folder) + (or show-buffer + (setq show-buffer mh-show-buffer)) + ;; Bind variables in folder buffer in case they are local + (let ((msg-filename (mh-msg-filename msg-num))) + (if (not (file-exists-p msg-filename)) + (error "Message %d does not exist" msg-num)) + (set-buffer show-buffer) + (cond ((not (equal msg-filename buffer-file-name)) + ;; Buffer does not yet contain message. + (clear-visited-file-modtime) + (unlock-buffer) + (setq buffer-file-name nil) ; no locking during setup + (setq buffer-read-only nil) + (erase-buffer) + (if mode + (let* ((aname (concat "article-" folder)) + (abuf (get-buffer aname)) + ) + (if abuf + (progn + (set-buffer abuf) + (setq buffer-read-only nil) + (erase-buffer) + ) + (setq abuf (get-buffer-create aname)) + (set-buffer abuf) + ) + (let ((file-coding-system-for-read + (if (boundp 'MULE) *noconv*)) + kanji-fileio-code) + (insert-file-contents msg-filename) + ;; (goto-char (point-min)) + (while (re-search-forward "\r$" nil t) + (replace-match "") + ) + ) + (set-buffer-modified-p nil) + (setq buffer-read-only t) + (setq buffer-file-name msg-filename) + (mh-show-mode) + (mime/viewer-mode nil nil nil + aname (concat "show-" folder)) + (goto-char (point-min)) + ) + (let ((clean-message-header mh-clean-message-header) + (invisible-headers mh-invisible-headers) + (visible-headers mh-visible-headers) + ) + ;; 1995/9/21 + ;; modified by ARIURA + ;; to support mhl. + (if mhl-formfile + (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear" + (if (stringp mhl-formfile) + (list "-form" mhl-formfile)) + msg-filename) + (insert-file-contents msg-filename)) + ;; end + (goto-char (point-min)) + (cond (clean-message-header + (mh-clean-msg-header (point-min) + invisible-headers + visible-headers) + (goto-char (point-min))) + (t + (mh-start-of-uncleaned-message))) + (if tm-mh-e/decode-encoded-word + (mime/decode-message-header) + ) + (set-buffer-modified-p nil) + (setq buffer-read-only t) + (setq buffer-file-name msg-filename) + (mh-show-mode) + )) + (or (eq buffer-undo-list t) ;don't save undo info for prev msgs + (setq buffer-undo-list nil)) +;;; Added by itokon (02/19/96) + (setq buffer-file-name msg-filename) ;;; -(defun tm-mh-e/toggle-header-decoding-mode (arg) - "Toggle MIME header processing. + (set-mark nil) + (setq mode-line-buffer-identification + (list (format mh-show-buffer-mode-line-buffer-id + folder msg-num))) + (set-buffer folder) + (setq mh-showing-with-headers nil))))) + +(defun tm-mh-e/view-message (&optional msg) + "MIME decode and play this message." + (interactive) + (if (or (null tm-mh-e/automatic-mime-preview) + (null (get-buffer mh-show-buffer)) + (save-excursion + (set-buffer mh-show-buffer) + (not (eq major-mode 'mime/viewer-mode)) + )) + (let ((tm-mh-e/automatic-mime-preview t)) + (mh-invalidate-show-buffer) + (mh-show-msg msg) + )) + (pop-to-buffer mh-show-buffer) + ) + +(defun tm-mh-e/toggle-decoding-mode (arg) + "Toggle MIME processing mode. With arg, turn MIME processing on if arg is positive." (interactive "P") - (setq mime/header-decoding-mode + (setq tm-mh-e/automatic-mime-preview (if (null arg) - (not mime/header-decoding-mode) + (not tm-mh-e/automatic-mime-preview) arg)) + (save-excursion + (set-buffer mh-show-buffer) + (if (null tm-mh-e/automatic-mime-preview) + (if (and mime::preview/article-buffer + (get-buffer mime::preview/article-buffer)) + (kill-buffer mime::preview/article-buffer) + ))) (mh-invalidate-show-buffer) - (mh-show-msg (mh-get-msg-num t)) + (mh-show (mh-get-msg-num t)) ) +(defun tm-mh-e/show (&optional message) + (interactive) + (mh-invalidate-show-buffer) + (mh-show message) + ) -;;; @ MIME body players -;;; -(defun tm-mh-e/view-message (arg) - "MIME decode and play this message." - (interactive "P") +(defun tm-mh-e/header-display () + (interactive) (mh-invalidate-show-buffer) - (mh-show-msg (mh-get-msg-num t)) - (pop-to-buffer mh-show-buffer t) - ;; patch for mh-narrow.el - ;; by YAMAOKA Katsumi - (if (featurep 'mh-narrow) - (widen) - ) - ;; end of patch - (mime/viewer-mode) + (let ((mime-viewer/ignored-field-regexp "^:$") + tm-mh-e/decode-encoded-word) + (mh-header-display) + )) + +(defun tm-mh-e/raw-display () + (interactive) + (mh-invalidate-show-buffer) + (let (tm-mh-e/automatic-mime-preview + tm-mh-e/decode-encoded-word) + (mh-header-display) + )) + + +;;; @ for tm-view +;;; + +(fset 'tm-mh-e/code-convert-region-to-emacs + (symbol-function 'mime/code-convert-region-to-emacs)) + +(defun tm-mh-e/content-header-filter () + (goto-char (point-min)) + (mime-preview/cut-header) + (tm-mh-e/code-convert-region-to-emacs (point-min)(point-max) + mime/default-coding-system) + (mime/decode-message-header) ) +(defun tm-mh-e/quitting-method () + (let ((win (get-buffer-window + mime/output-buffer-name)) + (buf (current-buffer)) + ) + (if win + (delete-window win) + ) + (pop-to-buffer + (let ((name (buffer-name buf))) + (substring name 5) + )) + (if (not tm-mh-e/automatic-mime-preview) + (mh-invalidate-show-buffer) + ) + (mh-show (mh-get-msg-num t)) + )) + +(defun tm-mh-e/set-window-configuration () + (save-excursion + (set-buffer mh-show-buffer) + (setq mime::preview/original-window-configuration + (current-window-configuration)) + )) + +(add-hook 'mh-show-hook 'tm-mh-e/set-window-configuration) + -;;; @ for tm-comp +;;; @ for tm-partial ;;; + +(call-after-loaded + 'tm-partial + (function + (lambda () + (set-atype 'mime/content-decoding-condition + '((type . "message/partial") + (method . mime-article/grab-message/partials) + (major-mode . mh-show-mode) + (summary-buffer-exp + . (and (or (string-match "^article-\\(.+\\)$" article-buffer) + (string-match "^show-\\(.+\\)$" article-buffer)) + (substring article-buffer + (match-beginning 1) (match-end 1)) + )) + )) + (set-alist 'tm-partial/preview-article-method-alist + 'mh-show-mode + (function + (lambda () + (let ((tm-mh-e/automatic-mime-preview t)) + (tm-mh-e/show) + )))) + ))) + + +;;; @ for tm-edit +;;; + (defun tm-mh-e::make-message (folder number) (vector folder number) ) @@ -78,11 +317,38 @@ With arg, turn MIME processing on if arg is positive." (tm-mh-e::message/number message) (mh-expand-file-name (tm-mh-e::message/folder message)) )) - -(defun tm-mh-e::prompt-for-message (prompt folder &optional default) - (let ((files - (directory-files (mh-expand-file-name folder) nil "^[0-9]+$") - )) + +;;; modified by OKABE Yasuo +;;; 1995/11/14 (cf. [tm-ja:1096]) +(defun tm-mh-e/prompt-for-message (prompt folder &optional default) + (let* ((files + (directory-files (mh-expand-file-name folder) nil "^[0-9]+$") + ) + (folder-buf (get-buffer folder)) + (default + (if folder-buf + (save-excursion + (set-buffer folder-buf) + (let* ((show-buffer (get-buffer mh-show-buffer)) + (show-buffer-file-name + (buffer-file-name show-buffer))) + (if show-buffer-file-name + (file-name-nondirectory show-buffer-file-name))))))) + (if (or (null default) + (not (string-match "^[0-9]+$" default))) + (setq default + (if (and (string= folder mh-sent-from-folder) + mh-sent-from-msg) + (int-to-string mh-sent-from-msg) + (save-excursion + (let (cur-msg) + (if (and + (= 0 (mh-exec-cmd-quiet nil "pick" folder "cur")) + (set-buffer mh-temp-buffer) + (setq cur-msg (buffer-string)) + (string-match "^[0-9]+$" cur-msg)) + (substring cur-msg 0 (match-end 0)) + (car files))))))) (completing-read prompt (let ((i 0)) (mapcar (function @@ -91,48 +357,294 @@ With arg, turn MIME processing on if arg is positive." (list file i) )) files) - )) + ) nil nil default) )) - -(defun tm-mh-e::query-message () - (let* ((folder (mh-prompt-for-folder "Visit" "+inbox" nil)) - (number (tm-mh-e::prompt-for-message "Number?" folder)) - ) + +(defun tm-mh-e/query-message (&optional message) + (let (folder number) + (if message + (progn + (setq folder (tm-mh-e::message/folder message)) + (setq number (tm-mh-e::message/number message)) + )) + (or (stringp folder) + (setq folder (mh-prompt-for-folder + "Message from" + (if (and (stringp mh-sent-from-folder) + (string-match "^\\+" mh-sent-from-folder)) + mh-sent-from-folder "+inbox") + nil))) + (setq number + (if (numberp number) + (number-to-string number) + (tm-mh-e/prompt-for-message "Message number: " folder) + )) (tm-mh-e::make-message folder number) )) +;;; end -(defun tm-mh-e::insert-message (&optional message) - (if (null message) - (setq message (tm-mh-e::query-message)) - ) - (insert-file (tm-mh-e::message/file-name message)) - ) +;;; by OKABE Yasuo +;;; 1995/11/14 (cf. [tm-ja:1099]) +(defun tm-mh-e/forward (to cc &optional msg-or-seq) + "Forward a message or message sequence as MIME message/rfc822. +Defaults to displayed message. If optional prefix argument provided, +then prompt for the message sequence. See also documentation for +`\\[mh-send]' function." + (interactive (progn + (require 'mh-comp) + (list (mh-read-address "To: ") + (mh-read-address "Cc: ") + (if current-prefix-arg + (mh-read-seq-default "Forward" t) + (mh-get-msg-num t) + )))) + (or msg-or-seq + (setq msg-or-seq (mh-get-msg-num t))) + (let* ((folder mh-current-folder) + (config (current-window-configuration)) + ;; uses "draft" for compatibility with forw. + ;; forw always leaves file in "draft" since it doesn't have -draft + (draft-name (expand-file-name "draft" mh-user-path)) + (draft (cond ((or (not (file-exists-p draft-name)) + (y-or-n-p "The file `draft' exists. Discard it? ")) + (mh-exec-cmd "comp" + "-noedit" "-nowhatnowproc" + "-form" tm-mh-e/forwcomps + "-nodraftfolder") + (prog1 + (mh-read-draft "" draft-name t) + (mh-insert-fields "To:" to "Cc:" cc) + (set-buffer-modified-p nil))) + (t + (mh-read-draft "" draft-name nil))))) + (require 'tm-edit) + (let ((msubtype "digest") + orig-from orig-subject multipart-flag + (tag-regexp + (concat "^" + (regexp-quote (mime-make-tag "message" "rfc822")))) + ) + (goto-char (point-min)) + (save-excursion + (save-restriction + (goto-char (point-max)) + (if (not (bolp)) (insert "\n")) + (let ((beg (point))) + (narrow-to-region beg beg) + (mh-exec-cmd-output "pick" nil folder msg-or-seq) + (if (> (count-lines (point) (point-max)) 1) + (setq multipart-flag t) + ) + (while (re-search-forward "^\\([0-9]+\\)\n" nil t) + (let ((forw-msg + (buffer-substring (match-beginning 1) (match-end 1))) + (beg (match-beginning 0)) + (end (match-end 0)) + ) + (save-restriction + (narrow-to-region beg end) + ;; modified for Emacs 18 + (delete-region beg end) + (insert-file-contents + (mh-expand-file-name forw-msg + (mh-expand-file-name folder)) + ) + (save-excursion + (push-mark (point-max)) + (mime-editor/inserted-message-filter)) + (goto-char (point-max)) + ) + (save-excursion + (goto-char beg) + (mime-editor/insert-tag "message" "rfc822") + ))) + (delete-region (point) (point-max)) + (if multipart-flag + (mime-editor/enclose-region "digest" beg (point)) + )))) + (re-search-forward tag-regexp) + (forward-line 1) + (save-restriction + (narrow-to-region (point) (point-max)) + (setq orig-from (mh-get-header-field "From:")) + (setq orig-subject (mh-get-header-field "Subject:"))) + (let ((forw-subject + (mh-forwarded-letter-subject orig-from orig-subject))) + (mh-insert-fields "Subject:" forw-subject) + (goto-char (point-min)) + (re-search-forward tag-regexp) + (forward-line -1) + (delete-other-windows) + (if (numberp msg-or-seq) + (mh-add-msgs-to-seq msg-or-seq 'forwarded t) + (mh-add-msgs-to-seq (mh-seq-to-msgs msg-or-seq) 'forwarded t)) + (mh-compose-and-send-mail draft "" folder msg-or-seq + to forw-subject cc + mh-note-forw "Forwarded:" + config))))) +;;; end + +(defun tm-mh-e/insert-message (&optional message) + ;; always ignores message + (let ((article-buffer + (if (not (and (stringp mh-sent-from-folder) + (numberp mh-sent-from-msg) + )) + (cond ((and (boundp 'gnus-original-article-buffer) + (bufferp mh-sent-from-folder) + (get-buffer gnus-original-article-buffer) + ) + gnus-original-article-buffer) + ((and (boundp 'gnus-article-buffer) + (get-buffer gnus-article-buffer) + (bufferp mh-sent-from-folder) + ) + (save-excursion + (set-buffer gnus-article-buffer) + (if (eq major-mode 'mime/viewer-mode) + mime::preview/article-buffer + (current-buffer) + ))) + )))) + (if (null article-buffer) + (tm-mh-e/insert-mail + (tm-mh-e::make-message mh-sent-from-folder mh-sent-from-msg) + ) + (insert-buffer article-buffer) + (mime-editor/inserted-message-filter) + ) + )) + +(defun tm-mh-e/insert-mail (&optional message) + (save-excursion + (save-restriction + (let ((message-file + (tm-mh-e::message/file-name (tm-mh-e/query-message message)))) + (narrow-to-region (point) (point)) + (insert-file-contents message-file) + (push-mark (point-max)) + (mime-editor/inserted-message-filter) + )))) (call-after-loaded - 'tm-comp + 'tm-edit (function (lambda () (set-alist - 'tm-comp/message-inserter-alist - 'mh-letter-mode (function tm-mh-e::insert-message)) + 'mime-editor/message-inserter-alist + 'mh-letter-mode (function tm-mh-e/insert-message)) + (set-alist + 'mime-editor/mail-inserter-alist + 'mh-letter-mode (function tm-mh-e/insert-mail)) + (set-alist + 'mime-editor/mail-inserter-alist + 'news-reply-mode (function tm-mh-e/insert-mail)) ))) +(defun tm-mh-e/insert-letter (verbatim) + "Interface to mh-insert-letter." + (interactive "P") + (let* + ((folder (mh-prompt-for-folder + "Message from" + (if (and (stringp mh-sent-from-folder) + (string-match "^\\+" mh-sent-from-folder)) + mh-sent-from-folder "+inbox") + nil)) + (number (tm-mh-e/prompt-for-message "Message number: " folder))) + (mh-insert-letter folder number verbatim))) -;;; @ set up -;;; +(defun tm-mh-e/yank-cur-msg () + "Interface to mh-yank-cur-msg." + (interactive) + (let ((mh-sent-from-folder mh-sent-from-folder) + (mh-sent-from-msg mh-sent-from-msg)) + (if (not (stringp mh-sent-from-folder)) + (cond ((and (boundp 'gnus-article-buffer) + (get-buffer gnus-article-buffer) + (bufferp mh-sent-from-folder) + ) ; might be called from GNUS + (if (boundp 'gnus-article-copy) ; might be sgnus + (save-excursion + (gnus-copy-article-buffer) + (setq mh-sent-from-folder gnus-article-copy) + (set-buffer mh-sent-from-folder) + (setq mh-show-buffer gnus-article-copy)) + (save-excursion + (setq mh-sent-from-folder gnus-article-buffer) + (set-buffer gnus-article-buffer) + (setq mh-show-buffer (current-buffer))))) + (t + (error "There is no current message")))) + (mh-yank-cur-msg))) -(defun tm-mh-e/decode-message-header () - (make-local-variable 'minor-mode-alist) - (mime/add-header-decoding-mode-to-mode-line) - (let ((buffer-read-only nil)) - (mime/decode-message-header-if-you-need) +(defun tm-mh-e/edit-again (msg) + (require 'mh-comp) + (interactive (list (mh-get-msg-num t))) + (let* ((from-folder mh-current-folder) + (config (current-window-configuration)) + (draft + (cond ((and mh-draft-folder (equal from-folder mh-draft-folder)) + (pop-to-buffer (find-file-noselect (mh-msg-filename msg)) t) + (if mime::preview/article-buffer + (switch-to-buffer mime::preview/article-buffer) + ) + (rename-buffer (format "draft-%d" msg)) + (buffer-name)) + (t + (let ((file-coding-system-for-read *noconv*)) + (mh-read-draft "clean-up" (mh-msg-filename msg) nil) + )) + ))) + (setq buffer-read-only nil) + (goto-char (point-min)) + (mh-clean-msg-header (point-min) mh-new-draft-cleaned-headers nil) + (if (re-search-forward "^-+$" nil t) + (replace-match "") + ) + (mime/edit-again t t) + (goto-char (point-min)) (set-buffer-modified-p nil) - )) -(add-hook 'mh-show-mode-hook - (function tm-mh-e/decode-message-header)) + (mh-compose-and-send-mail draft "" from-folder nil nil nil nil nil nil + config))) -(define-key mh-folder-mode-map "\et" 'tm-mh-e/toggle-header-decoding-mode) -(define-key mh-folder-mode-map "v" 'tm-mh-e/view-message) +(call-after-loaded + 'mime-setup + (function + (lambda () + (substitute-key-definition + 'mh-forward 'tm-mh-e/forward mh-folder-mode-map) + (call-after-loaded + 'mh-comp + (function + (lambda () + (substitute-key-definition + 'mh-yank-cur-msg 'tm-mh-e/yank-cur-msg mh-letter-mode-map) + ))) + (substitute-key-definition + 'mh-edit-again 'tm-mh-e/edit-again mh-folder-mode-map) + ))) + + +;;; @ for BBDB +;;; + +(call-after-loaded + 'bbdb + (function + (lambda () + (require 'tm-bbdb) + ))) + + +;;; @ set up +;;; + +(define-key mh-folder-mode-map "v" (function tm-mh-e/view-message)) +(define-key mh-folder-mode-map "\et" (function tm-mh-e/toggle-decoding-mode)) +(define-key mh-folder-mode-map "." (function tm-mh-e/show)) +(define-key mh-folder-mode-map "," (function tm-mh-e/header-display)) +(define-key mh-folder-mode-map "\e," (function tm-mh-e/raw-display)) (define-key mh-folder-mode-map "\r" (function (lambda () (interactive) @@ -144,5 +656,42 @@ With arg, turn MIME processing on if arg is positive." (scroll-other-window -1) ))) +(defun tm-mh-e/summary-before-quit () + (let ((buf (get-buffer mh-show-buffer))) + (if buf + (let ((the-buf (current-buffer))) + (switch-to-buffer buf) + (if (and mime::article/preview-buffer + (setq buf (get-buffer mime::article/preview-buffer)) + ) + (progn + (switch-to-buffer the-buf) + (kill-buffer buf) + ) + (switch-to-buffer the-buf) + ) + )))) + +(add-hook 'mh-before-quit-hook (function tm-mh-e/summary-before-quit)) + +(set-alist 'mime-viewer/quitting-method-alist + 'mh-show-mode + (function tm-mh-e/quitting-method)) + +(set-alist 'mime-viewer/content-header-filter-alist + 'mh-show-mode + (function tm-mh-e/content-header-filter)) + +(set-alist 'mime-viewer/code-converter-alist + 'mh-show-mode + (function tm-mh-e/code-convert-region-to-emacs)) + + +;;; @ end +;;; (provide 'tm-mh-e) + +(run-hooks 'tm-mh-e-load-hook) + +;;; tm-mh-e.el ends here