Sync up with Pterodactyl Gnus 0.84
[elisp/gnus.git-] / lisp / gnus-sum.el
index c082995..4608511 100644 (file)
@@ -45,6 +45,9 @@
   (defvar gnus-decode-encoded-word-function)
   )
 
+(eval-and-compile
+  (autoload 'gnus-cache-articles-in-group "gnus-cache"))
+
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (autoload 'gnus-set-summary-default-charset "gnus-i18n" nil t)
 
@@ -817,7 +820,7 @@ which it may alter in any way.")
     ("^cn\\>\\|\\<chinese\\>" cn-gb-2312)
     ("^fj\\>\\|^japan\\>" iso-2022-jp-2)
     ("^relcom\\>" koi8-r)
-    ("^\\(cz\\|hun\\|pl\\|sk\\)\\>" iso-8859-2)
+    ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2)
     ("^israel\\>" iso-8859-1)
     ("^han\\>" euc-kr)
     ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
@@ -1043,7 +1046,8 @@ variable (string, integer, character, etc).")
     gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay
     gnus-newsgroup-scored gnus-newsgroup-kill-headers
     gnus-thread-expunge-below
-    gnus-score-alist gnus-current-score-file gnus-summary-expunge-below
+    gnus-score-alist gnus-current-score-file
+    (gnus-summary-expunge-below . global)
     (gnus-summary-mark-below . global)
     gnus-newsgroup-active gnus-scores-exclude-files
     gnus-newsgroup-history gnus-newsgroup-ancient
@@ -1419,6 +1423,7 @@ increase the score of each group you read."
     "e" gnus-summary-end-of-article
     "^" gnus-summary-refer-parent-article
     "r" gnus-summary-refer-parent-article
+    "D" gnus-summary-enter-digest-group
     "R" gnus-summary-refer-references
     "T" gnus-summary-refer-thread
     "g" gnus-summary-show-article
@@ -1441,6 +1446,7 @@ increase the score of each group you read."
     "v" gnus-summary-verbose-headers
     "m" gnus-summary-toggle-mime
     "h" gnus-article-treat-html
+    "H" gnus-article-strip-headers-in-body
     "d" gnus-article-treat-dumbquotes)
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
@@ -3978,8 +3984,10 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (gnus-adjust-marked-articles info))
 
     ;; Kludge to avoid having cached articles nixed out in virtual groups.
-    (when (gnus-virtual-group-p group)
-      (setq cached gnus-newsgroup-cached))
+    (setq cached
+         (if (gnus-virtual-group-p group)
+             gnus-newsgroup-cached
+           (gnus-cache-articles-in-group group)))
 
     (setq gnus-newsgroup-unreads
          (gnus-set-difference
@@ -4020,10 +4028,6 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                  gnus-fetch-old-headers)))
       (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name)
 
-      ;; Kludge to avoid having cached articles nixed out in virtual groups.
-      (when cached
-       (setq gnus-newsgroup-cached cached))
-
       ;; Suppress duplicates?
       (when gnus-suppress-duplicates
        (gnus-dup-suppress-articles))
@@ -4040,6 +4044,11 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
+
+      ;; Kludge to avoid having cached articles nixed out in virtual groups.
+      (when cached
+       (setq gnus-newsgroup-cached cached))
+
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
@@ -4218,13 +4227,14 @@ If SELECT-ARTICLES, only select those articles from GROUP."
        (uncompressed '(score bookmark killed))
        type list newmarked symbol delta-marks)
     (when info
-      ;; Add all marks lists that are non-nil to the list of marks lists.
+      ;; Add all marks lists to the list of marks lists.
       (while (setq type (pop types))
-       (when (setq list (symbol-value
+       (setq list (symbol-value
                          (setq symbol
                                (intern (format "gnus-newsgroup-%s"
                                                (car type))))))
 
+       (when list
          ;; Get rid of the entries of the articles that have the
          ;; default score.
          (when (and (eq (cdr type) 'score)
@@ -4239,30 +4249,35 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                    (setcdr prev (cdr arts))
                  (setq prev arts))
                (setq arts (cdr arts)))
-             (setq list (cdr all))))
-
-         (when (gnus-check-backend-function 'request-set-mark
-                                            gnus-newsgroup-name)
-           ;; score & bookmark are not proper flags (they are cons cells)
-           ;; cache is a internal gnus flag
-           (unless (memq (cdr type) '(cache score bookmark))
-             (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
-                    (del (gnus-remove-from-range old list))
-                    (add (gnus-remove-from-range list old)))
-               (if add
-                   (push (list add 'add (list (cdr type))) delta-marks))
-               (if del
-                   (push (list del 'del (list (cdr type))) delta-marks)))))
-
+             (setq list (cdr all)))))
+
+         (when (gnus-check-backend-function 'request-set-mark
+                                            gnus-newsgroup-name)
+           ;; uncompressed:s are not proper flags (they are cons cells)
+           ;; cache is a internal gnus flag
+           (unless (memq (cdr type) (cons 'cache uncompressed))
+             (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
+                    (list (gnus-compress-sequence (sort list '<)))
+                    (del (gnus-remove-from-range old list))
+                    (add (gnus-remove-from-range list old)))
+               (if add
+                   (push (list add 'add (list (cdr type))) delta-marks))
+               (if del
+                   (push (list del 'del (list (cdr type))) delta-marks)))))
+         
+       (when list
          (push (cons (cdr type)
                      (if (memq (cdr type) uncompressed) list
                        (gnus-compress-sequence
                         (set symbol (sort list '<)) t)))
                newmarked)))
+       
 
-      (if delta-marks
-         (gnus-request-set-mark gnus-newsgroup-name delta-marks))
-
+      (when delta-marks
+       (unless (gnus-check-group gnus-newsgroup-name)
+         (error "Can't open server for %s" gnus-newsgroup-name))
+       (gnus-request-set-mark gnus-newsgroup-name delta-marks))
+         
       ;; Enter these new marks into the info of the group.
       (if (nthcdr 3 info)
          (setcar (nthcdr 3 info) newmarked)
@@ -4480,15 +4495,6 @@ The resulting hash table is returned, or nil if no Xrefs were found."
        ;; Update the group buffer.
        (gnus-group-update-group group t)))))
 
-(defun gnus-methods-equal-p (m1 m2)
-  (let ((m1 (or m1 gnus-select-method))
-       (m2 (or m2 gnus-select-method)))
-    (or (equal m1 m2)
-       (and (eq (car m1) (car m2))
-            (or (not (memq 'address (assoc (symbol-name (car m1))
-                                           gnus-valid-select-methods)))
-                (equal (nth 1 m1) (nth 1 m2)))))))
-
 (defvar gnus-newsgroup-none-id 0)
 
 (defun gnus-get-newsgroup-headers (&optional dependencies force-new)
@@ -6990,8 +6996,10 @@ If ARG is a negative number, hide the unwanted header lines."
     (save-restriction
       (let* ((buffer-read-only nil)
             (inhibit-point-motion-hooks t)
-            (hidden (gnus-article-hidden-text-p 'headers))
-            e)
+            hidden e)
+       (save-restriction 
+         (article-narrow-to-head)
+         (setq hidden (gnus-article-hidden-text-p 'headers)))
        (goto-char (point-min))
        (when (search-forward "\n\n" nil t)
          (delete-region (point-min) (1- (point))))
@@ -7003,6 +7011,7 @@ If ARG is a negative number, hide the unwanted header lines."
        (insert-buffer-substring gnus-original-article-buffer 1 e)
        (save-restriction
          (narrow-to-region (point-min) (point))
+         (article-decode-encoded-words)
          (if (or hidden
                  (and (numberp arg) (< arg 0)))
              (let ((gnus-treat-hide-headers nil)
@@ -7089,6 +7098,9 @@ and `request-accept' functions."
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
+       (default-marks gnus-article-mark-lists)
+       (no-expire-marks (delete '(expirable . expire)
+                                (copy-sequence gnus-article-mark-lists)))
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
@@ -7194,10 +7206,10 @@ and `request-accept' functions."
                                       (list (cdr art-group)))))
 
            ;; Copy any marks over to the new group.
-           (let ((marks gnus-article-mark-lists)
+           (let ((marks (if (gnus-group-auto-expirable-p to-group)
+                            default-marks
+                          no-expire-marks))
                  (to-article (cdr art-group)))
-             (unless (gnus-group-auto-expirable-p to-group)
-               (setq marks (delete '(expirable . expire) marks)))
 
              ;; See whether the article is to be put in the cache.
              (when gnus-use-cache
@@ -7402,6 +7414,8 @@ This will be the case if the article has both been mailed and posted."
        ;; There are expirable articles in this group, so we run them
        ;; through the expiry process.
        (gnus-message 6 "Expiring articles...")
+       (unless (gnus-check-group gnus-newsgroup-name)
+         (error "Can't open server for %s" gnus-newsgroup-name))
        ;; The list of articles that weren't expired is returned.
        (save-excursion
          (if expiry-wait
@@ -7490,10 +7504,9 @@ groups."
        (error "The current newsgroup does not support article editing"))
       (gnus-summary-show-article t)
       (gnus-article-edit-article
-       'mime-to-mml
+       'ignore
        `(lambda (no-highlight)
          (let ((mail-parse-charset ',gnus-newsgroup-charset))
-           (mml-to-mime)
            (gnus-summary-edit-article-done
             ,(or (mail-header-references gnus-current-headers) "")
             ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))))))
@@ -8755,7 +8768,7 @@ save those articles instead."
                           split-name))
                    ((consp result)
                     (setq split-name (append result split-name)))))))))
-    split-name))
+    (nreverse split-name)))
 
 (defun gnus-valid-move-group-p (group)
   (and (boundp group)
@@ -9111,6 +9124,8 @@ save those articles instead."
            (let ((del (gnus-remove-from-range (gnus-info-read info) read))
                  (add (gnus-remove-from-range read (gnus-info-read info))))
              (when (or add del)
+              (unless (gnus-check-group group)
+                (error "Can't open server for %s" group))
                (gnus-request-set-mark
                 group (delq nil (list (if add (list add 'add '(read)))
                                       (if del (list del 'del '(read)))))))))
@@ -9336,6 +9351,115 @@ treated as multipart/mixed."
        (gnus-summary-show-article))
     (gnus-summary-show-article)))
 
+;;;
+;;; with article
+;;;
+
+(defmacro gnus-with-article (article &rest forms)
+  "Select ARTICLE and perform FORMS in the original article buffer.
+Then replace the article with the result."
+  `(progn
+     ;; We don't want the article to be marked as read.
+     (let (gnus-mark-article-hook)
+       (gnus-summary-select-article t t nil ,article))
+     (set-buffer gnus-original-article-buffer)
+     ,@forms
+     (if (not (gnus-check-backend-function
+              'request-replace-article (car gnus-article-current)))
+        (gnus-message 5 "Read-only group; not replacing")
+       (unless (gnus-request-replace-article
+               ,article (car gnus-article-current)
+               (current-buffer) t)
+        (error "Couldn't replace article")))
+     ;; The cache and backlog have to be flushed somewhat.
+     (when gnus-keep-backlog
+       (gnus-backlog-remove-article
+       (car gnus-article-current) (cdr gnus-article-current)))
+     (when gnus-use-cache
+       (gnus-cache-update-article
+       (car gnus-article-current) (cdr gnus-article-current)))))
+
+(put 'gnus-with-article 'lisp-indent-function 1)
+(put 'gnus-with-article 'edebug-form-spec '(form body))
+
+;;;
+;;; Generic summary marking commands
+;;;
+
+(defvar gnus-summary-marking-alist
+  '((read gnus-del-mark "d")
+    (unread gnus-unread-mark "u")
+    (ticked gnus-ticked-mark "!")
+    (dormant gnus-dormant-mark "?")
+    (expirable gnus-expirable-mark "e"))
+  "An alist of names/marks/keystrokes.")
+
+(defvar gnus-summary-generic-mark-map (make-sparse-keymap))
+(defvar gnus-summary-mark-map)
+
+(defun gnus-summary-make-all-marking-commands ()
+  (define-key gnus-summary-mark-map "M" gnus-summary-generic-mark-map)
+  (dolist (elem gnus-summary-marking-alist)
+    (apply 'gnus-summary-make-marking-command elem)))
+
+(defun gnus-summary-make-marking-command (name mark keystroke)
+  (let ((map (make-sparse-keymap)))
+    (define-key gnus-summary-generic-mark-map keystroke map)
+    (dolist (lway `((next "next" next nil "n")
+                   (next-unread "next unread" next t "N")
+                   (prev "previous" prev nil "p")
+                   (prev-unread "previous unread" prev t "P")
+                   (nomove "" nil nil ,keystroke)))
+      (let ((func (gnus-summary-make-marking-command-1
+                  mark (car lway) lway name)))
+       (setq func (eval func))
+       (define-key map (nth 4 lway) func)))))
+      
+(defun gnus-summary-make-marking-command-1 (mark way lway name)      
+  `(defun ,(intern
+           (format "gnus-summary-put-mark-as-%s%s"
+                   name (if (eq way 'nomove)
+                            ""
+                          (concat "-" (symbol-name way)))))
+     (n)
+     ,(format
+       "Mark the current article as %s%s.
+If N, the prefix, then repeat N times.
+If N is negative, move in reverse order.
+The difference between N and the actual number of articles marked is
+returned."
+       name (cadr lway))
+     (interactive "p")
+     (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway))))
+    
+(defun gnus-summary-generic-mark (n mark move unread)
+  "Mark N articles with MARK."
+  (unless (eq major-mode 'gnus-summary-mode)
+    (error "This command can only be used in the summary buffer"))
+  (gnus-summary-show-thread)
+  (let ((nummove
+        (cond
+         ((eq move 'next) 1)
+         ((eq move 'prev) -1)
+         (t 0))))
+    (if (zerop nummove)
+       (setq n 1)
+      (when (< n 0)
+       (setq n (abs n)
+             nummove (* -1 nummove))))
+    (while (and (> n 0)
+               (gnus-summary-mark-article nil mark)
+               (zerop (gnus-summary-next-subject nummove unread t)))
+      (setq n (1- n)))
+    (when (/= 0 n)
+      (gnus-message 7 "No more %sarticles" (if mark "" "unread ")))
+    (gnus-summary-recenter)
+    (gnus-summary-position-point)
+    (gnus-set-mode-line 'summary)
+    n))
+
+(gnus-summary-make-all-marking-commands)
+
 (gnus-ems-redefine)
 
 (provide 'gnus-sum)