1 ;;; tm-vm.el --- tm-MUA (MIME Extension module) for VM
3 ;; Copyright (C) 1994,1995,1996 Free Software Foundation, Inc.
5 ;; Author: MASUTANI Yasuhiro <masutani@me.es.osaka-u.ac.jp>
6 ;; Kenji Wakamiya <wkenji@flab.fujitsu.co.jp>
7 ;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
8 ;; Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>
9 ;; Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
10 ;; Maintainer: Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
11 ;; Created: 1994/10/29
12 ;; Version: $Revision: 1.3 $
13 ;; Keywords: mail, MIME, multimedia, multilingual, encoded-word
15 ;; This file is part of tm (Tools for MIME).
17 ;; This program is free software; you can redistribute it and/or
18 ;; modify it under the terms of the GNU General Public License as
19 ;; published by the Free Software Foundation; either version 2, or (at
20 ;; your option) any later version.
22 ;; This program is distributed in the hope that it will be useful, but
23 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 ;; General Public License for more details.
27 ;; You should have received a copy of the GNU General Public License
28 ;; along with GNU Emacs; see the file COPYING. If not, write to the
29 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 ;; Boston, MA 02111-1307, USA.
34 ;; Please insert `(require 'tm-vm)' in your ~/.vm file.
54 ;;; @@ User customization variables
56 (defvar tm-vm/use-vm-bindings t
57 "*If t, use VM compatible keybindings in MIME Preview buffers.
58 Otherwise TM generic bindings for content extraction/playing are
61 (defvar tm-vm/attach-to-popup-menus t
62 "*If t append MIME specific commands to VM's popup menus.")
64 (defvar tm-vm/use-original-url-button t
65 "*If it is t, use original URL button instead of tm's.")
67 (defvar tm-vm/automatic-mime-preview (or (and (boundp 'vm-display-using-mime)
68 vm-display-using-mime)
70 "*If non-nil, automatically process and show MIME messages.")
72 (defvar tm-vm/strict-mime t
73 "*If nil, do MIME processing even if there is no MIME-Version field.")
75 (defvar tm-vm/use-ps-print (not (featurep 'mule))
76 "*Use Postscript printing (ps-print) to print MIME messages.")
78 (defvar tm-vm-load-hook nil
79 "*List of functions called after tm-vm is loaded.")
81 (defvar tm-vm/select-message-hook nil
82 "*List of functions called every time a message is selected.
83 tm-vm uses `vm-select-message-hook', use tm-vm/select-message-hook instead.
84 When the hooks are run current buffer is either VM folder buffer with
85 the current message delimited by (point-min) and (point-max) or the MIME
88 (defvar tm-vm/forward-message-hook vm-forward-message-hook
89 "*List of functions called after a Mail mode buffer has been
90 created to forward a message in message/rfc822 type format.
91 If `vm-forwarding-digest-type' is \"rfc1521\", tm-vm runs this
92 hook instead of `vm-forward-message-hook'.")
94 (defvar tm-vm/send-digest-hook nil
95 "*List of functions called after a Mail mode buffer has been
96 created to send a digest in multipart/digest type format.
97 If `vm-digest-send-type' is \"rfc1521\", tm-vm runs this hook
98 instead of `vm-send-digest-hook'.")
100 (defvar tm-vm/build-mime-preview-buffer-hook nil
101 "*List of functions called each time a MIME Preview buffer is built.
102 These hooks are run in the MIME-Preview buffer.")
104 ;;; @@ System/Information variables
106 (defconst tm-vm/RCS-ID
107 "$Id: tm-vm.el,v 1.3 2008-04-24 20:33:12 stephent Exp $")
108 (defconst tm-vm/version (get-version-string tm-vm/RCS-ID))
110 ; Ensure vm-menu-mail-menu gets properly defined *before* tm-vm/vm-emulation-map
111 ; since it contains a call to vm-menu-initialize-vm-mode-menu-map
112 (setq vm-menu-mail-menu
113 (let ((title (if (vm-menu-fsfemacs-menus-p)
114 (list "Mail Commands"
118 (list "Mail Commands"))))
121 (list ["Send and Exit" vm-mail-send-and-exit (vm-menu-can-send-mail-p)]
122 ["Send, Keep Composing" vm-mail-send (vm-menu-can-send-mail-p)]
123 ["Cancel" kill-buffer t]
128 [" Subject:" mail-subject t]
131 [" Reply-To:" mail-reply-to t]
132 [" Text" mail-text t]
134 ["Yank Original" vm-menu-yank-original vm-reply-list]
135 ["Fill Yanked Message" mail-fill-yanked-message t]
136 ["Insert Signature" mail-signature t]
137 ["Insert File..." insert-file t]
138 ["Insert Buffer..." insert-buffer t])
139 (if tm-vm/attach-to-popup-menus
141 (cons "MIME Commands"
142 (mapcar (function (lambda (item)
146 mime-editor/menu-list))))
149 (defvar tm-vm/vm-emulation-map
150 (let ((map (make-sparse-keymap)))
151 (define-key map "h" 'vm-summarize)
152 ;(define-key map "\M-n" 'vm-next-unread-message)
153 ;(define-key map "\M-p" 'vm-previous-unread-message)
154 (define-key map "n" 'vm-next-message)
155 (define-key map "p" 'vm-previous-message)
156 (define-key map "N" 'vm-next-message-no-skip)
157 (define-key map "P" 'vm-previous-message-no-skip)
158 ;(define-key map "\C-\M-n" 'vm-move-message-forward)
159 ;(define-key map "\C-\M-p" 'vm-move-message-backward)
160 ;(define-key map "\t" 'vm-goto-message-last-seen)
161 ;(define-key map "\r" 'vm-goto-message)
162 (define-key map "^" 'vm-goto-parent-message)
163 (define-key map "t" 'vm-expose-hidden-headers)
164 (define-key map " " 'vm-scroll-forward)
165 (define-key map "b" 'vm-scroll-backward)
166 (define-key map "\C-?" 'vm-scroll-backward)
167 (define-key map "d" 'vm-delete-message)
168 (define-key map "\C-d" 'vm-delete-message-backward)
169 (define-key map "u" 'vm-undelete-message)
170 (define-key map "U" 'vm-unread-message)
171 (define-key map "e" 'vm-edit-message)
172 ;(define-key map "a" 'vm-set-message-attributes)
173 ;(define-key map "j" 'vm-discard-cached-data)
174 ;(define-key map "k" 'vm-kill-subject)
175 (define-key map "f" 'vm-followup)
176 (define-key map "F" 'vm-followup-include-text)
177 (define-key map "r" 'vm-reply)
178 (define-key map "R" 'vm-reply-include-text)
179 (define-key map "\M-r" 'vm-resend-bounced-message)
180 (define-key map "B" 'vm-resend-message)
181 (define-key map "z" 'vm-forward-message)
182 ;(define-key map "c" 'vm-continue-composing-message)
183 (define-key map "@" 'vm-send-digest)
184 ;(define-key map "*" 'vm-burst-digest)
185 (define-key map "m" 'vm-mail)
186 (define-key map "g" 'vm-get-new-mail)
187 ;(define-key map "G" 'vm-sort-messages)
188 (define-key map "v" 'vm-visit-folder)
189 (define-key map "s" 'vm-save-message)
190 ;(define-key map "w" 'vm-save-message-sans-headers)
191 ;(define-key map "A" 'vm-auto-archive-messages)
192 (define-key map "S" 'vm-save-folder)
193 ;(define-key map "|" 'vm-pipe-message-to-command)
194 (define-key map "#" 'vm-expunge-folder)
195 (define-key map "q" 'vm-quit)
196 (define-key map "x" 'vm-quit-no-change)
197 (define-key map "i" 'vm-iconify-frame)
198 (define-key map "?" 'vm-help)
199 (define-key map "\C-_" 'vm-undo)
200 (define-key map "\C-xu" 'vm-undo)
201 (define-key map "!" 'shell-command)
202 (define-key map "<" 'vm-beginning-of-message)
203 (define-key map ">" 'vm-end-of-message)
204 ;(define-key map "\M-s" 'vm-isearch-forward)
205 (define-key map "=" 'vm-summarize)
206 (define-key map "L" 'vm-load-init-file)
207 ;(define-key map "l" (make-sparse-keymap))
208 ;(define-key map "la" 'vm-add-message-labels)
209 ;(define-key map "ld" 'vm-delete-message-labels)
210 ;(define-key map "V" (make-sparse-keymap))
211 ;(define-key map "VV" 'vm-visit-virtual-folder)
212 ;(define-key map "VC" 'vm-create-virtual-folder)
213 ;(define-key map "VA" 'vm-apply-virtual-folder)
214 ;(define-key map "VM" 'vm-toggle-virtual-mirror)
215 ;(define-key map "V?" 'vm-virtual-help)
216 ;(define-key map "M" (make-sparse-keymap))
217 ;(define-key map "MN" 'vm-next-command-uses-marks)
218 ;(define-key map "Mn" 'vm-next-command-uses-marks)
219 ;(define-key map "MM" 'vm-mark-message)
220 ;(define-key map "MU" 'vm-unmark-message)
221 ;(define-key map "Mm" 'vm-mark-all-messages)
222 ;(define-key map "Mu" 'vm-clear-all-marks)
223 ;(define-key map "MC" 'vm-mark-matching-messages)
224 ;(define-key map "Mc" 'vm-unmark-matching-messages)
225 ;(define-key map "MT" 'vm-mark-thread-subtree)
226 ;(define-key map "Mt" 'vm-unmark-thread-subtree)
227 ;(define-key map "MS" 'vm-mark-messages-same-subject)
228 ;(define-key map "Ms" 'vm-unmark-messages-same-subject)
229 ;(define-key map "MA" 'vm-mark-messages-same-author)
230 ;(define-key map "Ma" 'vm-unmark-messages-same-author)
231 ;(define-key map "M?" 'vm-mark-help)
232 ;(define-key map "W" (make-sparse-keymap))
233 ;(define-key map "WW" 'vm-apply-window-configuration)
234 ;(define-key map "WS" 'vm-save-window-configuration)
235 ;(define-key map "WD" 'vm-delete-window-configuration)
236 ;(define-key map "W?" 'vm-window-help)
237 (define-key map "\C-t" 'vm-toggle-threads-display)
238 (define-key map "\C-x\C-s" 'vm-save-buffer)
239 (define-key map "\C-x\C-w" 'vm-write-file)
240 (define-key map "\C-x\C-q" 'vm-toggle-read-only)
241 ;(define-key map "%" 'vm-change-folder-type)
242 (define-key map "\M-C" 'vm-show-copying-restrictions)
243 (define-key map "\M-W" 'vm-show-no-warranty)
244 ;; suppress-keymap provides these, but now that we don't use
245 ;; suppress-keymap anymore...
246 (define-key map "0" 'digit-argument)
247 (define-key map "1" 'digit-argument)
248 (define-key map "2" 'digit-argument)
249 (define-key map "3" 'digit-argument)
250 (define-key map "4" 'digit-argument)
251 (define-key map "5" 'digit-argument)
252 (define-key map "6" 'digit-argument)
253 (define-key map "7" 'digit-argument)
254 (define-key map "8" 'digit-argument)
255 (define-key map "9" 'digit-argument)
256 (define-key map "-" 'negative-argument)
258 (define-key map mouse-button-2 (function tm:button-dispatcher)))
259 (if (vm-menu-fsfemacs-menus-p)
261 (vm-menu-initialize-vm-mode-menu-map)
262 (define-key map [menu-bar]
263 (lookup-key vm-mode-menu-map [rootmenu vm]))))
265 "VM emulation keymap for MIME-Preview buffers.")
267 (defvar tm-vm/popup-menu
269 (dummy (make-sparse-keymap))
270 (menu (append vm-menu-dispose-menu
272 (cons mime-viewer/menu-title
275 (vector (nth 1 item)(nth 2 item) t)))
276 mime-viewer/menu-list))))))
279 (vm-easy-menu-define fsfmenu (list dummy) nil menu)
281 "VM's popup menu + MIME specific commands")
285 (define-key vm-mode-map "Z" 'tm-vm/view-message)
286 (define-key vm-mode-map "T" 'tm-vm/decode-message-header)
287 (define-key vm-mode-map "\et" 'tm-vm/toggle-preview-mode)
289 ; Disable VM 6 built-in MIME handling
290 (setq vm-display-using-mime nil
291 vm-send-using-mime nil)
293 ;;; @ MIME encoded-words
295 (defvar tm-vm/use-tm-patch nil
296 "Does not decode encoded-words in summary buffer if it is t.
297 If you use tiny-mime patch for VM (by RIKITAKE Kenji
298 <kenji@reseau.toyonaka.osaka.jp>), please set it t [tm-vm.el]")
300 (or tm-vm/use-tm-patch
302 (defadvice vm-compile-format (around tm activate)
303 "MIME decoding support through TM added."
304 (let ((vm-display-using-mime t))
307 (defadvice vm-tokenized-summary-insert (around tm activate)
308 "MIME decoding support through TM added."
309 (let ((vm-display-using-mime t))
312 (fset 'vm-decode-mime-encoded-words-in-string 'mime-eword/decode-string)
313 (fset 'vm-reencode-mime-encoded-words-in-string 'mime-eword/encode-string)
317 (defun tm-vm/decode-message-header (&optional count)
318 "Decode MIME header of current message.
319 Numeric prefix argument COUNT means to decode the current message plus
320 the next COUNT-1 messages. A negative COUNT means decode the current
321 message and the previous COUNT-1 messages.
322 When invoked on marked messages (via vm-next-command-uses-marks),
323 all marked messages are affected, other messages are ignored."
325 (or count (setq count 1))
326 (vm-follow-summary-cursor)
327 (vm-select-folder-buffer)
328 (vm-check-for-killed-summary)
329 (vm-error-if-folder-empty)
330 (vm-error-if-folder-read-only)
331 (let ((mlist (vm-select-marked-or-prefixed-messages count))
337 (setq realm (vm-real-message-of (car mlist)))
338 ;; Go to real folder of this message.
339 ;; But maybe this message is already real message...
340 (set-buffer (vm-buffer-of realm))
341 (let ((buffer-read-only nil))
343 (narrow-to-region (vm-headers-of realm) (vm-text-of realm))
344 (mime/decode-message-header))
345 (let ((vm-message-pointer (list realm))
347 (vm-discard-cached-data))
348 ;; Mark each virtual and real message for later summary
350 (setq vlist (cons realm (vm-virtual-messages-of realm)))
352 (vm-mark-for-summary-update (car vlist))
353 ;; Remember virtual and real folders related this message,
354 ;; for later display update.
355 (or (memq (vm-buffer-of (car vlist)) vbufs)
356 (setq vbufs (cons (vm-buffer-of (car vlist)) vbufs)))
357 (setq vlist (cdr vlist)))
358 (if (eq vm-flush-interval t)
359 (vm-stuff-virtual-attributes realm)
360 (vm-set-modflag-of realm t)))
361 (setq mlist (cdr mlist)))
362 ;; Update mail-buffers and summaries.
364 (set-buffer (car vbufs))
365 (vm-preview-current-message)
366 (setq vbufs (cdr vbufs))))))
368 (defun tm-vm/header-filter ()
369 "Filter headers in current buffer according to vm-visible-headers and vm-invisible-header-regexp.
370 Current buffer is assumed to have a message-like structure."
371 (goto-char (point-min))
372 (let ((visible-headers vm-visible-headers))
373 (if (or vm-use-lucid-highlighting
375 (setq visible-headers (cons "X-Face:" vm-visible-headers)))
376 (vm-reorder-message-headers nil
378 vm-invisible-header-regexp)
379 (mime/decode-message-header)))
381 (setq mime-viewer/content-header-filter-alist
382 (append '((vm-mode . tm-vm/header-filter)
383 (vm-virtual-mode . tm-vm/header-filter))
384 mime-viewer/content-header-filter-alist))
390 (setq mime-viewer/code-converter-alist
392 (list (cons 'vm-mode 'mime-charset/decode-buffer)
393 (cons 'vm-virtual-mode 'mime-charset/decode-buffer))
394 mime-viewer/code-converter-alist))
396 ;;; @@ MIME-Preview buffer management
398 (defvar tm-vm/system-state nil)
400 (defun tm-vm/system-state ()
402 (if mime::preview/article-buffer
403 (set-buffer mime::preview/article-buffer)
404 (vm-select-folder-buffer))
407 (defun tm-vm/build-preview-buffer ()
408 "Build the MIME Preview buffer for the current VM message.
409 Current buffer should be VM's folder buffer."
411 (set (make-local-variable 'tm-vm/system-state) 'mime-viewing)
412 (setq vm-system-state 'reading)
414 ;; Update message flags and store them in folder buffer before
415 ;; entering MIME viewer
416 (tm-vm/update-message-status)
418 ;; We need to save window configuration because we may be working
420 (save-window-excursion
424 (goto-char (vm-start-of (car vm-message-pointer)))
426 (narrow-to-region (point)
427 (vm-end-of (car vm-message-pointer)))
429 (let ((ml vm-message-list)
430 (mp vm-message-pointer))
431 (mime/viewer-mode nil nil nil nil nil nil)
432 (setq vm-mail-buffer mime::preview/article-buffer)
433 (setq vm-message-list ml
434 vm-message-pointer mp))
435 ;; Install VM toolbar for MIME-Preview buffer if not installed
436 (tm-vm/check-for-toolbar)
437 (if tm-vm/use-vm-bindings
439 (define-key tm-vm/vm-emulation-map "\C-c" (current-local-map))
440 (use-local-map tm-vm/vm-emulation-map)
441 (vm-menu-install-menubar)
442 (if (and vm-use-menus
443 (vm-menu-support-possible-p))
444 (setq mode-popup-menu tm-vm/popup-menu))))
446 ;; Highlight message (and display XFace if supported)
447 (if (or vm-highlighted-header-regexp
448 (and running-xemacs vm-use-lucid-highlighting))
449 (vm-highlight-headers))
450 ;; Display XFaces with VM internal support if appropriate
451 (if (and vm-display-xfaces
453 (vm-multiple-frames-possible-p)
455 (let ((highlight-headers-hack-x-face-p t)
456 (highlight-headers-regexp nil)
457 (highlight-headers-citation-regexp nil)
458 (highlight-headers-citation-header-regexp nil))
459 (highlight-headers (point-min) (point-max) t)))
460 ;; Energize URLs and buttons
461 (if (and tm-vm/use-original-url-button
462 vm-use-menus (vm-menu-support-possible-p))
463 (progn (vm-energize-headers)
465 (run-hooks 'tm-vm/build-mime-preview-buffer-hook)
468 (defun tm-vm/sync-preview-buffer ()
469 "Ensure that the MIME preview buffer, if it exists, actually corresponds to the current message.
470 If no MIME Preview buffer is needed then kill it. If no
471 MIME Preview buffer exists nothing is done."
472 ;; Current buffer should be message buffer when calling this function
473 (let* ((mbuf (current-buffer))
474 (pbuf (and mime::article/preview-buffer
475 (get-buffer mime::article/preview-buffer))))
477 ;; A MIME Preview buffer exists then it may need to be synch'ed
480 (if (and tm-vm/strict-mime
481 (not (vm-get-header-contents (car vm-message-pointer)
484 (setq mime::article/preview-buffer nil
485 tm-vm/system-state nil)
486 (if pbuf (kill-buffer pbuf)))
487 (tm-vm/build-preview-buffer)))
488 ;; Return to previous frame
491 (defun tm-vm/toggle-preview-mode ()
492 "Toggle automatic MIME preview on or off.
493 In automatic MIME Preview mode each newly selected article is MIME processed if
494 it has MIME content without need for an explicit request from the user. This
495 behaviour is controlled by the variable tm-vm/automatic-mime-preview."
498 (if tm-vm/automatic-mime-preview
500 (tm-vm/quit-view-message)
501 (setq tm-vm/automatic-mime-preview nil)
502 (message "Automatic MIME Preview is now disabled."))
503 ;; Enable Automatic MIME Preview
505 (setq tm-vm/automatic-mime-preview t)
506 (message "Automatic MIME Preview is now enabled.")
509 ;;; @@ Display functions
511 (defun tm-vm/update-message-status ()
512 "Update current message display and summary.
513 Remove 'unread' and 'new' flags. The MIME Preview buffer is not displayed,
514 tm-vm/display-preview-buffer should be called for that. This function is
515 display-configuration safe."
516 (if mime::preview/article-buffer
517 (set-buffer mime::preview/article-buffer)
518 (vm-select-folder-buffer))
519 (if (or (and mime::article/preview-buffer
520 (get-buffer mime::article/preview-buffer)
521 (vm-get-visible-buffer-window mime::article/preview-buffer))
522 (vm-get-visible-buffer-window (current-buffer)))
524 (if (vm-new-flag (car vm-message-pointer))
525 (vm-set-new-flag (car vm-message-pointer) nil))
526 (if (vm-unread-flag (car vm-message-pointer))
527 (vm-set-unread-flag (car vm-message-pointer) nil))
528 (vm-update-summary-and-mode-line)
530 (vm-update-summary-and-mode-line)))
532 (defun tm-vm/display-preview-buffer ()
533 "Replace the VM message buffer with the MIME-Preview buffer if the VM message buffer is currently displayed or undisplay it if tm-vm/system-state is nil."
534 (let* ((mbuf (current-buffer))
535 (mwin (vm-get-visible-buffer-window mbuf))
536 (pbuf (and mime::article/preview-buffer
537 (get-buffer mime::article/preview-buffer)))
538 (pwin (and pbuf (vm-get-visible-buffer-window pbuf))))
539 (if (and pbuf (tm-vm/system-state))
540 ;; display preview buffer if preview-buffer exists
543 (vm-undisplay-buffer mbuf)
544 (tm-vm/update-message-status))
545 ((and mwin (not pwin))
546 (set-window-buffer mwin pbuf)
547 (tm-vm/update-message-status))
549 (tm-vm/update-message-status))
551 ;; don't display if neither mwin nor pwin was displayed before.
553 ;; display folder buffer
556 (vm-undisplay-buffer pbuf))
557 ((and (not mwin) pwin)
558 (set-window-buffer pwin mbuf))
560 ;; folder buffer is already displayed.
563 ;; don't display if neither mwin nor pwin was displayed before.
566 (defun tm-vm/preview-current-message ()
567 "Either preview message (view first lines only) or MIME-Preview it.
568 The message is previewed if message previewing is enabled see vm-preview-lines.
569 If not, MIME-Preview current message (ie. parse MIME
570 contents and display appropriately) if it has MIME contents and
571 tm-vm/automatic-mime-preview is non nil. Installed on vm-visit-folder-hook and
572 vm-select-message-hook."
573 ;; assumed current buffer is folder buffer.
574 (setq tm-vm/system-state nil)
575 (if (get-buffer mime/output-buffer-name)
576 (vm-undisplay-buffer mime/output-buffer-name))
577 (if (and vm-message-pointer
578 tm-vm/automatic-mime-preview
579 (or (null vm-preview-lines)
580 (not (eq vm-system-state 'previewing))
581 (and (not vm-preview-read-messages)
582 (not (vm-new-flag (car vm-message-pointer)))
583 (not (vm-unread-flag (car vm-message-pointer))))))
584 (if (or (not tm-vm/strict-mime)
585 (vm-get-header-contents (car vm-message-pointer)
587 ;; do MIME processing.
589 (tm-vm/build-preview-buffer)
591 (set-buffer mime::article/preview-buffer)
592 (run-hooks 'tm-vm/select-message-hook)))
593 ;; don't do MIME processing. decode header only.
594 (let (buffer-read-only)
595 (mime/decode-message-header)
596 (run-hooks 'tm-vm/select-message-hook))
598 ;; don't preview; do nothing.
599 (run-hooks 'tm-vm/select-message-hook))
600 (tm-vm/display-preview-buffer))
602 (defun tm-vm/view-message ()
603 "Decode and view the current VM message as a MIME encoded message.
604 A MIME Preview buffer using mime/viewer-mode is created.
605 See mime/viewer-mode for more information"
607 (vm-follow-summary-cursor)
608 (vm-select-folder-buffer)
609 (vm-check-for-killed-summary)
610 (vm-error-if-folder-empty)
611 (vm-display (current-buffer) t '(tm-vm/view-message
612 tm-vm/toggle-preview-mode)
613 '(tm-vm/view-message reading-message))
614 (let ((tm-vm/automatic-mime-preview t))
615 (tm-vm/preview-current-message))
618 (defun tm-vm/quit-view-message ()
619 "Quit MIME-Viewer and go back to normal VM.
620 MIME Preview buffer is killed. This function is called by `mime-viewer/quit'
621 command via `mime-viewer/quitting-method-alist'."
622 (if (get-buffer mime/output-buffer-name)
623 (vm-undisplay-buffer mime/output-buffer-name))
624 (vm-select-folder-buffer)
625 (let* ((mbuf (current-buffer))
626 (pbuf (and mime::article/preview-buffer
627 (get-buffer mime::article/preview-buffer)))
628 (pwin (and pbuf (vm-get-visible-buffer-window pbuf))))
629 (if pbuf (kill-buffer pbuf))
632 (switch-to-buffer mbuf)))
633 (setq tm-vm/system-state nil)
634 (vm-display (current-buffer) t (list this-command)
635 (list 'reading-message)))
637 (add-hook 'vm-select-message-hook 'tm-vm/preview-current-message)
638 (add-hook 'vm-visit-folder-hook 'tm-vm/preview-current-message)
646 ;;; based on vm-do-reply [vm-reply.el]
647 (defun tm-vm/do-reply (buf to-all include-text)
650 (let ((dir default-directory)
651 to cc subject in-reply-to references newsgroups)
653 (let ((reply-to (std11-field-body "Reply-To")))
654 (if (vm-ignored-reply-to reply-to)
657 ((setq to (std11-field-body "From")))
658 ;; (t (error "No From: or Reply-To: header in message"))
661 (setq cc (delq nil (cons cc (std11-field-bodies '("To" "Cc"))))
662 cc (mapconcat 'identity cc ","))
664 (setq subject (std11-field-body "Subject"))
665 (and subject vm-reply-subject-prefix
666 (let ((case-fold-search t))
669 (string-match (regexp-quote vm-reply-subject-prefix)
672 (setq subject (concat vm-reply-subject-prefix subject)))
673 (setq in-reply-to (std11-field-body "Message-Id")
675 (std11-field-bodies '("References" "In-Reply-To"))
677 newsgroups (list (or (and to-all
678 (std11-field-body "Followup-To"))
679 (std11-field-body "Newsgroups"))))
680 (setq to (vm-parse-addresses to)
681 cc (vm-parse-addresses cc))
682 (if vm-reply-ignored-addresses
683 (setq to (vm-strip-ignored-addresses to)
684 cc (vm-strip-ignored-addresses cc)))
685 (setq to (vm-delete-duplicates to nil t))
686 (setq cc (vm-delete-duplicates
687 (append (vm-delete-duplicates cc nil t)
688 to (copy-sequence to))
690 (and to (setq to (mapconcat 'identity to ",\n ")))
691 (and cc (setq cc (mapconcat 'identity cc ",\n ")))
692 (and (null to) (setq to cc cc nil))
693 (setq references (delq nil references)
694 references (mapconcat 'identity references " ")
695 references (vm-parse references "[^<]*\\(<[^>]+>\\)")
696 references (vm-delete-duplicates references)
697 references (if references (mapconcat 'identity references "\n\t")))
698 (setq newsgroups (delq nil newsgroups)
699 newsgroups (mapconcat 'identity newsgroups ",")
700 newsgroups (vm-parse newsgroups "[ \t\f\r\n,]*\\([^ \t\f\r\n,]+\\)")
701 newsgroups (vm-delete-duplicates newsgroups)
702 newsgroups (if newsgroups (mapconcat 'identity newsgroups ",")))
705 (format "reply to %s%s"
706 (std11-full-name-string
707 (car (std11-parse-address-string to)))
709 to subject in-reply-to cc references newsgroups)
710 (setq mail-reply-buffer buf
711 ;; vm-system-state 'replying
712 default-directory dir))
715 (goto-char (point-min))
716 (let ((case-fold-search nil))
718 (concat "^" (regexp-quote mail-header-separator) "$") nil 0))
720 (tm-vm/yank-content)))
721 (run-hooks 'vm-reply-hook)
722 (run-hooks 'vm-mail-mode-hook)
725 (defun tm-vm/following-method (buf)
726 (tm-vm/do-reply buf 'to-all 'include-text)
729 (defun tm-vm/yank-content ()
731 (let ((this-command 'vm-yank-message))
732 (vm-display nil nil '(vm-yank-message)
733 '(vm-yank-message composing-message))
735 (narrow-to-region (point)(point))
736 (insert-buffer mail-reply-buffer)
737 (goto-char (point-max))
739 (goto-char (point-min)))
740 (cond (mail-citation-hook (run-hooks 'mail-citation-hook))
741 (mail-yank-hooks (run-hooks 'mail-yank-hooks))
742 (t (mail-indent-citation)))
745 (set-alist 'mime-viewer/following-method-alist
747 (function tm-vm/following-method))
748 (set-alist 'mime-viewer/following-method-alist
750 (function tm-vm/following-method))
752 (set-alist 'mime-viewer/quitting-method-alist
754 'tm-vm/quit-view-message)
755 (set-alist 'mime-viewer/quitting-method-alist
757 'tm-vm/quit-view-message)
759 ;;; @@ Motion commands
761 (defmacro tm-vm/save-window-excursion (&rest forms)
762 (list 'let '((tm-vm/selected-window (selected-window)))
763 (list 'unwind-protect
765 '(if (window-live-p tm-vm/selected-window)
766 (select-window tm-vm/selected-window)))))
768 (defmacro tm-vm/save-frame-excursion (&rest forms)
769 (list 'let '((tm-vm/selected-frame (vm-selected-frame)))
770 (list 'unwind-protect
772 '(if (frame-live-p tm-vm/selected-frame)
773 (vm-select-frame tm-vm/selected-frame)))))
775 (defadvice vm-scroll-forward (around tm-aware activate)
776 "Made TM-aware (handles the MIME-Preview buffer)."
779 (if mime::preview/article-buffer
780 (set-buffer mime::preview/article-buffer))
781 (vm-select-folder-buffer)
782 (eq vm-system-state 'previewing)))
783 (not (tm-vm/system-state)))
786 (tm-vm/display-preview-buffer))
787 (let* ((mp-changed (vm-follow-summary-cursor))
788 (mbuf (or (vm-select-folder-buffer) (current-buffer)))
789 (mwin (vm-get-buffer-window mbuf))
790 (pbuf (and mime::article/preview-buffer
791 (get-buffer mime::article/preview-buffer)))
792 (pwin (and pbuf (vm-get-buffer-window pbuf)))
794 (vm-check-for-killed-summary)
795 (vm-error-if-folder-empty)
797 ; A new message was selected
798 ; => leave it to tm-vm/preview-current-message
801 ((eq vm-system-state 'previewing)
802 (vm-display (current-buffer) t (list this-command) '(reading-message))
803 (vm-show-current-message)
804 (tm-vm/preview-current-message))
805 ; Preview buffer was killed
807 (tm-vm/preview-current-message))
808 ; Preview buffer was undisplayed
811 (vm-display mbuf t '(vm-scroll-forward vm-scroll-backward)
812 (list this-command 'reading-message)))
813 (tm-vm/display-preview-buffer))
814 ; Preview buffer is displayed => scroll
816 (tm-vm/save-window-excursion
819 (if (pos-visible-in-window-p (point-max) pwin)
820 (if vm-auto-next-message
822 ;; not at the end of message. scroll preview buffer only.
829 (defadvice vm-scroll-backward (around tm-aware activate)
830 "Made TM-aware (handles the MIME-Preview buffer)."
833 (if mime::preview/article-buffer
834 (set-buffer mime::preview/article-buffer))
835 (vm-select-folder-buffer)
836 (eq vm-system-state 'previewing)))
837 (not (tm-vm/system-state)))
839 (let* ((mp-changed (vm-follow-summary-cursor))
840 (mbuf (or (vm-select-folder-buffer) (current-buffer)))
841 (mwin (vm-get-buffer-window mbuf))
842 (pbuf (and mime::article/preview-buffer
843 (get-buffer mime::article/preview-buffer)))
844 (pwin (and pbuf (vm-get-buffer-window pbuf)))
846 (vm-check-for-killed-summary)
847 (vm-error-if-folder-empty)
849 ; A new message was selected
850 ; => leave it to tm-vm/preview-current-message
853 ((eq vm-system-state 'previewing)
854 (tm-vm/update-message-status)
855 (setq vm-system-state 'reading)
856 (tm-vm/preview-current-message))
857 ; Preview buffer was killed
859 (tm-vm/preview-current-message))
860 ; Preview buffer was undisplayed
863 (vm-display mbuf t '(vm-scroll-forward vm-scroll-backward)
864 (list this-command 'reading-message)))
865 (tm-vm/display-preview-buffer))
866 ; Preview buffer is displayed => scroll
868 (tm-vm/save-window-excursion
870 (if (pos-visible-in-window-p (point-min) pwin)
872 ;; not at the end of message. scroll preview buffer only.
877 (defadvice vm-beginning-of-message (around tm-aware activate)
878 "Made TM-aware, works properly in MIME-Preview buffers."
879 (if (not (tm-vm/system-state))
881 (vm-follow-summary-cursor)
882 (vm-select-folder-buffer)
883 (vm-check-for-killed-summary)
884 (vm-error-if-folder-empty)
885 (let ((pbuf (and mime::article/preview-buffer
886 (get-buffer mime::article/preview-buffer))))
889 (tm-vm/preview-current-message)
890 (setq pbuf (get-buffer mime::article/preview-buffer))
892 (vm-display (current-buffer) t '(vm-beginning-of-message)
893 '(vm-beginning-of-message reading-message))
894 (tm-vm/display-preview-buffer)
895 (tm-vm/save-window-excursion
896 (select-window (vm-get-visible-buffer-window pbuf))
898 (goto-char (point-min))
899 (vm-display (current-buffer) t '(vm-beginning-of-message)
900 '(vm-beginning-of-message reading-message))
903 (defadvice vm-end-of-message (around tm-aware activate)
904 "Made TM-aware, works properly in MIME-Preview buffers."
906 (if (not (tm-vm/system-state))
908 (vm-follow-summary-cursor)
909 (vm-select-folder-buffer)
910 (vm-check-for-killed-summary)
911 (vm-error-if-folder-empty)
912 (let ((pbuf (and mime::article/preview-buffer
913 (get-buffer mime::article/preview-buffer))))
916 (tm-vm/preview-current-message)
917 (setq pbuf (get-buffer mime::article/preview-buffer))
919 (vm-display (current-buffer) t '(vm-end-of-message)
920 '(vm-end-of-message reading-message))
921 (tm-vm/display-preview-buffer)
922 (tm-vm/save-window-excursion
923 (select-window (vm-get-buffer-window pbuf))
925 (goto-char (point-max))
926 (vm-display (current-buffer) t '(vm-end-of-message)
927 '(vm-end-of-message reading-message))
930 ;;; based on vm-howl-if-eom [vm-page.el]
931 (defun tm-vm/howl-if-eom ()
932 (let* ((pbuf (or mime::article/preview-buffer (current-buffer)))
933 (pwin (and (vm-get-visible-buffer-window pbuf))))
936 (save-window-excursion
938 (let ((next-screen-context-lines 0))
939 (tm-vm/save-frame-excursion
940 (vm-select-frame (vm-window-frame pwin))
941 (save-selected-window
944 (let ((scroll-in-place-replace-original nil))
951 (defadvice vm-emit-eom-blurb (around tm-aware activate)
952 "Made TM-aware, works properly in MIME-Preview buffers."
954 (if mime::preview/article-buffer
955 (set-buffer mime::preview/article-buffer))
958 (defadvice vm-next-message (around tm-aware activate)
959 "Made TM-aware, works properly in MIME-Preview buffers."
960 (if mime::preview/article-buffer
961 (set-buffer mime::preview/article-buffer))
962 (tm-vm/save-window-excursion
965 (defadvice vm-previous-message (around tm-aware activate)
966 "Made TM-aware, works properly in MIME-Preview buffers."
967 (if mime::preview/article-buffer
968 (set-buffer mime::preview/article-buffer))
969 (tm-vm/save-window-excursion
972 (defadvice vm-next-message-no-skip (around tm-aware activate)
973 "Made TM-aware, works properly in MIME-Preview buffers."
974 (if mime::preview/article-buffer
975 (set-buffer mime::preview/article-buffer))
976 (tm-vm/save-window-excursion
979 (defadvice vm-previous-message-no-skip (around tm-aware activate)
980 "TM wrapper for vm-previous-message-no-skip (which see)."
981 (if mime::preview/article-buffer
982 (set-buffer mime::preview/article-buffer))
983 (tm-vm/save-window-excursion
986 (defadvice vm-next-unread-message (around tm-aware activate)
987 "Made TM-aware, works properly in MIME-Preview buffers."
988 (if mime::preview/article-buffer
989 (set-buffer mime::preview/article-buffer))
990 (tm-vm/save-window-excursion
993 (defadvice vm-previous-unread-message (around tm-aware activate)
994 "Made TM-aware, works properly in MIME-Preview buffers."
995 (if mime::preview/article-buffer
996 (set-buffer mime::preview/article-buffer))
997 (tm-vm/save-window-excursion
1001 (set-alist 'mime-viewer/over-to-previous-method-alist
1002 'vm-mode 'vm-previous-message)
1003 (set-alist 'mime-viewer/over-to-next-method-alist
1004 'vm-mode 'vm-next-message)
1005 (set-alist 'mime-viewer/over-to-previous-method-alist
1006 'vm-virtual-mode 'vm-previous-message)
1007 (set-alist 'mime-viewer/over-to-next-method-alist
1008 'vm-virtual-mode 'vm-next-message)
1017 ;;; @@ vm-yank-message
1020 (defvar tm-vm/yank:message-to-restore nil
1021 "For internal use by tm-vm only.")
1023 (defun vm-yank-message (&optional message)
1024 "Yank message number N into the current buffer at point.
1025 When called interactively N is always read from the minibuffer. When
1026 called non-interactively the first argument is expected to be a
1029 This function originally provided by vm-reply has been patched for TM
1030 in order to provide better citation of MIME messages : if a MIME
1031 Preview buffer exists for the message then its contents are inserted
1032 instead of the raw message.
1034 This command is meant to be used in VM created Mail mode buffers; the
1035 yanked message comes from the mail buffer containing the message you
1036 are replying to, forwarding, or invoked VM's mail command from.
1038 All message headers are yanked along with the text. Point is
1039 left before the inserted text, the mark after. Any hook
1040 functions bound to mail-citation-hook are run, after inserting
1041 the text and setting point and mark. For backward compatibility,
1042 if mail-citation-hook is set to nil, `mail-yank-hooks' is run
1045 If mail-citation-hook and mail-yank-hooks are both nil, this
1046 default action is taken: the yanked headers are trimmed as
1047 specified by vm-included-text-headers and
1048 vm-included-text-discard-header-regexp, and the value of
1049 vm-included-text-prefix is prepended to every yanked line."
1052 ;; What we really want for the first argument is a message struct,
1053 ;; but if called interactively, we let the user type in a message
1058 (last-command last-command)
1059 (this-command this-command))
1060 (if (bufferp vm-mail-buffer)
1062 (vm-select-folder-buffer)
1063 (setq default (and vm-message-pointer
1064 (vm-number-of (car vm-message-pointer)))
1066 (format "Yank message number: (default %s) "
1068 "Yank message number: "))
1069 (while (zerop result)
1070 (setq result (read-string prompt))
1071 (and (string= result "") default (setq result default))
1072 (setq result (string-to-int result)))
1073 (if (null (setq mp (nthcdr (1- result) vm-message-list)))
1074 (error "No such message."))
1075 (setq tm-vm/yank:message-to-restore (string-to-int default))
1076 (save-selected-window
1077 (vm-goto-message result))
1081 (if mail-reply-buffer
1082 (tm-vm/yank-content)
1083 (error "This is not a VM Mail mode buffer."))
1084 (if (null (buffer-name vm-mail-buffer))
1085 (error "The folder buffer containing message %d has been killed."
1086 (vm-number-of message)))
1087 (vm-display nil nil '(vm-yank-message)
1088 '(vm-yank-message composing-message))
1089 (let ((b (current-buffer)) (start (point)) end)
1093 (set-buffer (vm-buffer-of message))
1095 (tm-vm/sync-preview-buffer)
1096 (setq pbuf (and mime::article/preview-buffer
1097 (get-buffer mime::article/preview-buffer)))
1099 (not (eq this-command 'vm-forward-message)))
1100 ;; Yank contents of MIME Preview buffer
1102 (let ((tmp (generate-new-buffer "tm-vm/tmp")))
1104 (append-to-buffer tmp (point-min) (point-max))
1107 '(lambda (ext maparg)
1108 (set-extent-property ext 'begin-glyph nil)))
1109 (append-to-buffer b (point-min) (point-max))
1110 (setq end (vm-marker
1111 (+ start (length (buffer-string))) b))
1114 (append-to-buffer b (point-min) (point-max))
1115 (setq end (vm-marker
1116 (+ start (length (buffer-string))) b)))
1117 ;; Yank contents of raw VM message
1119 (setq message (vm-real-message-of message))
1120 (set-buffer (vm-buffer-of message))
1123 b (vm-headers-of message) (vm-text-end-of message))
1125 (vm-marker (+ start (- (vm-text-end-of message)
1126 (vm-headers-of message))) b))))))
1128 (cond (mail-citation-hook (run-hooks 'mail-citation-hook))
1129 (mail-yank-hooks (run-hooks 'mail-yank-hooks))
1130 (t (vm-mail-yank-default message)))
1132 (if tm-vm/yank:message-to-restore
1133 (save-selected-window
1134 (vm-goto-message tm-vm/yank:message-to-restore)
1135 (setq tm-vm/yank:message-to-restore nil)))
1138 ;;; @@ for tm-partial
1145 (set-atype 'mime/content-decoding-condition
1146 '((type . "message/partial")
1147 (method . mime-article/grab-message/partials)
1148 (major-mode . vm-mode)
1149 (summary-buffer-exp . vm-summary-buffer)
1151 (set-alist 'tm-partial/preview-article-method-alist
1155 (tm-vm/view-message)
1167 (setq vm-forwarding-digest-type "rfc1521")
1168 (setq vm-digest-send-type "rfc1521")
1171 ;;; @@@ multipart/digest
1173 (if (not (fboundp 'vm-unsaved-message))
1174 (fset 'vm-unsaved-message 'message))
1176 (defun tm-vm/enclose-messages (mlist &optional preamble)
1177 "Enclose the messages in MLIST as multipart/digest.
1178 The resulting digest is inserted at point in the current buffer.
1180 MLIST should be a list of message structs (real or virtual).
1181 These are the messages that will be enclosed."
1183 (let ((digest (consp (cdr mlist)))
1187 (narrow-to-region (point) (point))
1189 (setq m (vm-real-message-of (car mlist)))
1190 (mime-editor/insert-tag "message" "rfc822")
1191 (tm-mail/insert-message m)
1192 (goto-char (point-max))
1193 (setq mlist (cdr mlist)))
1196 (goto-char (point-min))
1197 (mime-editor/insert-tag "text" "plain")
1198 (vm-unsaved-message "Building digest preamble...")
1200 (let ((vm-summary-uninteresting-senders nil))
1202 (vm-sprintf 'vm-digest-preamble-format (car mp)) "\n"))
1203 (if vm-digest-center-preamble
1208 (setq mp (cdr mp)))))
1210 (mime-editor/enclose-digest-region (point-min) (point-max)))
1213 (defadvice vm-forward-message (around tm-aware activate)
1214 "Extended to support rfc1521 digests (roughly equivalent to what
1215 VM does when vm-forwarding-digest-type is 'mime but using message/rfc822
1217 (if (not (equal vm-forwarding-digest-type "rfc1521"))
1219 (if mime::preview/article-buffer
1220 (set-buffer mime::preview/article-buffer))
1221 (vm-follow-summary-cursor)
1222 (vm-select-folder-buffer)
1223 (vm-check-for-killed-summary)
1224 (vm-error-if-folder-empty)
1225 (if (eq last-command 'vm-next-command-uses-marks)
1226 (let ((vm-digest-send-type vm-forwarding-digest-type))
1227 (setq this-command 'vm-next-command-uses-marks)
1228 (command-execute 'tm-vm/send-digest))
1229 (let ((dir default-directory)
1230 (mp vm-message-pointer))
1234 (format "forward of %s's note re: %s"
1235 (vm-su-full-name (car vm-message-pointer))
1236 (vm-su-subject (car vm-message-pointer)))
1238 (and vm-forwarding-subject-format
1239 (let ((vm-summary-uninteresting-senders nil))
1240 (vm-sprintf 'vm-forwarding-subject-format (car mp)))))
1241 (make-local-variable 'vm-forward-list)
1242 (setq vm-system-state 'forwarding
1243 vm-forward-list (list (car mp))
1244 default-directory dir)
1245 (goto-char (point-min))
1247 (concat "^" (regexp-quote mail-header-separator) "\n") nil 0)
1248 (tm-vm/enclose-messages vm-forward-list)
1249 (mail-position-on-field "To"))
1250 (run-hooks 'tm-vm/forward-message-hook)
1251 (run-hooks 'vm-mail-mode-hook)))))
1253 (defun tm-vm/send-digest (&optional arg)
1254 "Send a digest of all messages in the current folder to recipients.
1255 The type of the digest is specified by the variable vm-digest-send-type.
1256 You will be placed in a Mail mode buffer as is usual with replies, but you
1257 must fill in the To: and Subject: headers manually.
1259 If invoked on marked messages (via vm-next-command-uses-marks),
1260 only marked messages will be put into the digest."
1262 (if (not (equal vm-digest-send-type "rfc1521"))
1263 (vm-send-digest arg)
1264 (vm-select-folder-buffer)
1265 (vm-check-for-killed-summary)
1266 (vm-error-if-folder-empty)
1267 (let ((dir default-directory)
1268 (vm-forward-list (if (eq last-command 'vm-next-command-uses-marks)
1269 (vm-select-marked-or-prefixed-messages 0)
1273 (vm-mail-internal (format "digest from %s" (buffer-name)))
1274 (setq vm-system-state 'forwarding
1275 default-directory dir)
1276 (goto-char (point-min))
1277 (re-search-forward (concat "^" (regexp-quote mail-header-separator)
1279 (goto-char (match-end 0))
1280 (vm-unsaved-message "Building %s digest..." vm-digest-send-type)
1281 (tm-vm/enclose-messages vm-forward-list arg)
1282 (mail-position-on-field "To")
1283 (message "Building %s digest... done" vm-digest-send-type)))
1284 (run-hooks 'tm-vm/send-digest-hook)
1285 (run-hooks 'vm-mail-mode-hook)))
1287 (substitute-key-definition 'vm-send-digest
1288 'tm-vm/send-digest vm-mode-map)
1297 (autoload 'tm-mail/insert-message "tm-mail")
1298 (set-alist 'mime-editor/message-inserter-alist
1299 'mail-mode (function tm-mail/insert-message))
1300 (set-alist 'mime-editor/split-message-sender-alist
1301 'mail-mode (function
1304 (funcall send-mail-function)
1310 ;;; @ VM Integration
1312 (add-hook 'vm-quit-hook 'tm-vm/quit-view-message)
1314 ;;; @@ Wrappers for miscellaneous VM functions
1316 (defadvice vm-summarize (around tm-aware activate)
1317 "Made TM aware. Callable from the MIME Preview buffer."
1318 (if mime::preview/article-buffer
1319 (set-buffer mime::preview/article-buffer))
1322 (set-buffer vm-summary-buffer)
1323 (tm-vm/check-for-toolbar))
1324 (tm-vm/preview-current-message))
1326 (defadvice vm-expose-hidden-headers (around tm-aware activate)
1327 "Made TM aware. Callable from the MIME Preview buffer."
1328 (if mime::preview/article-buffer
1329 (set-buffer mime::preview/article-buffer))
1330 (let ((visible-headers vm-visible-headers))
1331 (tm-vm/quit-view-message)
1333 (let ((vm-visible-headers visible-headers))
1334 (if (= (point-min) (vm-start-of (car vm-message-pointer)))
1335 (setq vm-visible-headers '(".*")))
1336 (tm-vm/preview-current-message))))
1338 (if (vm-mouse-fsfemacs-mouse-p)
1340 (define-key tm-vm/vm-emulation-map [mouse-3] 'ignore)
1341 (define-key tm-vm/vm-emulation-map [down-mouse-3] 'vm-mouse-button-3)
1342 (defadvice vm-mouse-button-3 (after tm-aware activate)
1343 "Made TM aware. Works in MIME-Preview buffers."
1346 (eq major-mode 'mime/viewer-mode))
1347 (vm-menu-popup-mode-menu event))))
1350 (defadvice vm-save-message (around tm-aware activate)
1351 "Made TM aware. Callable from the MIME Preview buffer."
1352 (if mime::preview/article-buffer
1354 (set-buffer mime::preview/article-buffer)
1358 (defadvice vm-expunge-folder (around tm-aware activate)
1359 "Made TM aware. Callable from the MIME Preview buffer."
1360 (if mime::preview/article-buffer
1362 (set-buffer mime::preview/article-buffer)
1366 (defadvice vm-save-folder (around tm-aware activate)
1367 "Made TM aware. Callable from the MIME Preview buffer."
1368 (if mime::preview/article-buffer
1370 (set-buffer mime::preview/article-buffer)
1374 (defadvice vm-goto-parent-message (around tm-aware activate)
1375 "Made TM aware. Callable from the MIME Preview buffer."
1376 (if mime::preview/article-buffer
1378 (set-buffer mime::preview/article-buffer)
1382 (defadvice vm-delete-message (around tm-aware activate)
1383 "Made TM aware. Callable from the MIME Preview buffer."
1386 (vm-follow-summary-cursor))
1387 (if mime::preview/article-buffer
1389 (set-buffer mime::preview/article-buffer)
1393 (defadvice vm-delete-message-backward (around tm-aware activate)
1394 "Made TM aware. Callable from the MIME Preview buffer."
1397 (vm-follow-summary-cursor))
1398 (if mime::preview/article-buffer
1400 (set-buffer mime::preview/article-buffer)
1404 (defadvice vm-undelete-message (around tm-aware activate)
1405 "Made TM aware. Callable from the MIME Preview buffer."
1408 (vm-follow-summary-cursor))
1409 (if mime::preview/article-buffer
1411 (set-buffer mime::preview/article-buffer)
1415 (defadvice vm-unread-message (around tm-aware activate)
1416 "Made TM aware. Callable from the MIME Preview buffer."
1417 (if mime::preview/article-buffer
1419 (set-buffer mime::preview/article-buffer)
1423 (defadvice vm-edit-message (around tm-aware activate)
1424 "Made TM aware. Callable from the MIME Preview buffer."
1425 (if mime::preview/article-buffer
1427 (set-buffer mime::preview/article-buffer)
1433 ;;; @@ VM Toolbar Integration
1435 ;;; based on vm-toolbar-any-messages-p [vm-toolbar.el]
1436 (defun tm-vm/check-for-toolbar ()
1437 "Install VM toolbar if necessary."
1438 (if (and running-xemacs
1439 vm-toolbar-specifier)
1441 (if (null (specifier-instance vm-toolbar-specifier))
1442 (vm-toolbar-install-toolbar))
1443 (vm-toolbar-update-toolbar))))
1445 (defun vm-toolbar-any-messages-p ()
1447 (if mime::preview/article-buffer
1448 (set-buffer mime::preview/article-buffer))
1449 (vm-check-for-killed-folder)
1450 (vm-select-folder-buffer)
1454 ;;; @ BBDB Integration
1463 (defun tm-bbdb/vm-update-record (&optional offer-to-create)
1465 (vm-select-folder-buffer)
1466 (if (and (tm-vm/system-state)
1467 mime::article/preview-buffer
1468 (get-buffer mime::article/preview-buffer))
1469 (let ((tm-bbdb/auto-create-p bbdb/mail-auto-create-p))
1470 (tm-bbdb/update-record offer-to-create))
1471 (or (bbdb/vm-update-record offer-to-create)
1472 (delete-windows-on (get-buffer "*BBDB*")))
1474 (remove-hook 'vm-select-message-hook 'bbdb/vm-update-record)
1475 (remove-hook 'vm-show-message-hook 'bbdb/vm-update-record)
1476 (add-hook 'tm-vm/select-message-hook 'tm-bbdb/vm-update-record)
1479 ;;; @ ps-print (Suggested by Anders Stenman <stenman@isy.liu.se>)
1482 (if tm-vm/use-ps-print
1484 (autoload 'ps-print-buffer-with-faces "ps-print" "Postscript Print" t)
1485 (add-hook 'vm-mode-hook 'tm-vm/ps-print-setup)
1486 (add-hook 'mime-viewer/define-keymap-hook 'tm-vm/ps-print-setup)
1487 (fset 'vm-toolbar-print-command 'tm-vm/print-message)))
1489 (defun tm-vm/ps-print-setup ()
1490 "Set things up for printing MIME messages with ps-print. Set binding to
1491 the [Print Screen] key."
1492 (local-set-key (if running-xemacs
1495 'tm-vm/print-message)
1496 (make-local-variable 'ps-header-lines)
1497 (make-local-variable 'ps-left-header)
1498 (setq ps-header-lines 3)
1499 (setq ps-left-header
1500 (list 'ps-article-subject 'ps-article-author 'buffer-name)))
1502 (defun tm-vm/print-message ()
1503 "Print current message with ps-print if it's a MIME message.
1504 Value of tm-vm/strict-mime is also taken into consideration."
1506 (vm-follow-summary-cursor)
1507 (vm-select-folder-buffer)
1508 (tm-vm/sync-preview-buffer)
1509 (let ((pbuf (and mime::article/preview-buffer
1510 (get-buffer mime::article/preview-buffer))))
1515 (ps-print-buffer-with-faces))
1516 (vm-print-message))))
1522 (run-hooks 'tm-vm-load-hook)
1524 ;;; tm-vm.el ends here.