Include nt/inc/arpa and nt/inc/netinet in the dist.
[bpt/emacs.git] / lisp / gnus-vm.el
1 ;;; gnus-vm.el --- vm interface for Gnus
2
3 ;; Copyright (C) 1994,95 Free Software Foundation, Inc.
4
5 ;; Author: Per Persson <pp@solace.mh.se>
6 ;; Keywords: news, mail
7
8 ;; This file is part of GNU Emacs.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24
25 ;;; Commentary:
26
27 ;; Major contributors:
28 ;; Christian Limpach <Christian.Limpach@nice.ch>
29 ;; Some code stolen from:
30 ;; Rick Sladkey <jrs@world.std.com>
31
32 ;;; Code:
33
34 (require 'sendmail)
35 (require 'gnus)
36 (require 'gnus-msg)
37
38 (eval-when-compile
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"))
44
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.")
48
49 (or gnus-vm-inhibit-window-system
50 (condition-case nil
51 (if window-system
52 (require 'win-vm))
53 (error nil)))
54
55 (if (not (featurep 'vm))
56 (load "vm"))
57
58 (defun gnus-vm-make-folder (&optional buffer)
59 (let ((article (or buffer (current-buffer)))
60 (tmp-folder (generate-new-buffer " *tmp-folder*"))
61 (start (point-min))
62 (end (point-max)))
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))
74 (insert "\n")
75 (vm-mode)
76 tmp-folder))
77
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."
84 (interactive "P")
85 (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
86 (gnus-summary-save-article arg)))
87
88 (defun gnus-summary-save-in-vm (&optional folder)
89 (interactive)
90 (let ((default-name
91 (funcall gnus-mail-save-name gnus-newsgroup-name
92 gnus-current-headers gnus-newsgroup-last-mail)))
93 (or folder
94 (setq folder
95 (read-file-name
96 (concat "Save article in VM folder: (default "
97 (file-name-nondirectory default-name) ") ")
98 (file-name-directory default-name)
99 default-name)))
100 (setq folder
101 (expand-file-name folder
102 (and default-name
103 (file-name-directory default-name))))
104 (gnus-make-directory (file-name-directory folder))
105 (set-buffer gnus-article-buffer)
106 (save-excursion
107 (save-restriction
108 (widen)
109 (let ((vm-folder (gnus-vm-make-folder)))
110 (vm-save-message folder)
111 (kill-buffer vm-folder))))
112 ;; Remember the directory name to save articles.
113 (setq gnus-newsgroup-last-mail folder)))
114
115 (defun gnus-mail-forward-using-vm (&optional buffer)
116 "Forward the current message to another user using vm."
117 (let* ((gnus-buffer (or buffer (current-buffer)))
118 (subject (gnus-forward-make-subject gnus-buffer)))
119 (or (featurep 'win-vm)
120 (if gnus-use-full-window
121 (pop-to-buffer gnus-article-buffer)
122 (switch-to-buffer gnus-article-buffer)))
123 (gnus-copy-article-buffer)
124 (set-buffer gnus-article-copy)
125 (save-excursion
126 (save-restriction
127 (widen)
128 (let ((vm-folder (gnus-vm-make-folder))
129 (vm-forward-message-hook
130 (append (symbol-value 'vm-forward-message-hook)
131 '((lambda ()
132 (save-excursion
133 (mail-position-on-field "Subject")
134 (beginning-of-line)
135 (looking-at "^\\(Subject: \\).*$")
136 (replace-match (concat "\\1" subject))))))))
137 (vm-forward-message)
138 (gnus-vm-init-reply-buffer gnus-buffer)
139 (run-hooks 'gnus-mail-hook)
140 (kill-buffer vm-folder))))))
141
142 (defun gnus-vm-init-reply-buffer (buffer)
143 (make-local-variable 'gnus-summary-buffer)
144 (setq gnus-summary-buffer buffer)
145 (set 'vm-mail-buffer nil)
146 (use-local-map (copy-keymap (current-local-map)))
147 (local-set-key "\C-c\C-y" 'gnus-yank-article))
148
149 (defun gnus-mail-reply-using-vm (&optional yank)
150 "Compose reply mail using vm.
151 Optional argument YANK means yank original article.
152 The command \\[vm-yank-message] yank the original message into current buffer."
153 (let ((gnus-buffer (current-buffer)))
154 (gnus-copy-article-buffer)
155 (set-buffer gnus-article-copy)
156 (save-excursion
157 (save-restriction
158 (widen)
159 (let ((vm-folder (gnus-vm-make-folder gnus-article-copy)))
160 (vm-reply 1)
161 (gnus-vm-init-reply-buffer gnus-buffer)
162 (setq gnus-buffer (current-buffer))
163 (and yank
164 ;; nil will (magically :-)) yank the current article
165 (gnus-yank-article nil))
166 (kill-buffer vm-folder))))
167 (if (featurep 'win-vm) nil
168 (pop-to-buffer gnus-buffer))
169 (run-hooks 'gnus-mail-hook)))
170
171 (defun gnus-mail-other-window-using-vm ()
172 "Compose mail in the other window using VM."
173 (interactive)
174 (let ((gnus-buffer (current-buffer)))
175 (vm-mail)
176 (gnus-vm-init-reply-buffer gnus-buffer))
177 (run-hooks 'gnus-mail-hook))
178
179 (defun gnus-yank-article (article &optional prefix)
180 ;; Based on vm-yank-message by Kyle Jones.
181 "Yank article number N into the current buffer at point.
182 When called interactively N is read from the minibuffer.
183
184 This command is meant to be used in GNUS created Mail mode buffers;
185 the yanked article comes from the newsgroup containing the article
186 you are replying to or forwarding.
187
188 All article headers are yanked along with the text. Point is left
189 before the inserted text, the mark after. Any hook functions bound to
190 `mail-citation-hook' are run, after inserting the text and setting
191 point and mark.
192
193 Prefix arg means to ignore `mail-citation-hook', don't set the mark,
194 prepend the value of `vm-included-text-prefix' to every yanked line.
195 For backwards compatibility, if `mail-citation-hook' is set to nil,
196 `mail-yank-hooks' is run instead. If that is also nil, a default
197 action is taken."
198 (interactive
199 (list
200 (let ((result 0)
201 default prompt)
202 (setq default (and gnus-summary-buffer
203 (save-excursion
204 (set-buffer gnus-summary-buffer)
205 (and gnus-current-article
206 (int-to-string gnus-current-article))))
207 prompt (if default
208 (format "Yank article number: (default %s) " default)
209 "Yank article number: "))
210 (while (and (not (stringp result)) (zerop result))
211 (setq result (read-string prompt))
212 (and (string= result "") default (setq result default))
213 (or (string-match "^<.*>$" result)
214 (setq result (string-to-int result))))
215 result)
216 current-prefix-arg))
217 (if gnus-summary-buffer
218 (save-excursion
219 (let ((message (current-buffer))
220 (start (point)) end
221 (tmp (generate-new-buffer " *tmp-yank*")))
222 (set-buffer gnus-summary-buffer)
223 ;; Make sure the connection to the server is alive.
224 (or (gnus-server-opened (gnus-find-method-for-group
225 gnus-newsgroup-name))
226 (progn
227 (gnus-check-server
228 (gnus-find-method-for-group gnus-newsgroup-name))
229 (gnus-request-group gnus-newsgroup-name t)))
230 (and (stringp article)
231 (let ((gnus-override-method gnus-refer-article-method))
232 (gnus-read-header article)))
233 (gnus-request-article (or article
234 gnus-current-article)
235 gnus-newsgroup-name tmp)
236 (set-buffer tmp)
237 (run-hooks 'gnus-article-prepare-hook)
238 ;; Decode MIME message.
239 (if (and gnus-show-mime
240 (gnus-fetch-field "Mime-Version"))
241 (funcall gnus-show-mime-method))
242 ;; Perform the article display hooks.
243 (let ((buffer-read-only nil))
244 (run-hooks 'gnus-article-display-hook))
245 (append-to-buffer message (point-min) (point-max))
246 (kill-buffer tmp)
247 (set-buffer message)
248 (setq end (point))
249 (goto-char start)
250 (if (or prefix
251 (not (or mail-citation-hook mail-yank-hooks)))
252 (save-excursion
253 (while (< (point) end)
254 (insert (symbol-value 'vm-included-text-prefix))
255 (forward-line 1)))
256 (push-mark end)
257 (cond
258 (mail-citation-hook (run-hooks 'mail-citation-hook))
259 (mail-yank-hooks (run-hooks 'mail-yank-hooks))))))))
260
261 (provide 'gnus-vm)
262
263 ;;; gnus-vm.el ends here.