* gnus.el: Don't test for `mm-guess-mime-charset'.
[gnus] / lisp / gnus-sum.el
index 46f3839..56f6188 100644 (file)
@@ -26,7 +26,9 @@
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile
+  (require 'cl)
+  (defvar tool-bar-map))
 
 (require 'gnus)
 (require 'gnus-group)
@@ -321,13 +323,13 @@ place point on some subject line."
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
 If the value is t and the next newsgroup is empty, Gnus will exit
-summary mode and go back to group mode.         If the value is neither nil
-nor t, Gnus will select the following unread newsgroup.         In
+summary mode and go back to group mode.  If the value is neither nil
+nor t, Gnus will select the following unread newsgroup.  In
 particular, if the value is the symbol `quietly', the next unread
 newsgroup will be selected without any confirmation, and if it is
 `almost-quietly', the next group will be selected without any
 confirmation if you are located on the last article in the group.
-Finally, if this variable is `slightly-quietly', the `Z n' command
+Finally, if this variable is `slightly-quietly', the `\\<gnus-summary-mode-map>\\[gnus-summary-catchup-and-goto-next-group]' command
 will go to the next group without confirmation."
   :group 'gnus-summary-maneuvering
   :type '(choice (const :tag "off" nil)
@@ -343,6 +345,23 @@ the first unread article."
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
+(defcustom gnus-auto-goto-ignores 'unfetched
+  "*Says how to handle unfetched articles when maneuvering.
+
+This variable can either be the symbols `nil' (maneuver to any
+article), `undownloaded' (maneuvering while unplugged ignores articles
+that have not been fetched), `always-undownloaded' (maneuvering always
+ignores articles that have not been fetched), `unfetched' (maneuvering
+ignores articles whose headers have not been fetched).
+
+NOTE: The list of unfetched articles will always be nil when plugged
+and, when unplugged, a subset of the undownloaded article list."
+  :group 'gnus-summary-maneuvering
+  :type '(choice (const :tag "None" nil)
+                 (const :tag "Undownloaded when unplugged" undownloaded)
+                 (const :tag "Undownloaded" always-undownloaded)
+                 (const :tag "Unfetched" unfetched)))
+
 (defcustom gnus-summary-check-current nil
   "*If non-nil, consider the current article when moving.
 The \"unread\" movement commands will stay on the same line if the
@@ -1034,9 +1053,10 @@ For example: ((1 . cn-gb-2312) (2 . big5))."
                 integer))
 
 (defcustom gnus-summary-save-parts-default-mime "image/.*"
-  "*A regexp to match MIME parts when saving multiple parts of a message
-with gnus-summary-save-parts (X m). This regexp will be used by default
-when prompting the user for which type of files to save."
+  "*A regexp to match MIME parts when saving multiple parts of a
+message with `gnus-summary-save-parts' (\\<gnus-summary-mode-map>\\[gnus-summary-save-parts]).
+This regexp will be used by default when prompting the user for which
+type of files to save."
   :group 'gnus-summary
   :type 'regexp)
 
@@ -1062,7 +1082,7 @@ Set it to non-nil, Gnus will treat some articles as MIME even if
 the MIME-Version header is missed."
   :version "21.3"
   :type 'boolean
-  :group 'gnus-article)
+  :group 'gnus-article-mime)
 
 (defcustom gnus-article-emulate-mime t
   "If non-nil, use MIME emulation for uuencode and the like.
@@ -1070,7 +1090,7 @@ This means that Gnus will search message bodies for text that look
 like uuencoded bits, yEncoded bits, and so on, and present that using
 the normal Gnus MIME machinery."
   :type 'boolean
-  :group 'gnus-article)
+  :group 'gnus-article-mime)
 
 ;;; Internal variables
 
@@ -1253,10 +1273,13 @@ the type of the variable (string, integer, character, etc).")
   "Sorted list of articles in the current newsgroup that can be processed.")
 
 (defvar gnus-newsgroup-unfetched nil
-  "Sorted list of articles in the current newsgroup whose headers have not been fetched into the agent.")
+  "Sorted list of articles in the current newsgroup whose headers have
+not been fetched into the agent.
+
+This list will always be a subset of gnus-newsgroup-undownloaded.")
 
 (defvar gnus-newsgroup-undownloaded nil
-  "List of articles in the current newsgroup that haven't been downloaded..")
+  "List of articles in the current newsgroup that haven't been downloaded.")
 
 (defvar gnus-newsgroup-unsendable nil
   "List of articles in the current newsgroup that won't be sent.")
@@ -1304,7 +1327,7 @@ the type of the variable (string, integer, character, etc).")
 
 (defvar gnus-article-before-search nil)
 
-(defconst gnus-summary-local-variables
+(defvar gnus-summary-local-variables
   '(gnus-newsgroup-name
     gnus-newsgroup-begin gnus-newsgroup-end
     gnus-newsgroup-last-rmail gnus-newsgroup-last-mail
@@ -1361,9 +1384,18 @@ buffers. For example:
 ")
 
 ;; Byte-compiler warning.
-;(eval-when-compile (defvar gnus-article-mode-map))
 (eval-when-compile
+  ;; Bind features so that require will believe that gnus-sum has
+  ;; already been loaded (avoids infinite recursion)
   (let ((features (cons 'gnus-sum features)))
+    ;; Several of the declarations in gnus-sum are needed to load the
+    ;; following files. Right now, these definitions have been
+    ;; compiled but not defined (evaluated).  We could either do a
+    ;; eval-and-compile about all of the declarations or evaluate the
+    ;; source file.
+    (if (boundp 'gnus-newsgroup-variables)
+        nil
+      (load "gnus-sum.el" t t t))
     (require 'gnus)
     (require 'gnus-agent)
     (require 'gnus-art)))
@@ -1505,7 +1537,7 @@ See `gnus-simplify-buffer-fuzzy' for details."
       (buffer-string))))
 
 (defsubst gnus-simplify-subject-fully (subject)
-  "Simplify a subject string according to gnus-summary-gather-subject-limit."
+  "Simplify a subject string according to `gnus-summary-gather-subject-limit'."
   (cond
    (gnus-simplify-subject-functions
     (gnus-map-function gnus-simplify-subject-functions subject))
@@ -1521,7 +1553,7 @@ See `gnus-simplify-buffer-fuzzy' for details."
 
 (defsubst gnus-subject-equal (s1 s2 &optional simple-first)
   "Check whether two subjects are equal.
-If optional argument simple-first is t, first argument is already
+If optional argument SIMPLE-FIRST is t, first argument is already
 simplified."
   (cond
    ((null simple-first)
@@ -2065,14 +2097,20 @@ increase the score of each group you read."
              ["View MIME buttons" gnus-summary-display-buttonized t]
              ["View all" gnus-mime-view-all-parts t]
              ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
-             ["Encrypt body" gnus-article-encrypt-body t]
+             ["Encrypt body" gnus-article-encrypt-body
+              :active (not (gnus-group-read-only-p))
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "Encrypt the message body on disk"))]
              ["Extract all parts" gnus-summary-save-parts t]
              ("Multipart"
               ["Repair multipart" gnus-summary-repair-multipart t]
               ["Add buttons" gnus-summary-display-buttonized t]
               ["Pipe part" gnus-article-pipe-part t]
               ["Inline part" gnus-article-inline-part t]
-              ["Encrypt body" gnus-article-encrypt-body t]
+              ["Encrypt body" gnus-article-encrypt-body
+               :active (not (gnus-group-read-only-p))
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "Encrypt the message body on disk"))]
               ["View part externally" gnus-article-view-part-externally t]
               ["View part with charset" gnus-article-view-part-as-charset t]
               ["Copy part" gnus-article-copy-part t]
@@ -2096,9 +2134,9 @@ increase the score of each group you read."
               ,@(gnus-summary-menu-split
                  (mapcar
                   (lambda (cs)
-                    ;; Since easymenu under FSF Emacs doesn't allow lambda
-                    ;; forms for menu commands, we should provide intern'ed
-                    ;; function symbols.
+                    ;; Since easymenu under Emacs doesn't allow
+                    ;; lambda forms for menu commands, we should
+                    ;; provide intern'ed function symbols.
                     (let ((command (intern (format "\
 gnus-summary-show-article-from-menu-as-charset-%s" cs))))
                       (fset command
@@ -2180,8 +2218,12 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
              ["Crosspost article..." gnus-summary-crosspost-article
               (gnus-check-backend-function
                'request-replace-article gnus-newsgroup-name)]
-             ["Import file..." gnus-summary-import-article t]
-             ["Create article..." gnus-summary-create-article t]
+             ["Import file..." gnus-summary-import-article
+              (gnus-check-backend-function
+               'request-accept-article gnus-newsgroup-name)]
+             ["Create article..." gnus-summary-create-article
+              (gnus-check-backend-function
+               'request-accept-article gnus-newsgroup-name)]
              ["Check if posted" gnus-summary-article-posted-p t]
              ["Edit article" gnus-summary-edit-article
               (not (gnus-group-read-only-p))]
@@ -2636,7 +2678,7 @@ The following commands are available:
   (make-local-variable 'gnus-summary-dummy-line-format)
   (make-local-variable 'gnus-summary-dummy-line-format-spec)
   (make-local-variable 'gnus-summary-mark-positions)
-  (make-local-hook 'pre-command-hook)
+  (gnus-make-local-hook 'pre-command-hook)
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
   (gnus-run-hooks 'gnus-summary-mode-hook)
   (turn-on-gnus-mailing-list-mode)
@@ -3035,10 +3077,6 @@ display only a single character."
                                               (point)
                                               (current-buffer))))))
 
-(defun gnus-summary-buffer-name (group)
-  "Return the summary buffer name of GROUP."
-  (concat "*Summary " (gnus-group-decoded-name group) "*"))
-
 (defun gnus-summary-setup-buffer (group)
   "Initialize summary buffer."
   (let ((buffer (gnus-summary-buffer-name group))
@@ -3351,7 +3389,7 @@ the thread are to be displayed."
 (defsubst gnus-summary-line-message-size (head)
   "Return pretty-printed version of message size.
 This function is intended to be used in
-`gnus-summary-line-format-alist', which see."
+`gnus-summary-line-format-alist'."
   (let ((c (or (mail-header-chars head) -1)))
     (cond ((< c 0) "n/a")              ; chars not available
          ((< c (* 1000 10)) (format "%1.1fk" (/ c 1024.0)))
@@ -3578,7 +3616,7 @@ If NO-DISPLAY, don't generate a summary buffer."
    ((eq gnus-auto-select-subject 'first)
     ;; Do nothing.
     )
-   ((gnus-functionp gnus-auto-select-subject)
+   ((functionp gnus-auto-select-subject)
     (funcall gnus-auto-select-subject))))
 
 (defun gnus-summary-prepare ()
@@ -4529,6 +4567,11 @@ Unscored articles will be counted as having a score of zero."
 If nil, use subject instead."
   :type 'string
   :group 'gnus-thread)
+(defcustom gnus-sum-thread-tree-false-root "> "
+  "With %B spec, used for a false root of a thread.
+If nil, use subject instead."
+  :type 'string
+  :group 'gnus-thread)
 (defcustom gnus-sum-thread-tree-single-indent ""
   "With %B spec, used for a thread with just one message.
 If nil, use subject instead."
@@ -4793,13 +4836,18 @@ or a straight list of headers."
               (substring gnus-tmp-from
                          (1+ (match-beginning 0)) (1- (match-end 0))))
              (t gnus-tmp-from))
+
+            ;; Do the %B string
             gnus-tmp-thread-tree-header-string
             (cond
              ((not gnus-show-threads) "")
              ((zerop gnus-tmp-level)
-              (if (cdar thread)
-                  (or gnus-sum-thread-tree-root subject)
-                (or gnus-sum-thread-tree-single-indent subject)))
+              (cond ((cdar thread)
+                     (or gnus-sum-thread-tree-root subject))
+                    (gnus-tmp-new-adopts
+                     (or gnus-sum-thread-tree-false-root subject))
+                    (t
+                     (or gnus-sum-thread-tree-single-indent subject))))
              (t
               (concat (apply 'concat
                              (mapcar (lambda (item)
@@ -4830,7 +4878,7 @@ or a straight list of headers."
 
        (when (nth 1 thread)
          (push (list (max 0 gnus-tmp-level)
-                     (copy-list tree-stack)
+                     (copy-sequence tree-stack)
                      (nthcdr 1 thread))
                stack))
        (push (if (nth 1 thread) 1 0) tree-stack)
@@ -4966,6 +5014,18 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (error "Couldn't request group %s: %s"
             group (gnus-status-message group)))
 
+    (when gnus-agent
+      ;; The agent may be storing articles that are no longer in the
+      ;; server's active range.  If that is the case, the active range
+      ;; needs to be expanded such that the agent's articles can be
+      ;; included in the summary.
+      (let* ((gnus-command-method (gnus-find-method-for-group group))
+             (alist (gnus-agent-load-alist group))
+             (active (gnus-active group)))
+        (if (and (car alist)
+                 (< (caar alist) (car active)))
+            (gnus-set-active group (cons (caar alist) (cdr active))))))
+
     (setq gnus-newsgroup-name group
          gnus-newsgroup-unselected nil
          gnus-newsgroup-unreads (gnus-list-of-unread-articles group))
@@ -5865,8 +5925,7 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
                           (looking-at "Xref:"))
                      (search-forward "\nXref:" nil t))
              (goto-char (1+ (match-end 0)))
-             (setq xref (buffer-substring (point)
-                                          (progn (end-of-line) (point))))
+             (setq xref (buffer-substring (point) (gnus-point-at-eol)))
              (mail-header-set-xref headers xref)))))))
 
 (defun gnus-summary-insert-subject (id &optional old-header use-old-header)
@@ -6029,7 +6088,7 @@ If EXCLUDE-GROUP, do not go to this group."
       (gnus-group-best-unread-group exclude-group))))
 
 (defun gnus-summary-find-next (&optional unread article backward)
-  (if backward (gnus-summary-find-prev)
+  (if backward (gnus-summary-find-prev unread article)
     (let* ((dummy (gnus-summary-article-intangible-p))
           (article (or article (gnus-summary-article-number)))
           (data (gnus-data-find-list article))
@@ -6044,7 +6103,14 @@ If EXCLUDE-GROUP, do not go to this group."
                      (progn
                        (while data
                           (unless (memq (gnus-data-number (car data)) 
-                                        gnus-newsgroup-unfetched)
+                                        (cond ((eq gnus-auto-goto-ignores 'always-undownloaded)
+                                               gnus-newsgroup-undownloaded)
+                                              (gnus-plugged
+                                               nil)
+                                              ((eq gnus-auto-goto-ignores 'unfetched)
+                                               gnus-newsgroup-unfetched)
+                                              ((eq gnus-auto-goto-ignores 'undownloaded)
+                                               gnus-newsgroup-undownloaded)))
                             (when (gnus-data-unread-p (car data))
                               (setq result (car data)
                                     data nil)))
@@ -6068,7 +6134,15 @@ If EXCLUDE-GROUP, do not go to this group."
                (if unread
                    (progn
                      (while data
-                        (unless (memq (gnus-data-number (car data)) gnus-newsgroup-unfetched)
+                        (unless (memq (gnus-data-number (car data))
+                                      (cond ((eq gnus-auto-goto-ignores 'always-undownloaded)
+                                             gnus-newsgroup-undownloaded)
+                                            (gnus-plugged
+                                             nil)
+                                            ((eq gnus-auto-goto-ignores 'unfetched)
+                                             gnus-newsgroup-unfetched)
+                                            ((eq gnus-auto-goto-ignores 'undownloaded)
+                                             gnus-newsgroup-undownloaded)))
                           (when (gnus-data-unread-p (car data))
                             (setq result (car data)
                                   data nil)))
@@ -6277,17 +6351,19 @@ With arg, turn line truncation on if arg is positive."
          (> (prefix-numeric-value arg) 0)))
   (redraw-display))
 
-(defun gnus-summary-find-uncancelled ()
-  "Return the number of an uncancelled article.
+(defun gnus-summary-find-for-reselect ()
+  "Return the number of an article to stay on across a reselect.
 The current article is considered, then following articles, then previous
-articles.  If all articles are cancelled then return a dummy 0."
+articles.  An article is sought which is not cancelled and isn't a temporary
+insertion from another group.  If there's no such then return a dummy 0."
   (let (found)
     (dolist (rev '(nil t))
       (unless found      ; don't demand the reverse list if we don't need it
         (let ((data (gnus-data-find-list
                      (gnus-summary-article-number) (gnus-data-list rev))))
           (while (and data (not found))
-            (if (not (eq gnus-canceled-mark (gnus-data-mark (car data))))
+            (if (and (< 0 (gnus-data-number (car data)))
+                     (not (eq gnus-canceled-mark (gnus-data-mark (car data)))))
                 (setq found (gnus-data-number (car data))))
             (setq data (cdr data))))))
     (or found 0)))
@@ -6298,7 +6374,7 @@ The prefix argument ALL means to select all articles."
   (interactive "P")
   (when (gnus-ephemeral-group-p gnus-newsgroup-name)
     (error "Ephemeral groups can't be reselected"))
-  (let ((current-subject (gnus-summary-find-uncancelled))
+  (let ((current-subject (gnus-summary-find-for-reselect))
        (group gnus-newsgroup-name))
     (setq gnus-newsgroup-begin nil)
     (gnus-summary-exit)
@@ -6470,14 +6546,13 @@ If FORCE (the prefix), also save the .newsrc file(s)."
   (interactive)
   (let* ((group gnus-newsgroup-name)
         (gnus-group-is-exiting-p t)
+        (gnus-group-is-exiting-without-update-p t)
         (quit-config (gnus-group-quit-config group)))
     (when (or no-questions
              gnus-expert-user
              (gnus-y-or-n-p "Discard changes to this group and exit? "))
       (gnus-async-halt-prefetch)
-      (mapcar 'funcall
-             (delq 'gnus-summary-expire-articles
-                   (copy-sequence gnus-summary-prepare-exit-hook)))
+      (run-hooks 'gnus-summary-prepare-exit-hook)
       (when (gnus-buffer-live-p gnus-article-buffer)
        (save-excursion
          (set-buffer gnus-article-buffer)
@@ -6500,8 +6575,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
        (gnus-summary-clear-local-variables)
        (let ((gnus-summary-local-variables gnus-newsgroup-variables))
          (gnus-summary-clear-local-variables))
-       (when (get-buffer gnus-summary-buffer)
-         (kill-buffer gnus-summary-buffer)))
+       (gnus-kill-buffer gnus-summary-buffer))
       (unless gnus-single-article-buffer
        (setq gnus-article-current nil))
       (when gnus-use-trees
@@ -6679,6 +6753,11 @@ previous group instead."
   (let ((current-group gnus-newsgroup-name)
        (current-buffer (current-buffer))
        entered)
+    ;; First we semi-exit this group to update Xrefs and all variables.
+    ;; We can't do a real exit, because the window conf must remain
+    ;; the same in case the user is prompted for info, and we don't
+    ;; want the window conf to change before that...
+    (gnus-summary-exit t)
     (while (not entered)
       ;; Then we find what group we are supposed to enter.
       (set-buffer gnus-group-buffer)
@@ -6703,20 +6782,10 @@ previous group instead."
        (let ((unreads (gnus-group-group-unread)))
          (if (and (or (eq t unreads)
                       (and unreads (not (zerop unreads))))
-                  (progn
-                    ;; Now we semi-exit this group to update Xrefs
-                    ;; and all variables.  We can't do a real exit,
-                    ;; because the window conf must remain the same
-                    ;; in case the user is prompted for info, and we
-                    ;; don't want the window conf to change before
-                    ;; that...
-                    (when (gnus-buffer-live-p current-buffer)
-                      (set-buffer current-buffer)
-                      (gnus-summary-exit t))
-                    (gnus-summary-read-group
-                     target-group nil no-article
-                     (and (buffer-name current-buffer) current-buffer)
-                     nil backward)))
+                  (gnus-summary-read-group
+                   target-group nil no-article
+                   (and (buffer-name current-buffer) current-buffer)
+                   nil backward))
              (setq entered t)
            (setq current-group target-group
                  target-group nil)))))))
@@ -8024,9 +8093,10 @@ of what's specified by the `gnus-refer-thread-limit' variable."
        ;; We fetch the article.
        (catch 'found
          (dolist (gnus-override-method (gnus-refer-article-methods))
-           (gnus-check-server gnus-override-method)
-           ;; Fetch the header, and display the article.
-           (when (setq number (gnus-summary-insert-subject message-id))
+           (when (and (gnus-check-server gnus-override-method)
+                      ;; Fetch the header,
+                      (setq number (gnus-summary-insert-subject message-id)))
+             ;; and display the article.
              (gnus-summary-select-article nil nil nil number)
              (throw 'found t)))
          (gnus-message 3 "Couldn't fetch article %s" message-id)))))))
@@ -8471,8 +8541,8 @@ If ARG (the prefix) is a number, show the article with the charset
 defined in `gnus-summary-show-article-charset-alist', or the charset
 input.
 If ARG (the prefix) is non-nil and not a number, show the raw article
-without any article massaging functions being run.  Normally, the key strokes
-are `C-u g'."
+without any article massaging functions being run.  Normally, the key
+strokes are `C-u g'."
   (interactive "P")
   (cond
    ((numberp arg)
@@ -8580,7 +8650,7 @@ If ARG is a negative number, hide the unwanted header lines."
                      (1- (point))
                    (point-max))))
        (insert-buffer-substring gnus-original-article-buffer s e)
-       (article-decode-encoded-words)
+       (run-hooks 'gnus-article-decode-hook)
        (if hidden
            (let ((gnus-treat-hide-headers nil)
                  (gnus-treat-hide-boring-headers nil))
@@ -8794,14 +8864,15 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                      (nnheader-get-report (car to-method))))
        ((eq art-group 'junk)
        (when (eq action 'move)
-         (let ((id (mail-header-id (gnus-data-header 
-                                    (assoc article (gnus-data-list nil))))))
-           (gnus-summary-mark-article article gnus-canceled-mark)
-           (gnus-message 4 "Deleted article %s" article)
-           ;; run the move/copy/crosspost/respool hook
-           (run-hook-with-args 'gnus-summary-article-delete-hook 
-                               action id gnus-newsgroup-name nil
-                               select-method))))
+         (gnus-summary-mark-article article gnus-canceled-mark)
+         (gnus-message 4 "Deleted article %s" article)
+         ;; run the delete hook
+         (run-hook-with-args 'gnus-summary-article-delete-hook
+                             action
+                             (gnus-data-header
+                              (assoc article (gnus-data-list nil)))
+                             gnus-newsgroup-name nil
+                             select-method)))
        (t
        (let* ((pto-group (gnus-group-prefixed-name
                           (car art-group) to-method))
@@ -8882,15 +8953,17 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
               article gnus-newsgroup-name (current-buffer))))
 
          ;; run the move/copy/crosspost/respool hook
-         (let ((id (mail-header-id (gnus-data-header 
-                                  (assoc article (gnus-data-list nil))))))
          (run-hook-with-args 'gnus-summary-article-move-hook 
-                             action id gnus-newsgroup-name to-newsgroup
-                             select-method)))
+                             action
+                             (gnus-data-header 
+                              (assoc article (gnus-data-list nil)))
+                             gnus-newsgroup-name
+                             to-newsgroup
+                             select-method))
 
        ;;;!!!Why is this necessary?
        (set-buffer gnus-summary-buffer)
-
+       
        (gnus-summary-goto-subject article)
        (when (eq action 'move)
          (gnus-summary-mark-article article gnus-canceled-mark))))
@@ -8928,7 +9001,7 @@ If nil, use to the current newsgroup method."
   :group 'gnus-summary-mail)
 
 (defcustom gnus-summary-display-while-building nil
-  "If not-nil, show and update the summary buffer as it's being built.
+  "If non-nil, show and update the summary buffer as it's being built.
 If the value is t, update the buffer after every line is inserted.  If
 the value is an integer (N), update the display every N lines."
   :group 'gnus-thread
@@ -9062,8 +9135,9 @@ This will be the case if the article has both been mailed and posted."
 (defun gnus-summary-expire-articles (&optional now)
   "Expire all articles that are marked as expirable in the current group."
   (interactive)
-  (when (gnus-check-backend-function
-        'request-expire-articles gnus-newsgroup-name)
+  (when (and (not gnus-group-is-exiting-without-update-p)
+            (gnus-check-backend-function
+             'request-expire-articles gnus-newsgroup-name))
     ;; This backend supports expiry.
     (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name))
           (expirable (if total
@@ -9108,12 +9182,13 @@ This will be the case if the article has both been mailed and posted."
                (when (and (not (memq article es))
                           (gnus-data-find article))
                  (gnus-summary-mark-article article gnus-canceled-mark)
-                 (let ((id (mail-header-id (gnus-data-header 
-                                            (assoc article 
-                                                   (gnus-data-list nil))))))
-                   (run-hook-with-args 'gnus-summary-article-expire-hook
-                                       'delete id gnus-newsgroup-name nil
-                                       nil)))))))
+                 (run-hook-with-args 'gnus-summary-article-expire-hook
+                                     'delete
+                                     (gnus-data-header
+                                      (assoc article (gnus-data-list nil)))
+                                     gnus-newsgroup-name
+                                     nil
+                                     nil))))))
        (gnus-message 6 "Expiring articles...done")))))
 
 (defun gnus-summary-expire-articles-now ()
@@ -9133,9 +9208,13 @@ deleted forever, right now."
 This command actually deletes articles.         This is not a marking
 command.  The article will disappear forever from your life, never to
 return.
+
 If N is negative, delete backwards.
 If N is nil and articles have been marked with the process mark,
-delete these instead."
+delete these instead.
+
+If `gnus-novice-user' is non-nil you will be asked for
+confirmation before the articles are deleted."
   (interactive "P")
   (unless (gnus-check-backend-function 'request-expire-articles
                                       gnus-newsgroup-name)
@@ -9231,7 +9310,7 @@ groups."
                (let ((mbl1 mml-buffer-list))
                  (setq mml-buffer-list mbl)
                  (set (make-local-variable 'mml-buffer-list) mbl1))
-               (make-local-hook 'kill-buffer-hook)
+               (gnus-make-local-hook 'kill-buffer-hook)
                (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))))
         `(lambda (no-highlight)
            (let ((mail-parse-charset ',gnus-newsgroup-charset)
@@ -9777,7 +9856,7 @@ If NO-EXPIRE, auto-expiry will be inhibited."
   t)
 
 (defun gnus-summary-update-download-mark (article)
-  "Update the secondary (read, process, cache) mark."
+  "Update the download mark."
   (gnus-summary-update-mark
    (cond ((memq article gnus-newsgroup-undownloaded) 
           gnus-undownloaded-mark)
@@ -9930,12 +10009,13 @@ The difference between N and the number of marks cleared is returned."
   (when (memq gnus-current-article gnus-newsgroup-unreads)
     (gnus-summary-mark-article gnus-current-article gnus-read-mark)))
 
-(defun gnus-summary-mark-read-and-unread-as-read ()
+(defun gnus-summary-mark-read-and-unread-as-read (&optional new-mark)
   "Intended to be used by `gnus-summary-mark-article-hook'."
   (let ((mark (gnus-summary-article-mark)))
     (when (or (gnus-unread-mark-p mark)
              (gnus-read-mark-p mark))
-      (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
+      (gnus-summary-mark-article gnus-current-article
+                                (or new-mark gnus-read-mark)))))
 
 (defun gnus-summary-mark-unread-as-ticked ()
   "Intended to be used by `gnus-summary-mark-article-hook'."
@@ -10076,9 +10156,9 @@ The number of articles marked as read is returned."
            (if (and to-here reverse)
                (progn
                  (goto-char to-here)
-                 (while (and
-                         (gnus-summary-mark-article-as-read gnus-catchup-mark)
-                         (gnus-summary-find-next (not all)))))
+                 (gnus-summary-mark-read-and-unread-as-read gnus-catchup-mark)
+                 (while (gnus-summary-find-next (not all))
+                   (gnus-summary-mark-article-as-read gnus-catchup-mark)))
              (when (gnus-summary-first-subject (not all))
                (while (and
                        (if to-here (< (point) to-here) t)
@@ -10101,7 +10181,7 @@ If ALL is non-nil, also mark ticked and dormant articles as read."
   (gnus-summary-position-point))
 
 (defun gnus-summary-catchup-from-here (&optional all)
-  "Mark all unticked articles after the current one as read.
+  "Mark all unticked articles after (and including) the current one as read.
 If ALL is non-nil, also mark ticked and dormant articles as read."
   (interactive "P")
   (save-excursion
@@ -10302,8 +10382,8 @@ Returns nil if no thread was there to be shown."
   (interactive)
   (let ((buffer-read-only nil)
        (orig (point))
-       ;; first goto end then to beg, to have point at beg after let
-       (end (progn (end-of-line) (point)))
+       (end (gnus-point-at-eol))
+       ;; Leave point at bol
        (beg (progn (beginning-of-line) (point))))
     (prog1
        ;; Any hidden lines here?
@@ -10318,7 +10398,7 @@ Returns nil if no thread was there to be shown."
             gnus-thread-hide-subtree)
     (gnus-summary-hide-all-threads
      (if (or (consp gnus-thread-hide-subtree)
-            (gnus-functionp gnus-thread-hide-subtree))
+            (functionp gnus-thread-hide-subtree))
         (gnus-make-predicate gnus-thread-hide-subtree)
        nil))))
 
@@ -10734,7 +10814,7 @@ save those articles instead."
                    ;; Regular expression.
                    (ignore-errors
                      (re-search-forward match nil t)))
-                  ((gnus-functionp match)
+                  ((functionp match)
                    ;; Function.
                    (save-restriction
                      (widen)
@@ -11054,8 +11134,8 @@ If REVERSE, save parts that do not match TYPE."
   ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
   (when gnus-summary-selected-face
     (save-excursion
-      (let* ((beg (progn (beginning-of-line) (point)))
-            (end (progn (end-of-line) (point)))
+      (let* ((beg (gnus-point-at-bol))
+            (end (gnus-point-at-eol))
             ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
             (from (if (get-text-property beg gnus-mouse-face-prop)
                       beg
@@ -11096,7 +11176,8 @@ If REVERSE, save parts that do not match TYPE."
                  (c cond)
                  (list gnus-summary-highlight))
             (while list
-              (setcdr c (cons (list (caar list) (list 'quote (cdar list))) nil))
+              (setcdr c (cons (list (caar list) (list 'quote (cdar list)))
+                             nil))
               (setq c (cdr c)
                     list (cdr list)))
             (gnus-byte-compile (list 'lambda nil cond))))))
@@ -11363,10 +11444,10 @@ returned."
                                                (mail-header-number h))
                                              gnus-newsgroup-headers)))
     (setq gnus-newsgroup-headers
-         (merge 'list
-                gnus-newsgroup-headers
-                (gnus-fetch-headers articles)
-                'gnus-article-sort-by-number))
+         (gnus-merge 'list
+                     gnus-newsgroup-headers
+                     (gnus-fetch-headers articles)
+                     'gnus-article-sort-by-number))
     ;; Suppress duplicates?
     (when gnus-suppress-duplicates
       (gnus-dup-suppress-articles))
@@ -11495,4 +11576,8 @@ If ALL is a number, fetch this number of articles."
 
 (run-hooks 'gnus-sum-load-hook)
 
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
 ;;; gnus-sum.el ends here