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