*** empty log message ***
[gnus] / lisp / gnus-vm.el
1 ;;; gnus-vm.el --- vm interface for Gnus
2 ;; Copyright (C) 1994,95,96 Free Software Foundation, Inc.
3
4 ;; Author: Per Persson <pp@solace.mh.se>
5 ;; Keywords: news, mail
6
7 ;; This file is part of GNU Emacs.
8
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)
12 ;; any later version.
13
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.
18
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.
23
24 ;;; Commentary:
25
26 ;; Major contributors: 
27 ;;      Christian Limpach <Christian.Limpach@nice.ch>
28 ;; Some code stolen from: 
29 ;;      Rick Sladkey <jrs@world.std.com>
30
31 ;;; Code:
32
33 (require 'sendmail)
34 (require 'gnus)
35 (require 'gnus-msg)
36
37 (eval-when-compile
38   (autoload 'vm-mode "vm")
39   (autoload 'vm-save-message "vm")
40   (autoload 'vm-forward-message "vm")
41   (autoload 'vm-reply "vm")
42   (autoload 'vm-mail "vm"))
43
44 (defvar gnus-vm-inhibit-window-system nil
45   "Inhibit loading `win-vm' if using a window-system.
46 Has to be set before gnus-vm is loaded.")
47
48 (or gnus-vm-inhibit-window-system
49     (condition-case nil
50         (if window-system
51             (require 'win-vm))
52       (error nil)))
53
54 (if (not (featurep 'vm))
55     (load "vm"))
56
57 (defun gnus-vm-make-folder (&optional buffer)
58   (let ((article (or buffer (current-buffer)))
59         (tmp-folder (generate-new-buffer " *tmp-folder*"))
60         (start (point-min))
61         (end (point-max)))
62     (set-buffer tmp-folder)
63     (insert-buffer-substring article start end)
64     (goto-char (point-min))
65     (if (looking-at "^\\(From [^ ]+ \\).*$")
66         (replace-match (concat "\\1" (current-time-string)))
67       (insert "From " gnus-newsgroup-name " "
68               (current-time-string) "\n"))
69     (while (re-search-forward "\n\nFrom " nil t)
70       (replace-match "\n\n>From "))
71     ;; insert a newline, otherwise the last line gets lost
72     (goto-char (point-max))
73     (insert "\n")
74     (vm-mode)
75     tmp-folder))
76   
77 (defun gnus-summary-save-article-vm (&optional arg)
78   "Append the current article to a vm folder.
79 If N is a positive number, save the N next articles.
80 If N is a negative number, save the N previous articles.
81 If N is nil and any articles have been marked with the process mark,
82 save those articles instead."
83   (interactive "P")
84   (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
85     (gnus-summary-save-article arg)))
86
87 (defun gnus-summary-save-in-vm (&optional folder)
88   (interactive)
89   (let ((default-name
90           (funcall gnus-mail-save-name gnus-newsgroup-name
91                    gnus-current-headers gnus-newsgroup-last-mail)))
92     (setq folder
93           (cond ((eq folder 'default)
94                  default-name)
95                 (folder folder)
96                 (t (read-file-name 
97                     (concat "Save article in VM folder: (default "
98                             (file-name-nondirectory default-name) ") ")
99                     (file-name-directory default-name)
100                     default-name))))
101     (setq folder
102           (expand-file-name folder
103                             (and default-name
104                                  (file-name-directory default-name))))
105     (gnus-make-directory (file-name-directory folder))
106     (set-buffer gnus-original-article-buffer)
107     (save-excursion
108       (save-restriction
109         (widen)
110         (let ((vm-folder (gnus-vm-make-folder)))
111           (vm-save-message folder)
112           (kill-buffer vm-folder))))
113     ;; Remember the directory name to save articles.
114     (setq gnus-newsgroup-last-mail folder)))
115
116 (defun gnus-vm-mail-setup (to subject in-reply-to cc replybuffer actions)
117   (gnus-sendmail-mail-setup to subject in-reply-to cc replybuffer actions)
118   )
119
120 (defun gnus-mail-forward-using-vm (&optional buffer)
121   "Forward the current message to another user using vm."
122   (let* ((gnus-buffer (or buffer (current-buffer)))
123          (subject (gnus-forward-make-subject gnus-buffer)))
124     (or (featurep 'win-vm)
125         (if gnus-use-full-window
126             (pop-to-buffer gnus-article-buffer)
127           (switch-to-buffer gnus-article-buffer)))
128     (gnus-copy-article-buffer)
129     (set-buffer gnus-article-copy)
130     (save-excursion
131       (save-restriction
132         (widen)
133         (let ((vm-folder (gnus-vm-make-folder))
134               (vm-forward-message-hook
135                (append (symbol-value 'vm-forward-message-hook)
136                        '((lambda ()
137                            (save-excursion
138                              (mail-position-on-field "Subject")
139                              (beginning-of-line)
140                              (looking-at "^\\(Subject: \\).*$")
141                              (replace-match (concat "\\1" subject))))))))
142           (vm-forward-message)
143           (gnus-vm-init-reply-buffer gnus-buffer)
144           (run-hooks 'gnus-mail-hook)
145           (kill-buffer vm-folder))))))
146
147 (defun gnus-vm-init-reply-buffer (buffer)
148   (make-local-variable 'gnus-summary-buffer)
149   (setq gnus-summary-buffer buffer)
150   (set 'vm-mail-buffer nil)
151   (use-local-map (copy-keymap (current-local-map)))
152   (local-set-key "\C-c\C-y" 'gnus-yank-article))
153   
154 (defun gnus-mail-reply-using-vm (&optional yank)
155   "Compose reply mail using vm.
156 Optional argument YANK means yank original article.
157 The command \\[vm-yank-message] yank the original message into current buffer."
158   (let ((gnus-buffer (current-buffer)))
159     (gnus-copy-article-buffer)
160     (set-buffer gnus-article-copy)
161     (save-excursion
162       (save-restriction
163         (widen)
164         (let ((vm-folder (gnus-vm-make-folder gnus-article-copy)))
165           (vm-reply 1)
166           (gnus-vm-init-reply-buffer gnus-buffer)
167           (setq gnus-buffer (current-buffer))
168           (and yank
169                ;; nil will (magically :-)) yank the current article
170                (gnus-yank-article nil))
171           (kill-buffer vm-folder))))
172     (if (featurep 'win-vm) nil
173       (pop-to-buffer gnus-buffer))
174     (run-hooks 'gnus-mail-hook)))
175
176 (defun gnus-mail-other-window-using-vm ()
177   "Compose mail in the other window using VM."
178   (interactive)
179   (let ((gnus-buffer (current-buffer)))
180     (vm-mail)
181     (gnus-vm-init-reply-buffer gnus-buffer))
182   (run-hooks 'gnus-mail-hook))
183
184 (defun gnus-yank-article (article &optional prefix)
185   ;; Based on vm-yank-message by Kyle Jones.
186   "Yank article number N into the current buffer at point.
187 When called interactively N is read from the minibuffer.
188
189 This command is meant to be used in GNUS created Mail mode buffers;
190 the yanked article comes from the newsgroup containing the article
191 you are replying to or forwarding.
192
193 All article headers are yanked along with the text.  Point is left
194 before the inserted text, the mark after.  Any hook functions bound to
195 `mail-citation-hook' are run, after inserting the text and setting
196 point and mark.
197
198 Prefix arg means to ignore `mail-citation-hook', don't set the mark,
199 prepend the value of `vm-included-text-prefix' to every yanked line.
200 For backwards compatibility, if `mail-citation-hook' is set to nil,
201 `mail-yank-hooks' is run instead.  If that is also nil, a default
202 action is taken."
203   (interactive
204    (list
205     (let ((result 0)
206           default prompt)
207       (setq default (and gnus-summary-buffer
208                          (save-excursion
209                            (set-buffer gnus-summary-buffer)
210                            (and gnus-current-article
211                                 (int-to-string gnus-current-article))))
212             prompt (if default
213                        (format "Yank article number: (default %s) " default)
214                      "Yank article number: "))
215       (while (and (not (stringp result)) (zerop result))
216         (setq result (read-string prompt))
217         (and (string= result "") default (setq result default))
218         (or (string-match "^<.*>$" result)
219             (setq result (string-to-int result))))
220       result)
221     current-prefix-arg))
222   (if gnus-summary-buffer
223       (save-excursion
224         (let ((message (current-buffer))
225               (start (point)) end
226               (tmp (generate-new-buffer " *tmp-yank*")))
227           (set-buffer gnus-summary-buffer)
228           ;; Make sure the connection to the server is alive.
229           (or (gnus-server-opened (gnus-find-method-for-group
230                                    gnus-newsgroup-name))
231               (progn
232                 (gnus-check-server 
233                  (gnus-find-method-for-group gnus-newsgroup-name))
234                 (gnus-request-group gnus-newsgroup-name t)))
235           (and (stringp article) 
236                (let ((gnus-override-method gnus-refer-article-method))
237                  (gnus-read-header article)))
238           (gnus-request-article (or article
239                                     gnus-current-article)
240                                 gnus-newsgroup-name tmp)
241           (set-buffer tmp)
242           (run-hooks 'gnus-article-prepare-hook)
243           ;; Decode MIME message.
244           (if (and gnus-show-mime
245                    (gnus-fetch-field "Mime-Version"))
246               (funcall gnus-show-mime-method))
247           ;; Perform the article display hooks.
248           (let ((buffer-read-only nil))
249             (run-hooks 'gnus-article-display-hook))
250           (append-to-buffer message (point-min) (point-max))
251           (kill-buffer tmp)
252           (set-buffer message)
253           (setq end (point))
254           (goto-char start)
255           (if (or prefix
256                   (not (or mail-citation-hook mail-yank-hooks)))
257               (save-excursion
258                 (while (< (point) end)
259                   (insert (symbol-value 'vm-included-text-prefix))
260                   (forward-line 1)))
261             (push-mark end)
262             (cond
263              (mail-citation-hook (run-hooks 'mail-citation-hook))
264              (mail-yank-hooks (run-hooks 'mail-yank-hooks))))))))
265
266 (provide 'gnus-vm)
267
268 ;;; gnus-vm.el ends here.