1 ;;; gnus-vm.el --- vm interface for Gnus
2 ;; Copyright (C) 1994,95,96 Free Software Foundation, Inc.
4 ;; Author: Per Persson <pp@solace.mh.se>
5 ;; Keywords: news, mail
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
26 ;; Major contributors:
27 ;; Christian Limpach <Christian.Limpach@nice.ch>
28 ;; Some code stolen from:
29 ;; Rick Sladkey <jrs@world.std.com>
39 (autoload 'vm-mode "vm")
40 (autoload 'vm-save-message "vm")
41 (autoload 'vm-forward-message "vm")
42 (autoload 'vm-reply "vm")
43 (autoload 'vm-mail "vm"))
45 (defvar gnus-vm-inhibit-window-system nil
46 "Inhibit loading `win-vm' if using a window-system.
47 Has to be set before gnus-vm is loaded.")
49 (or gnus-vm-inhibit-window-system
55 (if (not (featurep 'vm))
58 (defun gnus-vm-make-folder (&optional buffer)
59 (let ((article (or buffer (current-buffer)))
60 (tmp-folder (generate-new-buffer " *tmp-folder*"))
63 (set-buffer tmp-folder)
64 (insert-buffer-substring article start end)
65 (goto-char (point-min))
66 (if (looking-at "^\\(From [^ ]+ \\).*$")
67 (replace-match (concat "\\1" (current-time-string)))
68 (insert "From " gnus-newsgroup-name " "
69 (current-time-string) "\n"))
70 (while (re-search-forward "\n\nFrom " nil t)
71 (replace-match "\n\n>From "))
72 ;; insert a newline, otherwise the last line gets lost
73 (goto-char (point-max))
78 (defun gnus-summary-save-article-vm (&optional arg)
79 "Append the current article to a vm folder.
80 If N is a positive number, save the N next articles.
81 If N is a negative number, save the N previous articles.
82 If N is nil and any articles have been marked with the process mark,
83 save those articles instead."
85 (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
86 (gnus-summary-save-article arg)))
88 (defun gnus-summary-save-in-vm (&optional folder)
91 (funcall gnus-mail-save-name gnus-newsgroup-name
92 gnus-current-headers gnus-newsgroup-last-mail)))
94 (cond ((eq folder 'default) default-name)
96 (t (gnus-read-save-file-name
97 "Save article in VM folder:" default-name))))
98 (gnus-make-directory (file-name-directory folder))
99 (set-buffer gnus-original-article-buffer)
103 (let ((vm-folder (gnus-vm-make-folder)))
104 (vm-save-message folder)
105 (kill-buffer vm-folder))))
106 ;; Remember the directory name to save articles.
107 (setq gnus-newsgroup-last-mail folder)))
109 (defun gnus-vm-mail-setup (to subject in-reply-to cc replybuffer actions)
113 (defun gnus-mail-forward-using-vm (&optional buffer)
114 "Forward the current message to another user using vm."
115 (let* ((gnus-buffer (or buffer (current-buffer)))
116 (subject (message-make-forward-subject)))
117 (or (featurep 'win-vm)
118 (if gnus-use-full-window
119 (pop-to-buffer gnus-article-buffer)
120 (switch-to-buffer gnus-article-buffer)))
121 (gnus-copy-article-buffer)
122 (set-buffer gnus-article-copy)
126 (let ((vm-folder (gnus-vm-make-folder))
127 (vm-forward-message-hook
128 (append (symbol-value 'vm-forward-message-hook)
131 (mail-position-on-field "Subject")
133 (looking-at "^\\(Subject: \\).*$")
134 (replace-match (concat "\\1" subject))))))))
136 (gnus-vm-init-reply-buffer gnus-buffer)
137 (run-hooks 'gnus-mail-hook)
138 (kill-buffer vm-folder))))))
140 (defun gnus-vm-init-reply-buffer (buffer)
141 (make-local-variable 'gnus-summary-buffer)
142 (setq gnus-summary-buffer buffer)
143 (set 'vm-mail-buffer nil)
144 (use-local-map (copy-keymap (current-local-map)))
145 (local-set-key "\C-c\C-y" 'gnus-yank-article))
147 (defun gnus-mail-reply-using-vm (&optional yank)
148 "Compose reply mail using vm.
149 Optional argument YANK means yank original article.
150 The command \\[vm-yank-message] yank the original message into current buffer."
151 (let ((gnus-buffer (current-buffer)))
152 (gnus-copy-article-buffer)
153 (set-buffer gnus-article-copy)
157 (let ((vm-folder (gnus-vm-make-folder gnus-article-copy)))
159 (gnus-vm-init-reply-buffer gnus-buffer)
160 (setq gnus-buffer (current-buffer))
162 ;; nil will (magically :-)) yank the current article
163 (gnus-yank-article nil))
164 (kill-buffer vm-folder))))
165 (if (featurep 'win-vm) nil
166 (pop-to-buffer gnus-buffer))
167 (run-hooks 'gnus-mail-hook)))
169 (defun gnus-mail-other-window-using-vm ()
170 "Compose mail in the other window using VM."
172 (let ((gnus-buffer (current-buffer)))
174 (gnus-vm-init-reply-buffer gnus-buffer))
175 (run-hooks 'gnus-mail-hook))
177 (defun gnus-yank-article (article &optional prefix)
178 ;; Based on vm-yank-message by Kyle Jones.
179 "Yank article number N into the current buffer at point.
180 When called interactively N is read from the minibuffer.
182 This command is meant to be used in GNUS created Mail mode buffers;
183 the yanked article comes from the newsgroup containing the article
184 you are replying to or forwarding.
186 All article headers are yanked along with the text. Point is left
187 before the inserted text, the mark after. Any hook functions bound to
188 `mail-citation-hook' are run, after inserting the text and setting
191 Prefix arg means to ignore `mail-citation-hook', don't set the mark,
192 prepend the value of `vm-included-text-prefix' to every yanked line.
193 For backwards compatibility, if `mail-citation-hook' is set to nil,
194 `mail-yank-hooks' is run instead. If that is also nil, a default
200 (setq default (and gnus-summary-buffer
202 (set-buffer gnus-summary-buffer)
203 (and gnus-current-article
204 (int-to-string gnus-current-article))))
206 (format "Yank article number: (default %s) " default)
207 "Yank article number: "))
208 (while (and (not (stringp result)) (zerop result))
209 (setq result (read-string prompt))
210 (and (string= result "") default (setq result default))
211 (or (string-match "^<.*>$" result)
212 (setq result (string-to-int result))))
215 (if gnus-summary-buffer
217 (let ((message (current-buffer))
219 (tmp (generate-new-buffer " *tmp-yank*")))
220 (set-buffer gnus-summary-buffer)
221 ;; Make sure the connection to the server is alive.
222 (or (gnus-server-opened (gnus-find-method-for-group
223 gnus-newsgroup-name))
226 (gnus-find-method-for-group gnus-newsgroup-name))
227 (gnus-request-group gnus-newsgroup-name t)))
228 (and (stringp article)
229 (let ((gnus-override-method gnus-refer-article-method))
230 (gnus-read-header article)))
231 (gnus-request-article (or article
232 gnus-current-article)
233 gnus-newsgroup-name tmp)
235 (run-hooks 'gnus-article-prepare-hook)
236 ;; Decode MIME message.
237 (if (and gnus-show-mime
238 (gnus-fetch-field "Mime-Version"))
239 (funcall gnus-show-mime-method))
240 ;; Perform the article display hooks.
241 (let ((buffer-read-only nil))
242 (run-hooks 'gnus-article-display-hook))
243 (append-to-buffer message (point-min) (point-max))
249 (not (or mail-citation-hook mail-yank-hooks)))
251 (while (< (point) end)
252 (insert (symbol-value 'vm-included-text-prefix))
256 (mail-citation-hook (run-hooks 'mail-citation-hook))
257 (mail-yank-hooks (run-hooks 'mail-yank-hooks))))))))
261 ;;; gnus-vm.el ends here.