Update copyright year to 2016
[gnus] / lisp / nndiary.el
index 3a35379..9245396 100644 (file)
@@ -1,7 +1,6 @@
-;;; nndiary.el --- A diary backend for Gnus
+;;; nndiary.el --- A diary back end for Gnus
 
-;; Copyright (C) 1999, 2000, 2001, 2003
-;;        Free Software Foundation, Inc.
+;; Copyright (C) 1999-2016 Free Software Foundation, Inc.
 
 ;; Author:        Didier Verna <didier@xemacs.org>
 ;; Maintainer:    Didier Verna <didier@xemacs.org>
@@ -10,9 +9,9 @@
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2 of the License, or
+;; the Free Software Foundation, either version 3 of the License, or
 ;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -21,8 +20,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with this program; if not, write to the Free Software
-;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 
 ;;; Commentary:
 ;; Description:
 ;; ===========
 
-;; This package implements NNDiary, a diary backend for Gnus.  NNDiary is a
-;; mail backend, pretty similar to nnml in its functionnning (it has all the
-;; features of nnml, actually), but in which messages are treated as event
-;; reminders.
-
-;; Here is a typical scenario:
-;; - You've got a date with Andy Mc Dowell or Bruce Willis (select according
-;;   to your sexual preference) in one month.  You don't want to forget it.
-;; - Send a (special) diary message to yourself (see below).
-;; - Forget all about it and keep on getting and reading new mail, as usual.
-;; - From time to time, as you type `g' in the group buffer and as the date
-;;   is getting closer, the message will pop up again, just like if it were
-;;   new and unread.
-;; - Read your "new" messages, this one included, and start dreaming of the
-;;   night you're gonna have.
-;; - Once the date is over (you actually fell asleep just after dinner), the
-;;   message will be automatically deleted if it is marked as expirable.
-
-;; Some more notes on the diary backend:
-;; - NNDiary is a *real* mail backend.  You *really* send real diary
-;;   messsages.  This means for instance that you can give appointements to
-;;   anybody (provided they use Gnus and NNDiary) by sending the diary message
-;;   to them as well.
-;; - However, since NNDiary also has a 'request-post method, you can also
-;;  `C-u a' instead of `C-u m' on a diary group and the message won't actually
-;;   be sent; just stored in the group.
-;; - The events you want to remember need not be punctual.  You can set up
-;;   reminders for regular dates (like once each week, each monday at 13:30
-;;   and so on).  Diary messages of this kind will never be deleted (unless
-;;   you do it explicitely).  But that, you guessed.
-
-
-;; Usage:
-;; =====
-
-;;  1/ NNDiary has two modes of operation: traditional (the default) and
-;;     autonomous.
-;;     a/ In traditional mode, NNDiary does not get new mail by itself.  You
-;;        have to move mails from your primary mail backend to nndiary
-;;        groups.
-;;     b/ In autonomous mode, NNDiary retrieves its own mail and handles it
-;;        independantly of your primary mail backend.  To use NNDiary in
-;;        autonomous mode, you have several things to do:
-;;           i/ Put (setq nndiary-get-new-mail t) in your gnusrc file.
-;;          ii/ Diary messages contain several `X-Diary-*' special headers.
-;;              You *must* arrange that these messages be split in a private
-;;              folder *before* Gnus treat them.  You need this because Gnus
-;;              is not able yet to manage multiple backends for mail
-;;              retrieval.  Getting them from a separate source will
-;;              compensate this misfeature to some extent, as we will see.
-;;              As an example, here's my procmailrc entry to store diary files
-;;              in ~/.nndiary (the default nndiary mail source file):
-;;
-;;              :0 HD :
-;;              * ^X-Diary
-;;              .nndiary
-;;         iii/ Customize the variables `nndiary-mail-sources' and
-;;              `nndiary-split-methods'.  These are replacements for the usual
-;;              mail sources and split methods which, and will be used in
-;;              autonomous mode.  `nndiary-mail-sources' defaults to
-;;              '(file :path "~/.nndiary").
-;;  2/ Install nndiary somewhere Emacs / Gnus can find it.  Normally, you
-;;     *don't* have to '(require 'nndiary) anywhere.  Gnus will do so when
-;;     appropriate as long as nndiary is somewhere in the load path.
-;;  3/ Now, customize the rest of nndiary.  In particular, you should
-;;     customize `nndiary-reminders', the list of times when you want to be
-;;     reminded of your appointements (e.g. 3 weeks before, then 2 days
-;;     before, then 1 hour before and that's it).
-;;  4/ You *must* use the group timestamp feature of Gnus.  This adds a
-;;     timestamp to each groups' parameters (please refer to the Gnus
-;;     documentation ("Group Timestamp" info node) to see how it's done.
-;;  5/ Once you have done this, you may add a permanent nndiary virtual server
-;;     (something like '(nndiary "")) to your `gnus-secondary-select-methods'.
-;;     Yes, this server will be able to retrieve mails and split them when you
-;;     type `g' in the group buffer, just as if it were your only mail backend.
-;;     This is the benefit of using a private folder.
-;;  6/ Hopefully, almost everything (see the TODO section below) will work as
-;;     expected when you restart Gnus: in the group buffer, `g' and `M-g' will
-;;     also get your new diary mails, `F' will find your new diary groups etc.
-
-
-;; How to send diary messages:
-;; ==========================
-
-;; There are 7 special headers in diary messages. These headers are of the
-;; form `X-Diary-<something>', the <something> being one of `Minute', `Hour',
-;; `Dom', `Month', `Year', `Time-Zone' and `Dow'. `Dom' means "Day of Month",
-;; and `dow' means "Day of Week".  These headers actually behave like crontab
-;; specifications and define the event date(s).
-
-;; For all headers but the `Time-Zone' one, a header value is either a
-;; star (meaning all possible values), or a list of fields (separated by a
-;; comma).  A field is either an integer, or a range.  A range is two integers
-;; separated by a dash.  Possible integer values are 0-59 for `Minute', 0-23
-;; for `Hour', 1-31 for `Dom', `1-12' for Month, above 1971 for `Year' and 0-6
-;; for `Dow' (0 = sunday).  As a special case, a star in either `Dom' or `Dow'
-;; doesn't mean "all possible values", but "use only the other field".  Note
-;; that if both are star'ed, the use of either one gives the same result :-),
-
-;; The `Time-Zone' header is special in that it can have only one value (you
-;; bet ;-).
-;; A star doesn't mean "all possible values" (because it has no sense), but
-;; "the current local time zone".
-
-;; As an example, here's how you would say "Each Monday and each 1st of month,
-;; at 12:00, 20:00, 21:00, 22:00, 23:00 and 24:00, from 1999 to 2010" (I let
-;; you find what to do then):
-;;
-;;   X-Diary-Minute: 0
-;;   X-Diary-Hour: 12, 20-24
-;;   X-Diary-Dom: 1
-;;   X-Diary-Month: *
-;;   X-Diary-Year: 1999-2010
-;;   X-Diary-Dow: 1
-;;   X-Diary-Time-Zone: *
-;;
-;;
-;; Sending a diary message is not different from sending any other kind of
-;; mail, except that such messages are identified by the presence of these
-;; special headers.
-
+;; nndiary is a mail back end designed to handle mails as diary event
+;; reminders. It is now fully documented in the Gnus manual.
 
 
 ;; Bugs / Todo:
 
 ;; * Respooling doesn't work because contrary to the request-scan function,
 ;;   Gnus won't allow me to override the split methods when calling the
-;;   respooling backend functions.
+;;   respooling back end functions.
 ;; * There's a bug in the time zone mechanism with variable TZ locations.
 ;; * We could allow a keyword like `ask' in X-Diary-* headers, that would mean
 ;;   "ask for value upon reception of the message".
 ;; * We could add an optional header X-Diary-Reminders to specify a special
 ;;   reminders value for this message. Suggested by Jody Klymak.
 ;; * We should check messages validity in other circumstances than just
-;;   moving an article from sonwhere else (request-accept). For instance, when
-;;   editing / saving and so on.
+;;   moving an article from somewhere else (request-accept). For instance,
+;;   when editing / saving and so on.
 
 
 ;; Remarks:
 ;; =======
 
-;; * nnoo.
-;;   NNDiary is very similar to nnml.  This makes the idea of using nnoo (to
-;;   derive nndiary from nnml) natural.  However, my experience with nnoo is
-;;   that for reasonably complex backends like this one, noo is a burden
-;;   rather than an help.  It's tricky to use, not everything can be
-;;   inherited, what can be inherited and when is not very clear, and you've
-;;   got to be very careful because a little mistake can fuck up your your
-;;   other backends, especially because their variables will be use instead of
-;;   your real ones.  Finally, I found it easier to just clone the needed
-;;   parts of nnml, and tracking nnml updates is not a big deal.
+;; * nnoo. NNDiary is very similar to nnml. This makes the idea of using nnoo
+;;   (to derive nndiary from nnml) natural. However, my experience with nnoo
+;;   is that for reasonably complex back ends like this one, nnoo is a burden
+;;   rather than an help. It's tricky to use, not everything can be inherited,
+;;   what can be inherited and when is not very clear, and you've got to be
+;;   very careful because a little mistake can fuck up your other back ends,
+;;   especially because their variables will be use instead of your real ones.
+;;   Finally, I found it easier to just clone the needed parts of nnml, and
+;;   tracking nnml updates is not a big deal.
 
 ;;   IMHO, nnoo is actually badly designed.  A much simpler, and yet more
 ;;   powerful one would be to make *real* functions and variables for a new
-;;   backend based on another. Lisp is a reflexive language so that's a very
-;;   easy thing to do: inspect the function's form, replace occurences of
+;;   back end based on another. Lisp is a reflexive language so that's a very
+;;   easy thing to do: inspect the function's form, replace occurrences of
 ;;   <nnfrom> (even in strings) with <nnto>, and you're done.
 
 ;; * nndiary-get-new-mail, nndiary-mail-source and nndiary-split-methods:
 ;;   NNDiary has some experimental parts, in the sense Gnus normally uses only
-;;   one mail backends for mail retreival and splitting.  This backend is also
-;;   an attempt to make it behave differently.  For Gnus developpers: as you
-;;   can see if you snarf into the code, that was not a very difficult thing
-;;   to do.  Something should be done about the respooling breakage though.
+;;   one mail back ends for mail retrieval and splitting. This back end is
+;;   also an attempt to make it behave differently. For Gnus developers: as
+;;   you can see if you snarf into the code, that was not a very difficult
+;;   thing to do. Something should be done about the respooling breakage
+;;   though.
 
 
 ;;; Code:
       (apply #'error args))))
 
 
-;; Backend behavior customization ===========================================
+;; Back End behavior customization ===========================================
 
 (defgroup nndiary nil
-  "The Gnus Diary backend."
+  "The Gnus Diary back end."
   :version "22.1"
   :group 'gnus-diary)
 
@@ -249,7 +128,7 @@ non-nil."
 
 
 (defcustom nndiary-reminders '((0 . day))
-  "*Different times when you want to be reminded of your appointements.
+  "*Different times when you want to be reminded of your appointments.
 Diary articles will appear again, as if they'd been just received.
 
 Entries look like (3 . day) which means something like \"Please
@@ -262,8 +141,8 @@ not 'century, sorry).
 
 NOTE: the units of measure actually express dates, not durations: if you
 use 'week, messages will pop up on Sundays at 00:00 (or Mondays if
-`nndiary-week-starts-on-monday' is non nil) and *not* 7 days before the
-appointement, if you use 'month, messages will pop up on the first day of
+`nndiary-week-starts-on-monday' is non-nil) and *not* 7 days before the
+appointment, if you use 'month, messages will pop up on the first day of
 each months, at 00:00 and so on.
 
 If you really want to specify a duration (like 24 hours exactly), you can
@@ -272,16 +151,16 @@ maximum in the reminder is not that painful, I think.  Although this
 scheme might appear somewhat weird at a first glance, it is very powerful.
 In order to make this clear, here are some examples:
 
-- '(0 . day): this is the default value of `nndiary-reminders'.  It means
-  pop up the appointements of the day each morning at 00:00.
+- (0 . day): this is the default value of `nndiary-reminders'.  It means
+  pop up the appointments of the day each morning at 00:00.
 
-- '(1 . day): this means pop up the appointements the day before, at 00:00.
+- (1 . day): this means pop up the appointments the day before, at 00:00.
 
-- '(6 . hour): for an appointement at 18:30, this would pop up the
-  appointement message at 12:00.
+- (6 . hour): for an appointment at 18:30, this would pop up the
+  appointment message at 12:00.
 
-- '(360 . minute): for an appointement at 18:30 and 15 seconds, this would
-  pop up the appointement message at 12:30."
+- (360 . minute): for an appointment at 18:30 and 15 seconds, this would
+  pop up the appointment message at 12:30."
   :group 'nndiary
   :type '(repeat (cons :format "%v\n"
                       (integer :format "%v")
@@ -300,22 +179,28 @@ In order to make this clear, here are some examples:
   :group 'nndiary)
 
 
-(defcustom nndiary-request-create-group-hooks nil
-  "*Hooks to run after `nndiary-request-create-group' is executed.
-The hooks will be called with the full group name as argument."
+(define-obsolete-variable-alias 'nndiary-request-create-group-hooks
+  'nndiary-request-create-group-functions "24.3")
+(defcustom nndiary-request-create-group-functions nil
+  "*Hook run after `nndiary-request-create-group' is executed.
+The hook functions will be called with the full group name as argument."
   :group 'nndiary
   :type 'hook)
 
-(defcustom nndiary-request-update-info-hooks nil
-  "*Hooks to run after `nndiary-request-update-info-group' is executed.
-The hooks will be called with the full group name as argument."
+(define-obsolete-variable-alias 'nndiary-request-update-info-hooks
+  'nndiary-request-update-info-functions "24.3")
+(defcustom nndiary-request-update-info-functions nil
+  "*Hook run after `nndiary-request-update-info-group' is executed.
+The hook functions will be called with the full group name as argument."
   :group 'nndiary
   :type 'hook)
 
-(defcustom nndiary-request-accept-article-hooks nil
-  "*Hooks to run before accepting an article.
+(define-obsolete-variable-alias 'nndiary-request-accept-article-hooks
+  'nndiary-request-accept-article-functions "24.3")
+(defcustom nndiary-request-accept-article-functions nil
+  "*Hook run before accepting an article.
 Executed near the beginning of `nndiary-request-accept-article'.
-The hooks will be called with the article in the current buffer."
+The hook functions will be called with the article in the current buffer."
   :group 'nndiary
   :type 'hook)
 
@@ -325,27 +210,27 @@ The hooks will be called with the article in the current buffer."
   :type 'boolean)
 
 
-;; Backend declaration ======================================================
+;; Back End declaration ======================================================
 
 ;; Well, most of this is nnml clonage.
 
 (nnoo-declare nndiary)
 
 (defvoo nndiary-directory (nnheader-concat gnus-directory "diary/")
-  "Spool directory for the nndiary backend.")
+  "Spool directory for the nndiary back end.")
 
 (defvoo nndiary-active-file
     (expand-file-name "active" nndiary-directory)
-  "Active file for the nndiary backend.")
+  "Active file for the nndiary back end.")
 
 (defvoo nndiary-newsgroups-file
     (expand-file-name "newsgroups" nndiary-directory)
-  "Newsgroups description file for the nndiary backend.")
+  "Newsgroups description file for the nndiary back end.")
 
 (defvoo nndiary-get-new-mail nil
   "Whether nndiary gets new mail and split it.
-Contrary to traditional mail backends, this variable can be set to t
-even if your primary mail backend also retreives mail. In such a case,
+Contrary to traditional mail back ends, this variable can be set to t
+even if your primary mail back end also retrieves mail. In such a case,
 NDiary uses its own mail-sources and split-methods.")
 
 (defvoo nndiary-nov-is-evil nil
@@ -366,10 +251,10 @@ all.  This may very well take some time.")
 \f
 
 (defconst nndiary-version "0.2-b14"
-  "Current Diary backend version.")
+  "Current Diary back end version.")
 
 (defun nndiary-version ()
-  "Current Diary backend version."
+  "Current Diary back end version."
   (interactive)
   (message "NNDiary version %s" nndiary-version))
 
@@ -474,7 +359,7 @@ all.  This may very well take some time.")
   ;; List of NNDiary headers that specify the time spec. Each header name is
   ;; followed by either two integers (specifying a range of possible values
   ;; for this header) or one list (specifying all the possible values for this
-  ;; header). In the latter case, the list does NOT include the unspecifyed
+  ;; header). In the latter case, the list does NOT include the unspecified
   ;; spec (*).
   ;; For time zone values, we have symbolic time zone names associated with
   ;; the (relative) number of seconds ahead GMT.
@@ -488,7 +373,7 @@ all.  This may very well take some time.")
           (setq head (nth 0 elt))
           (nndiary-parse-schedule (nth 0 elt) (nth 1 elt) (nth 2 elt)))
         nndiary-headers)
-      (t
+      (error
        (nnheader-report 'nndiary "X-Diary-%s header parse error: %s."
                        head (cdr arg))
        nil))
@@ -500,8 +385,7 @@ all.  This may very well take some time.")
 
 (deffoo nndiary-retrieve-headers (sequence &optional group server fetch-old)
   (when (nndiary-possibly-change-directory group server)
-    (save-excursion
-      (set-buffer nntp-server-buffer)
+    (with-current-buffer nntp-server-buffer
       (erase-buffer)
       (let* ((file nil)
             (number (length sequence))
@@ -539,7 +423,7 @@ all.  This may very well take some time.")
                   (> number nnmail-large-newsgroup)
                   (zerop (% count 20))
                   (nnheader-message 6 "nndiary: Receiving headers... %d%%"
-                                    (/ (* count 100) number))))
+                                    (floor (* count 100.0) number))))
 
            (and (numberp nnmail-large-newsgroup)
                 (> number nnmail-large-newsgroup)
@@ -601,9 +485,9 @@ all.  This may very well take some time.")
       (nnheader-report 'nndiary "Article %s retrieved" id)
       ;; We return the article number.
       (cons (if group-num (car group-num) group)
-           (string-to-int (file-name-nondirectory path)))))))
+           (string-to-number (file-name-nondirectory path)))))))
 
-(deffoo nndiary-request-group (group &optional server dont-check)
+(deffoo nndiary-request-group (group &optional server dont-check info)
   (let ((file-name-coding-system nnmail-pathname-coding-system))
     (cond
      ((not (nndiary-possibly-change-directory group server))
@@ -630,7 +514,7 @@ all.  This may very well take some time.")
 
 (deffoo nndiary-request-scan (&optional group server)
   ;; Use our own mail sources and split methods while Gnus doesn't let us have
-  ;; multiple backends for retrieving mail.
+  ;; multiple back ends for retrieving mail.
   (let ((mail-sources nndiary-mail-sources)
        (nnmail-split-methods nndiary-split-methods))
     (setq nndiary-article-file-alist nil)
@@ -663,7 +547,7 @@ all.  This may very well take some time.")
          (setcar active (apply 'min articles))
          (setcdr active (apply 'max articles))))
       (nnmail-save-active nndiary-group-alist nndiary-active-file)
-      (run-hook-with-args 'nndiary-request-create-group-hooks
+      (run-hook-with-args 'nndiary-request-create-group-functions
                          (gnus-group-prefixed-name group
                                                    (list "nndiary" server)))
       t))
@@ -724,7 +608,7 @@ all.  This may very well take some time.")
     (nconc rest articles)))
 
 (deffoo nndiary-request-move-article
-    (article group server accept-form &optional last)
+    (article group server accept-form &optional last move-is-internal)
   (let ((buf (get-buffer-create " *nndiary move*"))
        result)
     (nndiary-possibly-change-directory group server)
@@ -735,8 +619,7 @@ all.  This may very well take some time.")
      (let (nndiary-current-directory
           nndiary-current-group
           nndiary-article-file-alist)
-       (save-excursion
-        (set-buffer buf)
+       (with-current-buffer buf
         (insert-buffer-substring nntp-server-buffer)
         (setq result (eval accept-form))
         (kill-buffer (current-buffer))
@@ -756,7 +639,7 @@ all.  This may very well take some time.")
 (deffoo nndiary-request-accept-article (group &optional server last)
   (nndiary-possibly-change-directory group server)
   (nnmail-check-syntax)
-  (run-hooks 'nndiary-request-accept-article-hooks)
+  (run-hooks 'nndiary-request-accept-article-functions)
   (when (nndiary-schedule)
     (let (result)
       (when nnmail-cache-accepted-message-ids
@@ -792,8 +675,7 @@ all.  This may very well take some time.")
 
 (deffoo nndiary-request-replace-article (article group buffer)
   (nndiary-possibly-change-directory group)
-  (save-excursion
-    (set-buffer buffer)
+  (with-current-buffer buffer
     (nndiary-possibly-create-directory group)
     (let ((chars (nnmail-insert-lines))
          (art (concat (int-to-string article) "\t"))
@@ -808,8 +690,7 @@ all.  This may very well take some time.")
              t)
        (setq headers (nndiary-parse-head chars article))
        ;; Replace the NOV line in the NOV file.
-       (save-excursion
-         (set-buffer (nndiary-open-nov group))
+       (with-current-buffer (nndiary-open-nov group)
          (goto-char (point-min))
          (if (or (looking-at art)
                  (search-forward (concat "\n" art) nil t))
@@ -820,7 +701,7 @@ all.  This may very well take some time.")
            ;; we should insert it.  (This situation should never
            ;; occur, but one likes to make sure...)
            (while (and (looking-at "[0-9]+\t")
-                       (< (string-to-int
+                       (< (string-to-number
                            (buffer-substring
                             (match-beginning 0) (match-end 0)))
                           article)
@@ -929,7 +810,7 @@ all.  This may very well take some time.")
             (gnus-info-set-read info (gnus-update-read-articles
                                       (gnus-info-group info) unread t)))
        ))
-    (run-hook-with-args 'nndiary-request-update-info-hooks
+    (run-hook-with-args 'nndiary-request-update-info-functions
                        (gnus-info-group info))
     t))
 
@@ -962,8 +843,7 @@ all.  This may very well take some time.")
 
 ;; Find an article number in the current group given the Message-ID.
 (defun nndiary-find-group-number (id)
-  (save-excursion
-    (set-buffer (get-buffer-create " *nndiary id*"))
+  (with-current-buffer (get-buffer-create " *nndiary id*")
     (let ((alist nndiary-group-alist)
          number)
       ;; We want to look through all .overview files, but we want to
@@ -1008,8 +888,7 @@ all.  This may very well take some time.")
     (let ((nov (expand-file-name nndiary-nov-file-name
                                 nndiary-current-directory)))
       (when (file-exists-p nov)
-       (save-excursion
-         (set-buffer nntp-server-buffer)
+       (with-current-buffer nntp-server-buffer
          (erase-buffer)
          (nnheader-insert-file-contents nov)
          (if (and fetch-old
@@ -1109,8 +988,7 @@ all.  This may very well take some time.")
 
 (defun nndiary-add-nov (group article headers)
   "Add a nov line for the GROUP base."
-  (save-excursion
-    (set-buffer (nndiary-open-nov group))
+  (with-current-buffer (nndiary-open-nov group)
     (goto-char (point-max))
     (mail-header-set-number headers article)
     (nnheader-insert-nov headers)))
@@ -1135,8 +1013,7 @@ all.  This may very well take some time.")
   (or (cdr (assoc group nndiary-nov-buffer-alist))
       (let ((buffer (get-buffer-create (format " *nndiary overview %s*"
                                               group))))
-       (save-excursion
-         (set-buffer buffer)
+       (with-current-buffer buffer
          (set (make-local-variable 'nndiary-nov-buffer-file-name)
               (expand-file-name
                nndiary-nov-file-name
@@ -1189,9 +1066,9 @@ all.  This may very well take some time.")
                   (file-directory-p dir))
          (nndiary-generate-nov-databases-1 dir seen))))
     ;; Do this directory.
-    (let ((files (sort (nnheader-article-to-file-alist dir)
+    (let ((nndiary-files (sort (nnheader-article-to-file-alist dir)
                       'car-less-than-car)))
-      (if (not files)
+      (if (not nndiary-files)
          (let* ((group (nnheader-file-to-group
                         (directory-file-name dir) nndiary-directory))
                 (info (cadr (assoc group nndiary-group-alist))))
@@ -1199,11 +1076,11 @@ all.  This may very well take some time.")
              (setcar info (1+ (cdr info)))))
        (funcall nndiary-generate-active-function dir)
        ;; Generate the nov file.
-       (nndiary-generate-nov-file dir files)
+       (nndiary-generate-nov-file dir nndiary-files)
        (unless no-active
          (nnmail-save-active nndiary-group-alist nndiary-active-file))))))
 
-(eval-when-compile (defvar files))
+(defvar nndiary-files) ; dynamically bound in nndiary-generate-nov-databases-1
 (defun nndiary-generate-active-info (dir)
   ;; Update the active info for this group.
   (let* ((group (nnheader-file-to-group
@@ -1212,9 +1089,9 @@ all.  This may very well take some time.")
         (last (or (caadr entry) 0)))
     (setq nndiary-group-alist (delq entry nndiary-group-alist))
     (push (list group
-               (cons (or (caar files) (1+ last))
+               (cons (or (caar nndiary-files) (1+ last))
                      (max last
-                          (or (caar (last files))
+                          (or (caar (last nndiary-files))
                               0))))
          nndiary-group-alist)))
 
@@ -1223,9 +1100,8 @@ all.  This may very well take some time.")
         (nov (concat dir nndiary-nov-file-name))
         (nov-buffer (get-buffer-create " *nov*"))
         chars file headers)
-    (save-excursion
-      ;; Init the nov buffer.
-      (set-buffer nov-buffer)
+    ;; Init the nov buffer.
+    (with-current-buffer nov-buffer
       (buffer-disable-undo)
       (erase-buffer)
       (set-buffer nntp-server-buffer)
@@ -1245,20 +1121,17 @@ all.  This may very well take some time.")
          (unless (zerop (buffer-size))
            (goto-char (point-min))
            (setq headers (nndiary-parse-head chars (caar files)))
-           (save-excursion
-             (set-buffer nov-buffer)
+           (with-current-buffer nov-buffer
              (goto-char (point-max))
              (nnheader-insert-nov headers)))
          (widen))
        (setq files (cdr files)))
-      (save-excursion
-       (set-buffer nov-buffer)
+      (with-current-buffer nov-buffer
        (nnmail-write-region 1 (point-max) nov nil 'nomesg)
        (kill-buffer (current-buffer))))))
 
 (defun nndiary-nov-delete-article (group article)
-  (save-excursion
-    (set-buffer (nndiary-open-nov group))
+  (with-current-buffer (nndiary-open-nov group)
     (when (nnheader-find-nov-line article)
       (delete-region (point) (progn (forward-line 1) (point)))
       (when (bobp)
@@ -1279,14 +1152,14 @@ all.  This may very well take some time.")
          (nnheader-article-to-file-alist nndiary-current-directory))))
 
 
-(defun nndiary-string-to-int (str min &optional max)
-  ;; Like `string-to-int' but barf if STR is not exactly an integer, and not
+(defun nndiary-string-to-number (str min &optional max)
+  ;; Like `string-to-number' but barf if STR is not exactly an integer, and not
   ;; within the specified bounds.
   ;; Signals are caught by `nndiary-schedule'.
   (if (not (string-match "^[ \t]*[0-9]+[ \t]*$" str))
       (nndiary-error "not an integer value")
     ;; else
-    (let ((val (string-to-int str)))
+    (let ((val (string-to-number str)))
       (and (or (< val min)
               (and max (> val max)))
           (nndiary-error "value out of range"))
@@ -1294,11 +1167,11 @@ all.  This may very well take some time.")
 
 (defun nndiary-parse-schedule-value (str min-or-values max)
   ;; Parse the schedule string STR, or signal an error.
-  ;; Signals are caught by `nndary-schedule'.
+  ;; Signals are caught by `nndiary-schedule'.
   (if (string-match "[ \t]*\\*[ \t]*" str)
-      ;; unspecifyed
+      ;; unspecified
       nil
-    ;; specifyed
+    ;; specified
     (if (listp min-or-values)
        ;; min-or-values is values
        ;; #### NOTE: this is actually only a hack for time zones.
@@ -1313,12 +1186,12 @@ all.  This may very well take some time.")
         (let ((res (split-string val "-")))
           (cond
            ((= (length res) 1)
-            (nndiary-string-to-int (car res) min-or-values max))
+            (nndiary-string-to-number (car res) min-or-values max))
            ((= (length res) 2)
             ;; don't know if crontab accepts this, but ensure
             ;; that BEG is <= END
-            (let ((beg (nndiary-string-to-int (car res) min-or-values max))
-                  (end (nndiary-string-to-int (cadr res) min-or-values max)))
+            (let ((beg (nndiary-string-to-number (car res) min-or-values max))
+                  (end (nndiary-string-to-number (cadr res) min-or-values max)))
               (cond ((< beg end)
                      (cons beg end))
                     ((= beg end)
@@ -1337,7 +1210,7 @@ all.  This may very well take some time.")
   ;; - Returns nil if `*'
   ;; - Otherwise returns a list of integers and/or ranges (BEG . END)
   ;; The exception is the Timze-Zone value which is always of the form (STR).
-  ;; Signals are caught by `nndary-schedule'.
+  ;; Signals are caught by `nndiary-schedule'.
   (let ((header (format "^X-Diary-%s: \\(.*\\)$" head)))
     (goto-char (point-min))
     (if (not (re-search-forward header nil t))
@@ -1441,8 +1314,10 @@ all.  This may very well take some time.")
        res))
     (sort res 'time-less-p)))
 
+;; FIXME: "occurrence" is misspelled in this function name.
+
 (defun nndiary-last-occurence (sched)
-  ;; Returns the last occurence of schedule SCHED as an Emacs time struct, or
+  ;; Returns the last occurrence of schedule SCHED as an Emacs time struct, or
   ;; nil for permanent schedule or errors.
   (let ((minute (nndiary-max (nth 0 sched)))
        (hour (nndiary-max (nth 1 sched)))
@@ -1453,7 +1328,7 @@ all.  This may very well take some time.")
       (or minute (setq minute 59))
       (or hour (setq hour 23))
       ;; I'll just compute all possible values and test them by decreasing
-      ;; order until one succeeds. This is probably quide rude, but I got
+      ;; order until one succeeds. This is probably quite rude, but I got
       ;; bored in finding a good algorithm for doing that ;-)
       ;; ### FIXME: remove identical entries.
       (let ((dom-list (nth 2 sched))
@@ -1513,7 +1388,7 @@ all.  This may very well take some time.")
                            (encode-time 0 minute hour
                                         (car days) month year time-zone)))
                   )))))
-        ;; There's an upper limit, but we didn't find any last occurence.
+        ;; There's an upper limit, but we didn't find any last occurrence.
         ;; This means that the schedule is undecidable. This can happen if
         ;; you happen to say something like "each Feb 31 until 2038".
         (progn
@@ -1521,9 +1396,11 @@ all.  This may very well take some time.")
           nil))
        ))))
 
+;; FIXME: "occurrence" is misspelled in this function name.
+
 (defun nndiary-next-occurence (sched now)
-  ;; Returns the next occurence of schedule SCHED, starting from time NOW.
-  ;; If there's no next occurence, returns the last one (if any) which is then
+  ;; Returns the next occurrence of schedule SCHED, starting from time NOW.
+  ;; If there's no next occurrence, returns the last one (if any) which is then
   ;; in the past.
   (let* ((today (decode-time now))
         (this-minute (nth 1 today))
@@ -1677,12 +1554,12 @@ all.  This may very well take some time.")
        ;; The article should be re-considered as unread if there's a reminder
        ;; between the group timestamp and the current time.
        (when (and sched (setq sched (nndiary-next-occurence sched now)))
-         (let ((reminders ;; add the next occurence itself at the end.
+         (let ((reminders ;; add the next occurrence itself at the end.
                 (append (nndiary-compute-reminders sched) (list sched))))
            (while (and reminders (time-less-p (car reminders) timestamp))
              (pop reminders))
            ;; The reminders might be empty if the last date is in the past,
-           ;; or we've got at least the next occurence itself left. All past
+           ;; or we've got at least the next occurrence itself left. All past
            ;; dates are renewed.
            (or (not reminders)
                (time-less-p (car reminders) now)))
@@ -1693,19 +1570,15 @@ all.  This may very well take some time.")
 
 ;; The end... ===============================================================
 
-(mapcar
- (lambda (elt)
-   (let ((header (intern (format "X-Diary-%s" (car elt)))))
-     ;; Required for building NOV databases and some other stuff
-     (add-to-list 'gnus-extra-headers header)
-     (add-to-list 'nnmail-extra-headers header)))
- nndiary-headers)
+(dolist (header nndiary-headers)
+  (setq header (intern (format "X-Diary-%s" (car header))))
+  ;; Required for building NOV databases and some other stuff.
+  (add-to-list 'gnus-extra-headers header)
+  (add-to-list 'nnmail-extra-headers header))
 
 (unless (assoc "nndiary" gnus-valid-select-methods)
   (gnus-declare-backend "nndiary" 'post-mail 'respool 'address))
 
 (provide 'nndiary)
 
-
-;;; arch-tag: 9c542b95-92e7-4ace-a038-330ab296e203
 ;;; nndiary.el ends here