Better seed support for (random)
[gnus] / lisp / gnus-sum.el
index 17bd7e1..efbcb4d 100644 (file)
@@ -122,6 +122,7 @@ If t, fetch all the available old headers."
   "*Use nnir to search an entire server when referring threads. A
 nil value will only search for thread-related articles in the
 current group."
   "*Use nnir to search an entire server when referring threads. A
 nil value will only search for thread-related articles in the
 current group."
+  :version "24.1"
   :group 'gnus-thread
   :type 'boolean)
 
   :group 'gnus-thread
   :type 'boolean)
 
@@ -450,7 +451,8 @@ current article is unread."
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
-(defcustom gnus-auto-center-summary 2
+(defcustom gnus-auto-center-summary 
+  (max (or (bound-and-true-p scroll-margin) 0) 2)
   "*If non-nil, always center the current summary buffer.
 In particular, if `vertical' do only vertical recentering.  If non-nil
 and non-`vertical', do both horizontal and vertical recentering."
   "*If non-nil, always center the current summary buffer.
 In particular, if `vertical' do only vertical recentering.  If non-nil
 and non-`vertical', do both horizontal and vertical recentering."
@@ -1242,13 +1244,6 @@ For example: ((1 . cn-gb-2312) (2 . big5))."
   :type 'boolean
   :group 'gnus-summary-marks)
 
   :type 'boolean
   :group 'gnus-summary-marks)
 
-(defcustom gnus-propagate-marks nil
-  "If non-nil, Gnus will store and retrieve marks from the backends.
-This means that marks will be stored both in .newsrc.eld and in
-the backend, and will slow operation down somewhat."
-  :type 'boolean
-  :group 'gnus-summary-marks)
-
 (defcustom gnus-alter-articles-to-read-function nil
   "Function to be called to alter the list of articles to be selected."
   :type '(choice (const nil) function)
 (defcustom gnus-alter-articles-to-read-function nil
   "Function to be called to alter the list of articles to be selected."
   :type '(choice (const nil) function)
@@ -1579,6 +1574,7 @@ This list will always be a subset of gnus-newsgroup-undownloaded.")
     gnus-newsgroup-killed
     gnus-newsgroup-unseen
     gnus-newsgroup-seen
     gnus-newsgroup-killed
     gnus-newsgroup-unseen
     gnus-newsgroup-seen
+    gnus-newsgroup-unexist
     gnus-newsgroup-cached
     gnus-newsgroup-downloadable
     gnus-newsgroup-undownloaded
     gnus-newsgroup-cached
     gnus-newsgroup-downloadable
     gnus-newsgroup-undownloaded
@@ -2975,12 +2971,6 @@ When FORCE, rebuild the tool bar."
        (setq gnus-summary-tool-bar-map map))))
   (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map))
 
        (setq gnus-summary-tool-bar-map map))))
   (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map))
 
-(defun gnus-score-set-default (var value)
-  "A version of set that updates the GNU Emacs menu-bar."
-  (set var value)
-  ;; It is the message that forces the active status to be updated.
-  (message ""))
-
 (defun gnus-make-score-map (type)
   "Make a summary score map of type TYPE."
   (if t
 (defun gnus-make-score-map (type)
   "Make a summary score map of type TYPE."
   (if t
@@ -3266,13 +3256,6 @@ The following commands are available:
   "Say whether this article is a sparse article or not."
   `(memq ,article gnus-newsgroup-ancient))
 
   "Say whether this article is a sparse article or not."
   `(memq ,article gnus-newsgroup-ancient))
 
-(defun gnus-article-parent-p (number)
-  "Say whether this article is a parent or not."
-  (let ((data (gnus-data-find-list number)))
-    (and (cdr data)              ; There has to be an article after...
-        (< (gnus-data-level (car data)) ; And it has to have a higher level.
-           (gnus-data-level (nth 1 data))))))
-
 (defun gnus-article-children (number)
   "Return a list of all children to NUMBER."
   (let* ((data (gnus-data-find-list number))
 (defun gnus-article-children (number)
   "Return a list of all children to NUMBER."
   (let* ((data (gnus-data-find-list number))
@@ -3294,14 +3277,6 @@ The following commands are available:
   "Say whether this article is intangible or not."
   '(get-text-property (point) 'gnus-intangible))
 
   "Say whether this article is intangible or not."
   '(get-text-property (point) 'gnus-intangible))
 
-(defun gnus-article-read-p (article)
-  "Say whether ARTICLE is read or not."
-  (not (or (memq article gnus-newsgroup-marked)
-          (memq article gnus-newsgroup-spam-marked)
-          (memq article gnus-newsgroup-unreads)
-          (memq article gnus-newsgroup-unselected)
-          (memq article gnus-newsgroup-dormant))))
-
 ;; Some summary mode macros.
 
 (defmacro gnus-summary-article-number ()
 ;; Some summary mode macros.
 
 (defmacro gnus-summary-article-number ()
@@ -3562,7 +3537,7 @@ buffer that was in action when the last article was fetched."
            (push (eval (car locals)) vlist))
          (setq locals (cdr locals)))
        (setq vlist (nreverse vlist)))
            (push (eval (car locals)) vlist))
          (setq locals (cdr locals)))
        (setq vlist (nreverse vlist)))
-      (with-current-buffer gnus-group-buffer
+      (with-temp-buffer
        (setq gnus-newsgroup-name name
              gnus-newsgroup-marked marked
              gnus-newsgroup-spam-marked spam
        (setq gnus-newsgroup-name name
              gnus-newsgroup-marked marked
              gnus-newsgroup-spam-marked spam
@@ -5677,7 +5652,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
        (setq gnus-newsgroup-unselected
              (gnus-sorted-difference gnus-newsgroup-unreads articles))
       (setq articles (gnus-articles-to-read group read-all)))
        (setq gnus-newsgroup-unselected
              (gnus-sorted-difference gnus-newsgroup-unreads articles))
       (setq articles (gnus-articles-to-read group read-all)))
-    
+
     (cond
      ((null articles)
       ;;(gnus-message 3 "Couldn't select newsgroup -- no articles to display")
     (cond
      ((null articles)
       ;;(gnus-message 3 "Couldn't select newsgroup -- no articles to display")
@@ -5687,7 +5662,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Init the dependencies hash table.
       (setq gnus-newsgroup-dependencies
            (gnus-make-hashtable (length articles)))
       ;; Init the dependencies hash table.
       (setq gnus-newsgroup-dependencies
            (gnus-make-hashtable (length articles)))
-      (gnus-set-global-variables)
+      (if (gnus-buffer-live-p gnus-group-buffer)
+         (gnus-set-global-variables)
+       (set-default 'gnus-newsgroup-name gnus-newsgroup-name))
       ;; Retrieve the headers and read them in.
 
       (setq gnus-newsgroup-headers (gnus-fetch-headers articles))
       ;; Retrieve the headers and read them in.
 
       (setq gnus-newsgroup-headers (gnus-fetch-headers articles))
@@ -5933,17 +5910,6 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (setq articles (cdr articles)))
     out))
 
       (setq articles (cdr articles)))
     out))
 
-(defun gnus-uncompress-marks (marks)
-  "Uncompress the mark ranges in MARKS."
-  (let ((uncompressed '(score bookmark))
-       out)
-    (while marks
-      (if (memq (caar marks) uncompressed)
-         (push (car marks) out)
-       (push (cons (caar marks) (gnus-uncompress-range (cdar marks))) out))
-      (setq marks (cdr marks)))
-    out))
-
 (defun gnus-article-mark-to-type (mark)
   "Return the type of MARK."
   (or (cadr (assq mark gnus-article-special-mark-lists))
 (defun gnus-article-mark-to-type (mark)
   "Return the type of MARK."
   (or (cadr (assq mark gnus-article-special-mark-lists))
@@ -5971,7 +5937,6 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (setq mark (car marks)
            mark-type (gnus-article-mark-to-type mark)
            var (intern (format "gnus-newsgroup-%s" (car (rassq mark types)))))
       (setq mark (car marks)
            mark-type (gnus-article-mark-to-type mark)
            var (intern (format "gnus-newsgroup-%s" (car (rassq mark types)))))
-
       ;; We set the variable according to the type of the marks list,
       ;; and then adjust the marks to a subset of the active articles.
       (cond
       ;; We set the variable according to the type of the marks list,
       ;; and then adjust the marks to a subset of the active articles.
       (cond
@@ -6293,10 +6258,9 @@ The resulting hash table is returned, or nil if no Xrefs were found."
         (info (nth 2 entry))
         (active (gnus-active group))
         (set-marks
         (info (nth 2 entry))
         (active (gnus-active group))
         (set-marks
-         (or gnus-propagate-marks
-             (gnus-method-option-p
-              (gnus-find-method-for-group group)
-              'server-marks)))
+         (gnus-method-option-p
+          (gnus-find-method-for-group group)
+          'server-marks))
         range)
     (if (not entry)
        ;; Group that Gnus doesn't know exists, but still allow the
         range)
     (if (not entry)
        ;; Group that Gnus doesn't know exists, but still allow the
@@ -6633,9 +6597,9 @@ too, instead of trying to fetch new headers."
       ;; article if ID is a number -- so that the next `P' or `N'
       ;; command will fetch the previous (or next) article even
       ;; if the one we tried to fetch this time has been canceled.
       ;; article if ID is a number -- so that the next `P' or `N'
       ;; command will fetch the previous (or next) article even
       ;; if the one we tried to fetch this time has been canceled.
-      (when (> number gnus-newsgroup-end)
+      (unless (and gnus-newsgroup-end (< number gnus-newsgroup-end))
        (setq gnus-newsgroup-end number))
        (setq gnus-newsgroup-end number))
-      (when (< number gnus-newsgroup-begin)
+      (unless (and gnus-newsgroup-begin (> number gnus-newsgroup-begin))
        (setq gnus-newsgroup-begin number))
       (setq gnus-newsgroup-unselected
            (delq number gnus-newsgroup-unselected)))
        (setq gnus-newsgroup-begin number))
       (setq gnus-newsgroup-unselected
            (delq number gnus-newsgroup-unselected)))
@@ -7261,7 +7225,8 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (gnus-summary-update-info))
     (gnus-close-group group)
     ;; Make sure where we were, and go to next newsgroup.
       (gnus-summary-update-info))
     (gnus-close-group group)
     ;; Make sure where we were, and go to next newsgroup.
-    (set-buffer gnus-group-buffer)
+    (when (buffer-live-p (get-buffer gnus-group-buffer))
+      (set-buffer gnus-group-buffer))
     (unless quit-config
       (gnus-group-jump-to-group group))
     (gnus-run-hooks 'gnus-summary-exit-hook)
     (unless quit-config
       (gnus-group-jump-to-group group))
     (gnus-run-hooks 'gnus-summary-exit-hook)
@@ -7286,7 +7251,8 @@ If FORCE (the prefix), also save the .newsrc file(s)."
          (gnus-kill-buffer buf)))
 
       (setq gnus-current-select-method gnus-select-method)
          (gnus-kill-buffer buf)))
 
       (setq gnus-current-select-method gnus-select-method)
-      (set-buffer gnus-group-buffer)
+      (when (gnus-buffer-live-p gnus-group-buffer)
+       (set-buffer gnus-group-buffer))
       (if quit-config
          (gnus-handle-ephemeral-exit quit-config)
        (goto-char group-point)
       (if quit-config
          (gnus-handle-ephemeral-exit quit-config)
        (goto-char group-point)
@@ -7327,6 +7293,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
          (gnus-article-stop-animations)
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
          (gnus-article-stop-animations)
+         (gnus-stop-downloads)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
          (setq gnus-article-mime-handle-alist nil)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
          (setq gnus-article-mime-handle-alist nil)
@@ -7364,7 +7331,8 @@ If FORCE (the prefix), also save the .newsrc file(s)."
   "Handle movement when leaving an ephemeral group.
 The state which existed when entering the ephemeral is reset."
   (if (not (buffer-live-p (car quit-config)))
   "Handle movement when leaving an ephemeral group.
 The state which existed when entering the ephemeral is reset."
   (if (not (buffer-live-p (car quit-config)))
-      (gnus-configure-windows 'group 'force)
+      (when (gnus-buffer-live-p gnus-group-buffer)
+       (gnus-configure-windows 'group 'force))
     (set-buffer (car quit-config))
     (unless (eq (cdr quit-config) 'group)
       (setq gnus-current-select-method
     (set-buffer (car quit-config))
     (unless (eq (cdr quit-config) 'group)
       (setq gnus-current-select-method
@@ -7762,10 +7730,6 @@ be displayed."
                                            gnus-buttonized-mime-types)))
     (gnus-summary-select-article nil 'force)))
 
                                            gnus-buttonized-mime-types)))
     (gnus-summary-select-article nil 'force)))
 
-(defun gnus-summary-set-current-mark (&optional current-mark)
-  "Obsolete function."
-  nil)
-
 (defun gnus-summary-next-article (&optional unread subject backward push)
   "Select the next article.
 If UNREAD, only unread articles are selected.
 (defun gnus-summary-next-article (&optional unread subject backward push)
   "Select the next article.
 If UNREAD, only unread articles are selected.
@@ -8239,9 +8203,17 @@ If NOT-MATCHING, excluding articles that have subjects that match a regexp."
   "Limit the summary buffer to articles that have authors that match a regexp.
 If NOT-MATCHING, excluding articles that have authors that match a regexp."
   (interactive
   "Limit the summary buffer to articles that have authors that match a regexp.
 If NOT-MATCHING, excluding articles that have authors that match a regexp."
   (interactive
-   (list (read-string (if current-prefix-arg
-                         "Exclude author (regexp): "
-                       "Limit to author (regexp): "))
+   (list (let* ((header (gnus-summary-article-header))
+               (default (and header (car (mail-header-parse-address
+                                          (mail-header-from header))))))
+          (read-string (concat (if current-prefix-arg
+                                   "Exclude author (regexp"
+                                 "Limit to author (regexp")
+                               (if default
+                                   (concat ", default \"" default "\"): ")
+                                 "): "))
+                       nil nil
+                       default))
         current-prefix-arg))
   (gnus-summary-limit-to-subject from "from" not-matching))
 
         current-prefix-arg))
   (gnus-summary-limit-to-subject from "from" not-matching))
 
@@ -9173,7 +9145,7 @@ To control what happens when you exit the group, see the
                           (list (cons 'save-article-group ogroup))))
           (case-fold-search t)
           (buf (current-buffer))
                           (list (cons 'save-article-group ogroup))))
           (case-fold-search t)
           (buf (current-buffer))
-          dig to-address)
+          dig to-address charset)
       (with-current-buffer gnus-original-article-buffer
        ;; Have the digest group inherit the main mail address of
        ;; the parent article.
       (with-current-buffer gnus-original-article-buffer
        ;; Have the digest group inherit the main mail address of
        ;; the parent article.
@@ -9186,16 +9158,32 @@ To control what happens when you exit the group, see the
                                      to-address))))))
        (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*"))
        (insert-buffer-substring gnus-original-article-buffer)
                                      to-address))))))
        (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*"))
        (insert-buffer-substring gnus-original-article-buffer)
-       ;; Remove lines that may lead nndoc to misinterpret the
-       ;; document type.
        (narrow-to-region
         (goto-char (point-min))
         (or (search-forward "\n\n" nil t) (point)))
        (narrow-to-region
         (goto-char (point-min))
         (or (search-forward "\n\n" nil t) (point)))
+       ;; Remove lines that may lead nndoc to misinterpret the
+       ;; document type.
        (goto-char (point-min))
        (delete-matching-lines "^Path:\\|^From ")
        (goto-char (point-min))
        (delete-matching-lines "^Path:\\|^From ")
+       ;; Parse charset, and decode content transfer encoding.
+       (setq charset (mail-content-type-get
+                      (mail-header-parse-content-type
+                       (or (gnus-fetch-field "content-type") ""))
+                      'charset))
+       (let ((encoding (gnus-fetch-field "content-transfer-encoding")))
+         (when encoding
+           (message-remove-header "content-transfer-encoding")
+           (goto-char (point-max))
+           (widen)
+           (narrow-to-region (point) (point-max))
+           (mm-decode-content-transfer-encoding
+            (intern (downcase (mail-header-strip encoding))))))
        (widen))
       (unwind-protect
        (widen))
       (unwind-protect
-         (if (let ((gnus-newsgroup-ephemeral-charset gnus-newsgroup-charset)
+         (if (let ((gnus-newsgroup-ephemeral-charset
+                    (if charset
+                        (intern (downcase (gnus-strip-whitespace charset)))
+                      gnus-newsgroup-charset))
                    (gnus-newsgroup-ephemeral-ignored-charsets
                     gnus-newsgroup-ignored-charsets))
                (gnus-group-read-ephemeral-group
                    (gnus-newsgroup-ephemeral-ignored-charsets
                     gnus-newsgroup-ignored-charsets))
                (gnus-group-read-ephemeral-group
@@ -9675,6 +9663,7 @@ C-u g', show the raw article."
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
          (gnus-article-stop-animations)
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
          (gnus-article-stop-animations)
+         (gnus-stop-downloads)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
          (setq gnus-article-mime-handle-alist nil)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
          (setq gnus-article-mime-handle-alist nil)
@@ -10093,10 +10082,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                   to-group 'expire (list to-article) info))
 
                (when (and to-marks
                   to-group 'expire (list to-article) info))
 
                (when (and to-marks
-                          (or gnus-propagate-marks
-                              (gnus-method-option-p
-                               (gnus-find-method-for-group to-group)
-                               'server-marks)))
+                          (gnus-method-option-p
+                           (gnus-find-method-for-group to-group)
+                           'server-marks))
                  (gnus-request-set-mark
                   to-group (list (list (list to-article) 'add to-marks)))))
 
                  (gnus-request-set-mark
                   to-group (list (list (list to-article) 'add to-marks)))))
 
@@ -10310,16 +10298,19 @@ This will be the case if the article has both been mailed and posted."
              'request-expire-articles gnus-newsgroup-name))
     ;; This backend supports expiry.
     (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name))
              'request-expire-articles gnus-newsgroup-name))
     ;; This backend supports expiry.
     (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name))
-          (expirable (if total
-                         (progn
-                           ;; We need to update the info for
-                           ;; this group for `gnus-list-of-read-articles'
-                           ;; to give us the right answer.
-                           (gnus-run-hooks 'gnus-exit-group-hook)
-                           (gnus-summary-update-info)
-                           (gnus-list-of-read-articles gnus-newsgroup-name))
-                       (setq gnus-newsgroup-expirable
-                             (sort gnus-newsgroup-expirable '<))))
+          (expirable
+           (gnus-list-range-difference
+            (if total
+                (progn
+                  ;; We need to update the info for
+                  ;; this group for `gnus-list-of-read-articles'
+                  ;; to give us the right answer.
+                  (gnus-run-hooks 'gnus-exit-group-hook)
+                  (gnus-summary-update-info)
+                  (gnus-list-of-read-articles gnus-newsgroup-name))
+              (setq gnus-newsgroup-expirable
+                    (sort gnus-newsgroup-expirable '<)))
+            gnus-newsgroup-unexist))
           (expiry-wait (if now 'immediate
                          (gnus-group-find-parameter
                           gnus-newsgroup-name 'expiry-wait)))
           (expiry-wait (if now 'immediate
                          (gnus-group-find-parameter
                           gnus-newsgroup-name 'expiry-wait)))
@@ -12431,6 +12422,13 @@ If REVERSE, save parts that do not match TYPE."
                (not (setq header (car (gnus-get-newsgroup-headers nil t)))))
            ()                          ; Malformed head.
          (unless (gnus-summary-article-sparse-p (mail-header-number header))
                (not (setq header (car (gnus-get-newsgroup-headers nil t)))))
            ()                          ; Malformed head.
          (unless (gnus-summary-article-sparse-p (mail-header-number header))
+            (when (and (bound-and-true-p gnus-registry-enabled)
+                       (not (gnus-ephemeral-group-p (car where))))
+              (gnus-registry-handle-action
+               (mail-header-id header) nil
+               (gnus-group-prefixed-name (car where) gnus-override-method)
+               (mail-header-subject header)
+               (mail-header-from header)))
            (when (and (stringp id)
                       (or
                        (not (string= (gnus-group-real-name group)
            (when (and (stringp id)
                       (or
                        (not (string= (gnus-group-real-name group)
@@ -12578,10 +12576,9 @@ UNREAD is a sorted list."
        (save-excursion
          (let (setmarkundo)
            ;; Propagate the read marks to the backend.
        (save-excursion
          (let (setmarkundo)
            ;; Propagate the read marks to the backend.
-           (when (and (or gnus-propagate-marks
-                          (gnus-method-option-p
-                           (gnus-find-method-for-group group)
-                           'server-marks))
+           (when (and (gnus-method-option-p
+                       (gnus-find-method-for-group group)
+                       'server-marks)
                       (gnus-check-backend-function 'request-set-mark group))
              (let ((del (gnus-remove-from-range (gnus-info-read info) read))
                    (add (gnus-remove-from-range read (gnus-info-read info))))
                       (gnus-check-backend-function 'request-set-mark group))
              (let ((del (gnus-remove-from-range (gnus-info-read info) read))
                    (add (gnus-remove-from-range read (gnus-info-read info))))
@@ -12842,7 +12839,9 @@ If ALL is a number, fetch this number of articles."
              ;; Some nntp servers lie about their active range.  When
              ;; this happens, the active range can be in the millions.
              ;; Use a compressed range to avoid creating a huge list.
              ;; Some nntp servers lie about their active range.  When
              ;; this happens, the active range can be in the millions.
              ;; Use a compressed range to avoid creating a huge list.
-             (gnus-range-difference (list gnus-newsgroup-active) old))
+             (gnus-range-difference
+              (gnus-range-difference (list gnus-newsgroup-active) old)
+              gnus-newsgroup-unexist))
        (setq len (gnus-range-length older))
        (cond
         ((null older) nil)
        (setq len (gnus-range-length older))
        (cond
         ((null older) nil)
@@ -12877,9 +12876,8 @@ If ALL is a number, fetch this number of articles."
                        (if initial "max" "default")
                        len)
                       nil nil
                        (if initial "max" "default")
                        len)
                       nil nil
-                      (if initial
-                          (cons (number-to-string initial)
-                                0)))))
+                      (and initial
+                           (number-to-string initial)))))
                (unless (string-match "^[ \t]*$" input)
                  (setq all (string-to-number input))
                  (if (< all len)
                (unless (string-match "^[ \t]*$" input)
                  (setq all (string-to-number input))
                  (if (< all len)