lisp/ChangeLog.2: ChangeLog fixes
[gnus] / lisp / gnus-sum.el
index 15cbb5a..a1c0a0a 100644 (file)
@@ -1,6 +1,6 @@
 ;;; gnus-sum.el --- summary mode commands for Gnus
 
-;; Copyright (C) 1996-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2014 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
@@ -847,14 +847,6 @@ controls how articles are sorted."
                           (function :tag "other"))
                   (boolean :tag "Reverse order"))))
 
-(defcustom gnus-sort-threads-recursively t
-  "If non-nil, `gnus-thread-sort-functions' are applied recursively.
-Setting this to nil allows sorting high-score, recent,
-etc. threads to the top of the summary buffer while still
-retaining chronological old to new sorting order inside threads."
-  :group 'gnus-summary-sort
-  :type 'boolean)
-
 (defcustom gnus-thread-sort-functions '(gnus-thread-sort-by-number)
   "*List of functions used for sorting threads in the summary buffer.
 By default, threads are sorted by article number.
@@ -880,7 +872,11 @@ and `gnus-thread-sort-by-total-score' (see
 `gnus-thread-score-function').
 
 When threading is turned off, the variable
-`gnus-article-sort-functions' controls how articles are sorted."
+`gnus-article-sort-functions' controls how articles are sorted.
+
+By default, threads and their subthreads are sorted according to
+the value of this variable.  To use a different sorting order for
+subthreads, customize `gnus-subthread-sort-functions'."
   :group 'gnus-summary-sort
   :type '(repeat
           (gnus-widget-reversible
@@ -897,6 +893,29 @@ When threading is turned off, the variable
                    (function :tag "other"))
            (boolean :tag "Reverse order"))))
 
+(defcustom gnus-subthread-sort-functions 'gnus-thread-sort-functions
+  "*List of functions used for sorting subthreads in the summary buffer.
+By default, subthreads are sorted the same as threads, i.e.,
+according to the value of `gnus-thread-sort-functions'."
+  :version "24.4"
+  :group 'gnus-summary-sort
+  :type '(choice
+         (const :tag "Sort subthreads like threads" gnus-thread-sort-functions)
+         (repeat
+          (gnus-widget-reversible
+           (choice (function-item gnus-thread-sort-by-number)
+                   (function-item gnus-thread-sort-by-author)
+                   (function-item gnus-thread-sort-by-recipient)
+                   (function-item gnus-thread-sort-by-subject)
+                   (function-item gnus-thread-sort-by-date)
+                   (function-item gnus-thread-sort-by-score)
+                   (function-item gnus-thread-sort-by-most-recent-number)
+                   (function-item gnus-thread-sort-by-most-recent-date)
+                   (function-item gnus-thread-sort-by-random)
+                   (function-item gnus-thread-sort-by-total-score)
+                   (function :tag "other"))
+           (boolean :tag "Reverse order")))))
+
 (defcustom gnus-thread-score-function '+
   "*Function used for calculating the total score of a thread.
 
@@ -1122,7 +1141,6 @@ score:        The article's score.
 default:      The default article score.
 default-high: The default score for high scored articles.
 default-low:  The default score for low scored articles.
-below:        The score below which articles are automatically marked as read.
 mark:         The article's mark.
 uncached:     Non-nil if the article is uncached."
   :group 'gnus-summary-visual
@@ -1833,7 +1851,6 @@ increase the score of each group you read."
   [?\S-\ ] gnus-summary-prev-page
   "\177" gnus-summary-prev-page
   [delete] gnus-summary-prev-page
-  [backspace] gnus-summary-prev-page
   "\r" gnus-summary-scroll-up
   "\M-\r" gnus-summary-scroll-down
   "n" gnus-summary-next-unread-article
@@ -2205,7 +2222,6 @@ increase the score of each group you read."
   "\M-\C-e" gnus-summary-expire-articles-now
   "\177" gnus-summary-delete-article
   [delete] gnus-summary-delete-article
-  [backspace] gnus-summary-delete-article
   "m" gnus-summary-move-article
   "r" gnus-summary-respool-article
   "w" gnus-summary-edit-article
@@ -2341,7 +2357,8 @@ increase the score of each group you read."
           ["Mark above" gnus-summary-mark-above t]
           ["Tick above" gnus-summary-tick-above t]
           ["Clear above" gnus-summary-clear-above t])
-         ["Current score" gnus-summary-current-score t]
+         ["Current article score" gnus-summary-current-score t]
+         ["Current thread score" (gnus-summary-current-score 'total) t]
          ["Set score" gnus-summary-set-score t]
          ["Switch current score file..." gnus-score-change-score-file t]
          ["Set mark below..." gnus-score-set-mark-below t]
@@ -3085,6 +3102,7 @@ buffer; read the info pages for more information (`\\[gnus-info-find-node]').
 The following commands are available:
 
 \\{gnus-summary-mode-map}"
+  ;; FIXME: Use define-derived-mode.
   (interactive)
   (kill-all-local-variables)
   (let ((gnus-summary-local-variables gnus-newsgroup-variables))
@@ -3523,7 +3541,7 @@ If the setup was successful, non-nil is returned."
   "Set the global equivalents of the buffer-local variables.
 They are set to the latest values they had.  These reflect the summary
 buffer that was in action when the last article was fetched."
-  (when (eq major-mode 'gnus-summary-mode)
+  (when (derived-mode-p 'gnus-summary-mode)
     (setq gnus-summary-buffer (current-buffer))
     (let ((name gnus-newsgroup-name)
          (marked gnus-newsgroup-marked)
@@ -3971,7 +3989,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       t)
      ;; We couldn't select this group.
      ((null did-select)
-      (when (and (eq major-mode 'gnus-summary-mode)
+      (when (and (derived-mode-p 'gnus-summary-mode)
                 (not (equal (current-buffer) kill-buffer)))
        (kill-buffer (current-buffer))
        (if (not quit-config)
@@ -3990,7 +4008,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
      ;; The user did a `C-g' while prompting for number of articles,
      ;; so we exit this group.
      ((eq did-select 'quit)
-      (and (eq major-mode 'gnus-summary-mode)
+      (and (derived-mode-p 'gnus-summary-mode)
           (not (equal (current-buffer) kill-buffer))
           (kill-buffer (current-buffer)))
       (when kill-buffer
@@ -4033,7 +4051,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (unless no-display
        (gnus-summary-prepare))
       (when gnus-use-trees
-       (gnus-tree-open group)
+       (gnus-tree-open)
        (setq gnus-summary-highlight-line-function
              'gnus-tree-highlight-article))
       ;; If the summary buffer is empty, but there are some low-scored
@@ -4854,10 +4872,25 @@ If LINE, insert the rebuilt thread starting on line LINE."
            (gnus-delete-line)))))))
 
 (defun gnus-sort-threads-recursive (threads func)
+  ;; Responsible for sorting the root articles of threads.
+  (let ((subthread-sort-func (if (eq gnus-subthread-sort-functions
+                                    'gnus-thread-sort-functions)
+                                func
+                              (gnus-make-sort-function
+                               gnus-subthread-sort-functions))))
+    (sort (mapcar (lambda (thread)
+                   (cons (car thread)
+                         (and (cdr thread)
+                              (gnus-sort-subthreads-recursive
+                               (cdr thread) subthread-sort-func))))
+                 threads) func)))
+
+(defun gnus-sort-subthreads-recursive (threads func)
+  ;; Responsible for sorting subthreads.
   (sort (mapcar (lambda (thread)
                  (cons (car thread)
                        (and (cdr thread)
-                            (gnus-sort-threads-recursive (cdr thread) func))))
+                            (gnus-sort-subthreads-recursive (cdr thread) func))))
                threads) func))
 
 (defun gnus-sort-threads-loop (threads func)
@@ -4885,9 +4918,7 @@ If LINE, insert the rebuilt thread starting on line LINE."
        (condition-case nil
            (let ((max-lisp-eval-depth (max max-lisp-eval-depth 5000))
                  (sort-func (gnus-make-sort-function gnus-thread-sort-functions)))
-             (if gnus-sort-threads-recursively
-                 (gnus-sort-threads-recursive threads sort-func)
-               (sort threads sort-func)))
+             (gnus-sort-threads-recursive threads sort-func))
          ;; Even after binding max-lisp-eval-depth, the recursive
          ;; sorter might fail for very long threads.  In that case,
          ;; try using a (less well-tested) non-recursive sorter.
@@ -5580,7 +5611,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
     (or (and entry (not (eq (car entry) t))) ; Either it's active...
        (gnus-activate-group group)     ; Or we can activate it...
        (progn                          ; Or we bug out.
-         (when (equal major-mode 'gnus-summary-mode)
+         (when (derived-mode-p 'gnus-summary-mode)
            (gnus-kill-buffer (current-buffer)))
          (error
           "Couldn't activate group %s: %s"
@@ -5588,7 +5619,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
           (mm-decode-coding-string (gnus-status-message group) charset))))
 
     (unless (gnus-request-group group t)
-      (when (equal major-mode 'gnus-summary-mode)
+      (when (derived-mode-p 'gnus-summary-mode)
        (gnus-kill-buffer (current-buffer)))
       (error "Couldn't request group %s: %s"
             (mm-decode-coding-string group charset)
@@ -7185,6 +7216,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
     (gnus-dribble-save)))
 
 (declare-function gnus-cache-write-active "gnus-cache" (&optional force))
+(declare-function gnus-article-stop-animations "gnus-art" ())
 
 (defun gnus-summary-exit (&optional temporary leave-hidden)
   "Exit reading current newsgroup, and then return to group selection mode.
@@ -7225,7 +7257,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
     (when gnus-suppress-duplicates
       (gnus-dup-enter-articles))
     (when gnus-use-trees
-      (gnus-tree-close group))
+      (gnus-tree-close))
     (when gnus-use-cache
       (gnus-cache-write-active))
     ;; Remove entries for this group.
@@ -7248,6 +7280,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
                (not (string= group (gnus-group-group-name))))
       (gnus-group-next-unread-group 1))
     (setq group-point (point))
+    (gnus-article-stop-animations)
     (if temporary
        nil                             ;Nothing to do.
       (set-buffer buf)
@@ -7288,7 +7321,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (unless quit-config
        (setq gnus-newsgroup-name nil)))))
 
-(declare-function gnus-article-stop-animations "gnus-art" ())
 (declare-function gnus-stop-downloads "gnus-art" ())
 
 (defalias 'gnus-summary-quit 'gnus-summary-exit-no-update)
@@ -7328,7 +7360,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (unless gnus-single-article-buffer
        (setq gnus-article-current nil))
       (when gnus-use-trees
-       (gnus-tree-close group))
+       (gnus-tree-close))
       (gnus-async-prefetch-remove-group group)
       (when (get-buffer gnus-article-buffer)
        (bury-buffer gnus-article-buffer))
@@ -7338,6 +7370,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
        (gnus-group-update-group group nil t))
       (when (equal (gnus-group-group-name) group)
        (gnus-group-next-unread-group 1))
+      (gnus-article-stop-animations)
       (when quit-config
        (gnus-handle-ephemeral-exit quit-config)))))
 
@@ -7351,9 +7384,9 @@ The state which existed when entering the ephemeral is reset."
     (unless (eq (cdr quit-config) 'group)
       (setq gnus-current-select-method
            (gnus-find-method-for-group gnus-newsgroup-name)))
-    (cond ((eq major-mode 'gnus-summary-mode)
+    (cond ((derived-mode-p 'gnus-summary-mode)
           (gnus-set-global-variables))
-         ((eq major-mode 'gnus-article-mode)
+         ((derived-mode-p 'gnus-article-mode)
           (save-current-buffer
             ;; The `gnus-summary-buffer' variable may point
             ;; to the old summary buffer when using a single
@@ -7368,7 +7401,7 @@ The state which existed when entering the ephemeral is reset."
            (gnus-configure-windows 'pick 'force)
          (gnus-configure-windows (cdr quit-config) 'force))
       (gnus-configure-windows (cdr quit-config) 'force))
-    (when (eq major-mode 'gnus-summary-mode)
+    (when (derived-mode-p 'gnus-summary-mode)
       (if (memq gnus-auto-select-on-ephemeral-exit '(next-noselect
                                                     next-unread-noselect))
          (when (zerop (cond ((eq gnus-auto-select-on-ephemeral-exit
@@ -7438,7 +7471,7 @@ The state which existed when entering the ephemeral is reset."
       (when (and gnus-use-trees
                 (gnus-buffer-exists-p buffer))
        (with-current-buffer buffer
-         (gnus-tree-close gnus-newsgroup-name)))
+         (gnus-tree-close)))
       (gnus-kill-buffer buffer))
      ;; Deaden the buffer.
      ((gnus-buffer-exists-p buffer)
@@ -7667,7 +7700,7 @@ Given a prefix, will force an `article' buffer configuration."
   "Display ARTICLE in article buffer."
   (unless (and (gnus-buffer-live-p gnus-article-buffer)
               (with-current-buffer gnus-article-buffer
-                (eq major-mode 'gnus-article-mode)))
+                (derived-mode-p 'gnus-article-mode)))
     (gnus-article-setup-buffer))
   (gnus-set-global-variables)
   (with-current-buffer gnus-article-buffer
@@ -7699,7 +7732,7 @@ non-nil, the article will be re-fetched even if it already present in
 the article buffer.  If PSEUDO is non-nil, pseudo-articles will also
 be displayed."
   ;; Make sure we are in the summary buffer to work around bbdb bug.
-  (unless (eq major-mode 'gnus-summary-mode)
+  (unless (derived-mode-p 'gnus-summary-mode)
     (set-buffer gnus-summary-buffer))
   (let ((article (or article (gnus-summary-article-number)))
        (all-headers (not (not all-headers))) ;Must be t or nil.
@@ -7751,7 +7784,7 @@ If SUBJECT, only articles with SUBJECT are selected.
 If BACKWARD, the previous article is selected instead of the next."
   (interactive "P")
   ;; Make sure we are in the summary buffer.
-  (unless (eq major-mode 'gnus-summary-mode)
+  (unless (derived-mode-p 'gnus-summary-mode)
     (set-buffer gnus-summary-buffer))
   (cond
    ;; Is there such an article?
@@ -9170,6 +9203,7 @@ To control what happens when you exit the group, see the
                                   (gnus-fetch-field "from")))
          (setq params
                (append
+                params
                 (list (cons 'to-address
                             (funcall gnus-decode-encoded-address-function
                                      to-address))))))
@@ -10625,13 +10659,31 @@ groups."
 
 ;;; Respooling
 
+(defvar nnimap-split-fancy)
+(defvar nnimap-split-methods)
+
 (defun gnus-summary-respool-query (&optional silent trace)
   "Query where the respool algorithm would put this article."
   (interactive)
   (let (gnus-mark-article-hook)
     (gnus-summary-select-article)
     (with-current-buffer gnus-original-article-buffer
-      (let ((groups (nnmail-article-group 'identity trace)))
+      (let ((groups
+            (if (eq (car (gnus-find-method-for-group gnus-newsgroup-name))
+                    'nnimap)
+                ;; nnimap has its own splitting variables.
+                (let ((nnmail-split-methods
+                       (cond
+                        ((eq nnimap-split-methods 'default)
+                         nnmail-split-methods)
+                        (nnimap-split-methods
+                         nnimap-split-methods)
+                        (nnimap-split-fancy
+                         'nnmail-split-fancy)))
+                      (nnmail-split-fancy (or nnimap-split-fancy
+                                              nnmail-split-fancy)))
+                  (nnmail-article-group 'identity trace))
+              (nnmail-article-group 'identity trace))))
        (unless silent
          (if groups
              (message "This message would go to %s"
@@ -12648,7 +12700,7 @@ UNREAD is a sorted list."
                 (string-match "Summary" buffer)
                 (with-current-buffer buffer
                   ;; We check that this is, indeed, a summary buffer.
-                  (and (eq major-mode 'gnus-summary-mode)
+                  (and (derived-mode-p 'gnus-summary-mode)
                        ;; Also make sure this isn't bogus.
                        gnus-newsgroup-prepared
                        ;; Also make sure that this isn't a
@@ -12783,7 +12835,7 @@ returned."
 
 (defun gnus-summary-generic-mark (n mark move unread)
   "Mark N articles with MARK."
-  (unless (eq major-mode 'gnus-summary-mode)
+  (unless (derived-mode-p 'gnus-summary-mode)
     (error "This command can only be used in the summary buffer"))
   (gnus-summary-show-thread)
   (let ((nummove