Synch to No Gnus 200402240748.
[elisp/gnus.git-] / lisp / gnus-start.el
index 21bd7b4..7db9bb9 100644 (file)
 (require 'gnus-util)
 (autoload 'message-make-date "message")
 (autoload 'gnus-agent-read-servers-validate "gnus-agent")
+(autoload 'gnus-agent-save-local "gnus-agent")
 (autoload 'gnus-agent-possibly-alter-active "gnus-agent")
+(eval-when-compile
+  (defvar gnus-agent-covered-methods nil)
+  (defvar gnus-agent-file-loading-local nil)
+  (defvar gnus-agent-file-loading-cache nil))
 
 (defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
   "Your `.newsrc' file.
@@ -624,8 +629,7 @@ the first newsgroup."
     ;; We subscribe the group by changing its level to `subscribed'.
     (gnus-group-change-level
      newsgroup gnus-level-default-subscribed
-     gnus-level-killed (gnus-gethash (or next "dummy.group")
-                                    gnus-newsrc-hashtb))
+     gnus-level-killed (gnus-group-entry (or next "dummy.group")))
     (gnus-message 5 "Subscribe newsgroup: %s" newsgroup)
     (run-hook-with-args 'gnus-subscribe-newsgroup-hooks newsgroup)
     t))
@@ -682,6 +686,8 @@ the first newsgroup."
   (setq gnus-list-of-killed-groups nil
        gnus-have-read-active-file nil
         gnus-agent-covered-methods nil
+        gnus-agent-file-loading-local nil
+        gnus-agent-file-loading-cache nil
         gnus-server-method-cache nil
        gnus-newsrc-alist nil
        gnus-newsrc-hashtb nil
@@ -789,11 +795,6 @@ prompt the user for the name of an NNTP server to use."
          (when (or gnus-slave gnus-use-dribble-file)
            (gnus-dribble-read-file))
 
-         ;; Allow using GroupLens predictions.
-         (when gnus-use-grouplens
-           (bbb-login)
-           (add-hook 'gnus-summary-mode-hook 'gnus-grouplens-mode))
-
          ;; Do the actual startup.
          (if gnus-agent
              (gnus-request-create-group "queue" '(nndraft "")))
@@ -813,7 +814,7 @@ prompt the user for the name of an NNTP server to use."
 (defun gnus-start-draft-setup ()
   "Make sure the draft group exists."
   (gnus-request-create-group "drafts" '(nndraft ""))
-  (unless (gnus-gethash "nndraft:drafts" gnus-newsrc-hashtb)
+  (unless (gnus-group-entry "nndraft:drafts")
     (let ((gnus-level-default-subscribed 1))
       (gnus-subscribe-group "nndraft:drafts" nil '(nndraft "")))
     (gnus-group-set-parameter
@@ -1318,16 +1319,16 @@ for new groups, and subscribe the new groups as zombies."
     (when (and (stringp entry)
               oldlevel
               (< oldlevel gnus-level-zombie))
-      (setq entry (gnus-gethash entry gnus-newsrc-hashtb)))
+      (setq entry (gnus-group-entry entry)))
     (if (and (not oldlevel)
             (consp entry))
        (setq oldlevel (gnus-info-level (nth 2 entry)))
       (setq oldlevel (or oldlevel gnus-level-killed)))
     (when (stringp previous)
-      (setq previous (gnus-gethash previous gnus-newsrc-hashtb)))
+      (setq previous (gnus-group-entry previous)))
 
     (if (and (>= oldlevel gnus-level-zombie)
-            (gnus-gethash group gnus-newsrc-hashtb))
+            (gnus-group-entry group))
        ;; We are trying to subscribe a group that is already
        ;; subscribed.
        ()                              ; Do nothing.
@@ -1351,8 +1352,7 @@ for new groups, and subscribe the new groups as zombies."
                   entry)
          (gnus-sethash (car (nth 2 entry)) nil gnus-newsrc-hashtb)
          (when (nth 3 entry)
-           (setcdr (gnus-gethash (car (nth 3 entry))
-                                 gnus-newsrc-hashtb)
+           (setcdr (gnus-group-entry (car (nth 3 entry)))
                    (cdr entry)))
          (setcdr (cdr entry) (cdddr entry)))))
 
@@ -1412,7 +1412,7 @@ for new groups, and subscribe the new groups as zombies."
            (gnus-sethash group (cons num previous)
                          gnus-newsrc-hashtb))
          (when (cdr entry)
-           (setcdr (gnus-gethash (caadr entry) gnus-newsrc-hashtb) entry))
+           (setcdr (gnus-group-entry (caadr entry)) entry))
          (gnus-dribble-enter
           (format
            "(gnus-group-set-info '%S)" info)))))
@@ -1423,7 +1423,7 @@ for new groups, and subscribe the new groups as zombies."
 (defun gnus-kill-newsgroup (newsgroup)
   "Obsolete function.  Kills a newsgroup."
   (gnus-group-change-level
-   (gnus-gethash newsgroup gnus-newsrc-hashtb) gnus-level-killed))
+   (gnus-group-entry newsgroup) gnus-level-killed))
 
 (defun gnus-check-bogus-newsgroups (&optional confirm)
   "Remove bogus newsgroups.
@@ -1451,14 +1451,14 @@ newsgroup."
           (lambda (group)
             ;; Remove all bogus subscribed groups by first killing them, and
             ;; then removing them from the list of killed groups.
-            (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+            (when (setq entry (gnus-group-entry group))
               (gnus-group-change-level entry gnus-level-killed)
               (setq gnus-killed-list (delete group gnus-killed-list))))
           bogus '("group" "groups" "remove"))
        (while (setq group (pop bogus))
          ;; Remove all bogus subscribed groups by first killing them, and
          ;; then removing them from the list of killed groups.
-         (when (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+         (when (setq entry (gnus-group-entry group))
            (gnus-group-change-level entry gnus-level-killed)
            (setq gnus-killed-list (delete group gnus-killed-list)))))
       ;; Then we remove all bogus groups from the list of killed and
@@ -1532,6 +1532,15 @@ newsgroup."
                    (gnus-active group))
               (gnus-active group)
 
+             ;; If a cache is present, we may have to alter the active info.
+             (when gnus-use-cache
+               (inline (gnus-cache-possibly-alter-active
+                        group active)))
+
+             ;; If the agent is enabled, we may have to alter the active info.
+             (when gnus-agent
+               (gnus-agent-possibly-alter-active group active))
+
             (gnus-set-active group active)
             ;; Return the new active info.
             active)))))
@@ -1547,6 +1556,10 @@ newsgroup."
 
     (let* ((range (gnus-info-read info))
           (num 0))
+
+      ;; These checks are present in gnus-activate-group but skipped
+      ;; due to setting dont-check in the preceeding call.
+
       ;; If a cache is present, we may have to alter the active info.
       (when (and gnus-use-cache info)
        (inline (gnus-cache-possibly-alter-active
@@ -1554,8 +1567,7 @@ newsgroup."
 
       ;; If the agent is enabled, we may have to alter the active info.
       (when (and gnus-agent info)
-       (gnus-agent-possibly-alter-active
-        (gnus-info-group info) active))
+       (gnus-agent-possibly-alter-active (gnus-info-group info) active info))
 
       ;; Modify the list of read articles according to what articles
       ;; are available; then tally the unread articles and add the
@@ -1624,8 +1636,8 @@ newsgroup."
        (setq num (max 0 (- (cdr active) num)))))
       ;; Set the number of unread articles.
       (when (and info
-                (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb))
-       (setcar (gnus-gethash (gnus-info-group info) gnus-newsrc-hashtb) num))
+                (gnus-group-entry (gnus-info-group info)))
+       (setcar (gnus-group-entry (gnus-info-group info)) num))
       num)))
 
 ;; Go though `gnus-newsrc-alist' and compare with `gnus-active-hashtb'
@@ -1741,7 +1753,7 @@ newsgroup."
        ;; The group couldn't be reached, so we nix out the number of
        ;; unread articles and stuff.
        (gnus-set-active group nil)
-       (let ((tmp (gnus-gethash group gnus-newsrc-hashtb)))
+       (let ((tmp (gnus-group-entry group)))
          (when tmp
            (setcar tmp t))))))
 
@@ -1766,7 +1778,7 @@ newsgroup."
              ;; The group couldn't be reached, so we nix out the number of
              ;; unread articles and stuff.
              (gnus-set-active group nil)
-             (setcar (gnus-gethash group gnus-newsrc-hashtb) t)))))))
+             (setcar (gnus-group-entry group) t)))))))
 
     (gnus-message 6 "Checking new news...done")))
 
@@ -1818,9 +1830,9 @@ newsgroup."
 
 (defun gnus-make-articles-unread (group articles)
   "Mark ARTICLES in GROUP as unread."
-  (let* ((info (nth 2 (or (gnus-gethash group gnus-newsrc-hashtb)
-                         (gnus-gethash (gnus-group-real-name group)
-                                       gnus-newsrc-hashtb))))
+  (let* ((info (nth 2 (or (gnus-group-entry group)
+                         (gnus-group-entry
+                          (gnus-group-real-name group)))))
         (ranges (gnus-info-read info))
         news article)
     (while articles
@@ -1840,9 +1852,8 @@ newsgroup."
 
 (defun gnus-make-ascending-articles-unread (group articles)
   "Mark ascending ARTICLES in GROUP as unread."
-  (let* ((entry (or (gnus-gethash group gnus-newsrc-hashtb)
-                    (gnus-gethash (gnus-group-real-name group)
-                                  gnus-newsrc-hashtb)))
+  (let* ((entry (or (gnus-group-entry group)
+                    (gnus-group-entry (gnus-group-real-name group))))
          (info (nth 2 entry))
         (ranges (gnus-info-read info))
          (r ranges)
@@ -2148,7 +2159,7 @@ newsgroup."
             (gnus-online method)
             (gnus-agent-method-p method))
        (progn
-         (gnus-agent-save-groups method)
+         (gnus-agent-save-active method)
          (gnus-active-to-gnus-format method hashtb nil real-active))
 
       (goto-char (point-min))
@@ -2217,6 +2228,85 @@ If FORCE is non-nil, the .newsrc file is read."
          (kill-buffer (current-buffer))
          (gnus-message 5 "Reading %s...done" newsrc-file))))))
 
+(quote (;; T-gnus doesn't provide those functions.
+(defun gnus-convert-old-newsrc ()
+  "Convert old newsrc formats into the current format, if needed."
+  (let ((fcv (and gnus-newsrc-file-version
+                 (gnus-continuum-version gnus-newsrc-file-version))))
+    (when fcv
+      ;; A .newsrc.eld file was loaded.
+      (let ((converters
+             (sort
+              (mapcar (lambda (date-func)
+                        (cons (gnus-continuum-version (car date-func))
+                              date-func))
+                      ;; This is a list of converters that must be run
+                      ;; to bring the newsrc file up to the current
+                      ;; version.  If you create an incompatibility
+                      ;; with older versions, you should create an
+                      ;; entry here.  The entry should consist of the
+                      ;; current gnus version (hardcoded so that it
+                      ;; doesn't change with each release) and the
+                      ;; function that must be applied to convert the
+                      ;; previous version into the current version.
+                      '(("September Gnus v0.1" nil gnus-convert-old-ticks)))
+              #'car-less-than-car)))
+        ;; Skip converters older than the file version
+        (while (and converters (>= fcv (caar converters)))
+          (pop converters))
+
+        ;; Perform converters to bring older version up to date.
+        (when (and converters 
+                   (< fcv (caar converters)))
+          (while (let (c
+                       (cursor-in-echo-area t)
+                       (echo-keystrokes 0))
+                   (message "Convert newsrc from version '%s' to '%s'? (n/y/?)"
+                            gnus-newsrc-file-version gnus-version)
+                   (setq c (read-char-exclusive))
+
+                   (cond ((or (eq c ?n) (eq c ?N))
+                          (error "Can not start gnus using old (unconverted) newsrc"))
+                         ((or (eq c ?y) (eq c ?Y))
+                          nil)
+                         ((eq c ?\?)
+                          (message "This conversion is irreversible. \
+ You should backup your files before proceeding.")
+                          (sit-for 5)
+                          t)
+                         (t
+                          (gnus-message 3 "Ignoring unexpected input")
+                          (sit-for 3)
+                          t))))
+          (while (and converters (< fcv (caar converters)))
+            (let* ((converter  (pop converters))
+                   (convert-to (nth 1 converter))
+                   (load-from  (nth 2 converter))
+                   (func       (nth 3 converter)))
+              (when (and load-from
+                         (not (fboundp func)))
+                (load load-from t))
+              (funcall func convert-to)))
+          (gnus-dribble-enter 
+           (format ";Converted newsrc from version '%s' to '%s'? (n/y/?)"
+                   gnus-newsrc-file-version gnus-version)))))))
+
+(defun gnus-convert-old-ticks (converting-to)
+  (let ((newsrc (cdr gnus-newsrc-alist))
+       marks info dormant ticked)
+    (while (setq info (pop newsrc))
+      (when (setq marks (gnus-info-marks info))
+       (setq dormant (cdr (assq 'dormant marks))
+             ticked (cdr (assq 'tick marks)))
+       (when (or dormant ticked)
+         (gnus-info-set-read
+          info
+          (gnus-add-to-range
+           (gnus-info-read info)
+           (nconc (gnus-uncompress-range dormant)
+                  (gnus-uncompress-range ticked)))))))))
+))
+
 (defun gnus-load (file &optional coding-system)
   "Load FILE, but in such a way that read errors can be reported."
   (with-temp-buffer
@@ -2446,7 +2536,7 @@ If FORCE is non-nil, the .newsrc file is read."
                       (point-at-bol)
                       ;; Options may continue on the next line.
                       (or (and (re-search-forward "^[^ \t]" nil 'move)
-                               (progn (beginning-of-line) (point)))
+                               (point-at-bol))
                           (point)))))
        (forward-line -1))
        (symbol
@@ -2659,6 +2749,10 @@ If FORCE is non-nil, the .newsrc file is read."
   ;; from the variable gnus-newsrc-alist.
   (when (and (or gnus-newsrc-alist gnus-killed-list)
             gnus-current-startup-file)
+    ;; Save agent range limits for the currently active method.
+    (when gnus-agent
+      (gnus-agent-save-local force))
+
     (save-excursion
       (if (and (or gnus-use-dribble-file gnus-slave)
               (not force)
@@ -2676,6 +2770,7 @@ If FORCE is non-nil, the .newsrc file is read."
            (gnus-message 8 "Saving %s..." gnus-current-startup-file)
            (gnus-gnus-to-newsrc-format)
            (gnus-message 8 "Saving %s...done" gnus-current-startup-file))
+
          ;; Save .newsrc.eld.
          (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*"))
          (make-local-variable 'version-control)