Require `cl' using `eval-when-compile'.
[elisp/gnus.git-] / lisp / gnus-vm.el
1 ;;; gnus-vm.el --- vm interface for Gnus
2 ;; Copyright (C) 1994,95,96,97,98,99 Free Software Foundation, Inc.
3
4 ;; Author: Per Persson <pp@gnu.ai.mit.edu>
5 ;;         Katsumi Yamaoka <yamaoka@jpl.org>
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 (eval-when-compile (require 'cl))
35 (require 'gnus-art)
36
37 (eval-when-compile
38   (autoload 'vm-mode "vm")
39   (autoload 'vm-read-file-name "vm")
40   (autoload 'vm-save-message "vm"))
41
42 (when (not (featurep 'vm))
43   (load "vm"))
44
45 (defvar vm-folder-directory)
46 (defvar vm-folder-history)
47 (defvar vm-primary-inbox)
48 (defvar vm-use-toolbar)
49   
50 (defun gnus-vm-make-folder (&optional buffer)
51   (let ((article (or buffer (current-buffer)))
52         (tmp-folder (generate-new-buffer " *tmp-folder*"))
53         (start (point-min))
54         (end (point-max)))
55     (set-buffer tmp-folder)
56     (insert-buffer-substring article start end)
57     (goto-char (point-min))
58     (if (looking-at "^\\(From [^ ]+ \\).*$")
59         (replace-match (concat "\\1" (current-time-string)))
60       (insert "From " gnus-newsgroup-name " "
61               (current-time-string) "\n"))
62     (while (re-search-forward "\n\nFrom " nil t)
63       (replace-match "\n\n>From "))
64     ;; insert a newline, otherwise the last line gets lost
65     (goto-char (point-max))
66     (insert "\n")
67     (let (mime-display-header-hook
68           mime-display-text/plain-hook mime-text-decode-hook
69           mime-view-define-keymap-hook mime-view-mode-hook)
70       (vm-mode))
71     tmp-folder))
72
73 (defvar gnus-summary-save-article-vm-folder nil)
74 (defvar gnus-summary-save-article-vm-count nil)
75
76 (defun gnus-summary-save-article-vm (&optional arg folder)
77   "Append the current article to a vm folder.
78 If N is a positive number, save the N next articles.
79 If N is a negative number, save the N previous articles.
80 If N is nil and any articles have been marked with the process mark,
81 save those articles instead."
82   (interactive
83    (let ((prefix-arg current-prefix-arg)
84          articles marks default-folder)
85      (setq default-folder (or (car vm-folder-history) vm-primary-inbox))
86      (if (numberp prefix-arg)
87          (setq articles prefix-arg)
88        (setq marks (delq nil (gnus-summary-work-articles nil))
89              articles (length marks)))
90      (list
91       prefix-arg
92       (unless (zerop articles)
93         (vm-read-file-name
94          (format
95           "Save %s in VM folder: "
96           (cond ((eq 1 articles)
97                  (if (or (not marks) (eq gnus-current-article (car marks)))
98                      "this article"
99                    "the marked article"))
100                 ((< 0 articles)
101                  (if marks
102                      (format "the marked %d articles" articles)
103                    (format "the %d next articles" articles)))
104                 ((> 0 articles)
105                  (format "the %d previous articles" (- articles)))))
106          (if default-folder "" vm-folder-directory)
107          nil nil default-folder 'vm-folder-history)))))
108   (if (interactive-p)
109       (unless folder
110         (error "No articles to be saved"))
111     (unless (setq folder (or folder gnus-summary-save-article-vm-folder))
112       (error "No VM folder is specified")))
113   (unwind-protect
114       (progn
115         (setq gnus-summary-save-article-vm-folder folder
116               gnus-summary-save-article-vm-count 0)
117         (let ((gnus-default-article-saver 'gnus-summary-save-in-vm)
118               mime-display-header-hook mime-display-text/plain-hook
119               mime-text-decode-hook mime-view-define-keymap-hook
120               mime-view-mode-hook)
121           (gnus-summary-save-article arg))
122         (cond ((eq 1 gnus-summary-save-article-vm-count)
123                (message "One article is saved in %s" folder))
124               ((< 0 gnus-summary-save-article-vm-count)
125                (message "%d articles are saved in %s"
126                         gnus-summary-save-article-vm-count folder))
127               (t
128                (message "Maybe no articles are saved in %s" folder))))
129     (setq gnus-summary-save-article-vm-folder nil
130           gnus-summary-save-article-vm-count nil)))
131
132 (defun gnus-summary-save-in-vm (&optional folder)
133   (interactive
134    (let (default-folder)
135      (setq default-folder (or (car vm-folder-history) vm-primary-inbox))
136      (list (vm-read-file-name "Save this article in VM folder: "
137                               (if default-folder "" vm-folder-directory)
138                               nil nil default-folder 'vm-folder-history))))
139   (unless (interactive-p)
140     (setq folder (or folder gnus-summary-save-article-vm-folder)))
141   (unless folder
142     (error "No VM folder is specified"))
143   (unless (interactive-p)
144     (message "Saving the article %d in %s..." gnus-current-article folder)
145     (when (numberp gnus-summary-save-article-vm-count)
146       (incf gnus-summary-save-article-vm-count)))
147   (save-window-excursion
148     (apply 'gnus-summary-select-article gnus-show-all-headers
149            (unless (interactive-p)
150              (list nil nil gnus-current-article)))
151     (gnus-eval-in-buffer-window gnus-original-article-buffer
152       (save-excursion
153         (save-restriction
154           (widen)
155           (let* ((vm-use-toolbar nil)
156                  (vm-folder (gnus-vm-make-folder)))
157             (vm-save-message folder)
158             (when (interactive-p)
159               (message "This article is saved in %s" folder))
160             (kill-buffer vm-folder)))))))
161
162 (provide 'gnus-vm)
163
164 ;;; gnus-vm.el ends here.