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