]> code.delx.au - gnu-emacs/commitdiff
Merge changes made in Gnus trunk
authorKatsumi Yamaoka <yamaoka@jpl.org>
Tue, 2 Jul 2013 10:38:58 +0000 (10:38 +0000)
committerKatsumi Yamaoka <yamaoka@jpl.org>
Tue, 2 Jul 2013 10:38:58 +0000 (10:38 +0000)
2012-03-22 Lars Magne Ingebrigtsen <larsi@gnus.org>
 * gnus.texi (Client-Side IMAP Splitting):
   Note that `nnimap-inbox' now can be a list.

2013-06-05 David Engster <deng@randomsample.de>
 * gnus-sum.el (gnus-update-marks): Do not remove empty 'unexist'
   ranges, since `nnimap-retrieve-group-data-early' also uses it as a flag
   to see whether the group was synced before.

2012-09-05 Martin Stjernholm <mast@lysator.liu.se>
 * nnimap.el (nnimap-request-move-article): Decode the group name when
   doing internal moves to avoid charset issues.

2012-09-05 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-request-list):
   Revert change that made listing synchronous.
   (nnimap-get-responses): Restore.

2012-08-31 Dave Abrahams <dave@boostpro.com>
 * nnimap.el (nnimap-change-group): Document result value.
 * nnimap.el (nnimap-find-article-by-message-id):
   Account for the fact that nnimap-change-group can return t.

2012-08-06 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-request-head):
   Resture to-buffer parameter, used by `nnimap-request-move-article'.
 * nnimap.el (nnimap-request-head): Remove to-buffer argument.
 * gnus-int.el (gnus-request-head): Remove to-buffer argument, only
   supported by nnimap actually. Reverts previous change.
 * gnus-int.el (gnus-request-head): Add an optional to-buffer parameter
   to mimic `gnus-request-article' and enjoy backends the nn*-request-head
   to-buffer argument that is already supported.

2012-07-24 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-get-responses): Remove, unused.

2012-06-25 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-request-articles-find-limit): Rename from
   `nnimap-request-move-articles-find-limit' since we do not use it
   only for move operations.
   (nnimap-request-accept-article):
   Use `nnimap-request-articles-find-limit' to limit search by message-id.

2012-06-19 Julien Danjou <julien@danjou.info>
 * nnir.el (nnir-run-imap): Fix, use `nnimap-change-group'.
 * nnimap.el (nnimap-log-buffer):
   Check that `window-point-insertion-type' is boundp, since it's not
   available in XEmacs.

2012-06-19 Michael Welsh Duggan <md5i@md5i.com>
 * nnimap.el (nnimap-log-buffer):
   Add this, setting `window-point-insertion-type' in the buffer to t.
   (nnimap-log-command): Use nnimap-log-buffer.

2012-06-19 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-find-article-by-message-id):
   Add an optional limit argument to be able to limit the search.
   (nnimap-request-move-article):
   Use `nnimap-request-move-articles-find-limit'.
   (nnimap-request-move-articles-find-limit):
   Add this to limit the search by Message-Id after a message move.
   (nnimap): Add defgroup.

2012-06-15 Julien Danjou <julien@danjou.info>
 * nnimap.el (nnimap-find-article-by-message-id):
   Use `nnimap-possibly-change-group' rather than its own EXAMINE call.
   (nnimap-possibly-change-group): Add read-only argument.
   (nnimap-request-list): Use nnimap-possibly-change-group rather than
   issuing EXAMINE manually.
   (nnimap-find-article-by-message-id):
   Use `nnimap-possibly-change-group' with read-only argument.
   (nnimap-change-group): Rename from `nnimap-possibly-change-group'.
   We cannot possibly change because we need to be sure that it's either
   read-write or read-only.

2012-06-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
 * gnus-sum.el (gnus-summary-insert-old-articles):
   Don't include unexistent messages.

2012-04-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
 * gnus-start.el (gnus-clean-old-newsrc):
   Remove totally bogus `unexists' entries.
   (gnus-clean-old-newsrc): Fix last checkin.
 * nnimap.el (nnimap-update-info):
   None of the articles below the active low-water mark exist.

2012-03-27 Katsumi Yamaoka <yamaoka@jpl.org>
 * nnimap.el (gnus-refer-thread-use-nnir): Silence the byte compiler.

2012-03-22 Sergio Martinez <samf0xb58@gmail.com> (tiny change)
 * nnimap.el (nnimap-request-scan):
   Allow `nnimap-inbox' to be a list of inboxes.

2012-03-10 Lars Magne Ingebrigtsen <larsi@gnus.org>
 * gnus-group.el (gnus-group-expire-articles-1):
   Don't try to expire messages that don't exist.
 * gnus-sum.el (gnus-summary-expire-articles): Ditto.

2012-02-20 Lars Ingebrigtsen <larsi@gnus.org>
 * gnus-start.el (gnus-clean-old-newsrc): Allow a FORCE parameter.

2012-02-15 Lars Ingebrigtsen <larsi@gnus.org>
 * gnus-start.el (gnus-clean-old-newsrc):
   Delete `unexist' from pre-Ma Gnus 0.3.

2012-02-15 Lars Ingebrigtsen <larsi@gnus.org>
 * gnus-sum.el (gnus-summary-local-variables):
   Make `gnus-newsgroup-unexist' into a local variable.

2012-02-11 Lars Ingebrigtsen <larsi@gnus.org>
 * gnus-sum.el (gnus-adjust-marked-articles):
   Add to `gnus-newsgroup-unexist'.
 * gnus.el (gnus-article-mark-lists):
   Add `unexist' to the list of marks.
   (gnus-article-special-mark-lists):
   Put the `unexist' in the special marks list instead.
 * gnus-sum.el (gnus-articles-to-read): Don't include unexisting
   articles in the list of articles to be selected.
 * nnimap.el (nnimap-retrieve-group-data-early):
   Query for unexisting articles.
   (nnimap-update-info): Keep track of unexisting articles.
   (nnimap-update-qresync-info): Ditto.

2012-02-01 Lars Ingebrigtsen <larsi@gnus.org>
 * gnus-start.el (gnus-clean-old-newsrc): New function.
   (gnus-read-newsrc-file): Use it.

doc/misc/ChangeLog
doc/misc/gnus.texi
lisp/gnus/ChangeLog
lisp/gnus/gnus-group.el
lisp/gnus/gnus-start.el
lisp/gnus/gnus-sum.el
lisp/gnus/gnus.el
lisp/gnus/nnimap.el
lisp/gnus/nnir.el

index 016b0e8340fb55dde1281c8263b5453c3b6c4bbf..d0f229a9c9e4d2e916a2048dddbc8f6e860e8913 100644 (file)
@@ -1,3 +1,8 @@
+2013-07-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus.texi (Client-Side IMAP Splitting):
+       Note that `nnimap-inbox' now can be a list.
+
 2013-06-24  Glenn Morris  <rgm@gnu.org>
 
        * eshell.texi: Fix cross-references to other manuals.
index b4d786c4d45cf3c934d1591624f484455d39516f..6df72f87fc76dd13bb548cb233f225d892e49532 100644 (file)
@@ -14240,7 +14240,8 @@ variables are relevant:
 
 @table @code
 @item nnimap-inbox
-This is the @acronym{IMAP} mail box that will be scanned for new mail.
+This is the @acronym{IMAP} mail box that will be scanned for new
+mail.  This can also be a list of mail box names.
 
 @item nnimap-split-methods
 Uses the same syntax as @code{nnmail-split-methods} (@pxref{Splitting
index 9639f21c2fbbf8914eb1b7dae25951d5ddfefb15..49b4538057593e8c50504070f0b5da983a362054 100644 (file)
@@ -1,3 +1,157 @@
+2013-07-02  David Engster  <deng@randomsample.de>
+
+       * gnus-sum.el (gnus-update-marks): Do not remove empty 'unexist'
+       ranges, since `nnimap-retrieve-group-data-early' also uses it as a flag
+       to see whether the group was synced before.
+
+2013-07-02  Martin Stjernholm  <mast@lysator.liu.se>
+
+       * nnimap.el (nnimap-request-move-article): Decode the group name when
+       doing internal moves to avoid charset issues.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-request-list):
+       Revert change that made listing synchronous.
+       (nnimap-get-responses): Restore.
+
+2013-07-02  Dave Abrahams  <dave@boostpro.com>
+
+       * nnimap.el (nnimap-change-group): Document result value.
+
+       * nnimap.el (nnimap-find-article-by-message-id):
+       Account for the fact that nnimap-change-group can return t.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-request-head):
+       Resture to-buffer parameter, used by `nnimap-request-move-article'.
+
+       * nnimap.el (nnimap-request-head): Remove to-buffer argument.
+
+       * gnus-int.el (gnus-request-head): Remove to-buffer argument, only
+       supported by nnimap actually. Reverts previous change.
+
+       * gnus-int.el (gnus-request-head): Add an optional to-buffer parameter
+       to mimic `gnus-request-article' and enjoy backends the nn*-request-head
+       to-buffer argument that is already supported.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-get-responses): Remove, unused.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-request-articles-find-limit): Rename from
+       `nnimap-request-move-articles-find-limit' since we do not use it
+       only for move operations.
+       (nnimap-request-accept-article):
+       Use `nnimap-request-articles-find-limit' to limit search by message-id.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnir.el (nnir-run-imap): Fix, use `nnimap-change-group'.
+
+       * nnimap.el (nnimap-log-buffer):
+       Check that `window-point-insertion-type' is boundp, since it's not
+       available in XEmacs.
+
+2013-07-02  Michael Welsh Duggan  <md5i@md5i.com>
+
+       * nnimap.el (nnimap-log-buffer):
+       Add this, setting `window-point-insertion-type' in the buffer to t.
+       (nnimap-log-command): Use nnimap-log-buffer.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-find-article-by-message-id):
+       Add an optional limit argument to be able to limit the search.
+       (nnimap-request-move-article):
+       Use `nnimap-request-move-articles-find-limit'.
+       (nnimap-request-move-articles-find-limit):
+       Add this to limit the search by Message-Id after a message move.
+       (nnimap): Add defgroup.
+
+2013-07-02  Julien Danjou  <julien@danjou.info>
+
+       * nnimap.el (nnimap-find-article-by-message-id):
+       Use `nnimap-possibly-change-group' rather than its own EXAMINE call.
+       (nnimap-possibly-change-group): Add read-only argument.
+       (nnimap-request-list): Use nnimap-possibly-change-group rather than
+       issuing EXAMINE manually.
+       (nnimap-find-article-by-message-id):
+       Use `nnimap-possibly-change-group' with read-only argument.
+       (nnimap-change-group): Rename from `nnimap-possibly-change-group'.
+       We cannot possibly change because we need to be sure that it's either
+       read-write or read-only.
+
+2013-07-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-summary-insert-old-articles):
+       Don't include unexistent messages.
+
+2013-07-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-start.el (gnus-clean-old-newsrc):
+       Remove totally bogus `unexists' entries.
+       (gnus-clean-old-newsrc): Fix last checkin.
+
+       * nnimap.el (nnimap-update-info):
+       None of the articles below the active low-water mark exist.
+
+2013-07-02  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+       * nnimap.el (gnus-refer-thread-use-nnir): Silence the byte compiler.
+
+2013-07-02  Sergio Martinez  <samf0xb58@gmail.com>  (tiny change)
+
+       * nnimap.el (nnimap-request-scan):
+       Allow `nnimap-inbox' to be a list of inboxes.
+
+2013-07-02  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-group.el (gnus-group-expire-articles-1):
+       Don't try to expire messages that don't exist.
+
+       * gnus-sum.el (gnus-summary-expire-articles): Ditto.
+
+2013-07-02  Lars Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-start.el (gnus-clean-old-newsrc): Allow a FORCE parameter.
+
+2013-07-02  Lars Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-start.el (gnus-clean-old-newsrc):
+       Delete `unexist' from pre-Ma Gnus 0.3.
+
+2013-07-02  Lars Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-summary-local-variables):
+       Make `gnus-newsgroup-unexist' into a local variable.
+
+2013-07-02  Lars Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-sum.el (gnus-adjust-marked-articles):
+       Add to `gnus-newsgroup-unexist'.
+
+       * gnus.el (gnus-article-mark-lists):
+       Add `unexist' to the list of marks.
+       (gnus-article-special-mark-lists):
+       Put the `unexist' in the special marks list instead.
+
+       * gnus-sum.el (gnus-articles-to-read): Don't include unexisting
+       articles in the list of articles to be selected.
+
+       * nnimap.el (nnimap-retrieve-group-data-early):
+       Query for unexisting articles.
+       (nnimap-update-info): Keep track of unexisting articles.
+       (nnimap-update-qresync-info): Ditto.
+
+2013-07-02  Lars Ingebrigtsen  <larsi@gnus.org>
+
+       * gnus-start.el (gnus-clean-old-newsrc): New function.
+       (gnus-read-newsrc-file): Use it.
+
 2013-07-02  Daiki Ueno  <ueno@gnu.org>
 
        * mml2015.el (mml2015-epg-key-image): Use 'gnus-create-image' instead
index 207877364fea44d848e13fe21ff37c11f7a18291..8050f5d59d755a380d17d1046a0b836876260ce4 100644 (file)
@@ -3654,6 +3654,10 @@ Uses the process/prefix convention."
           (expirable (if (gnus-group-total-expirable-p group)
                          (cons nil (gnus-list-of-read-articles group))
                        (assq 'expire (gnus-info-marks info))))
+          (articles-to-expire
+           (gnus-list-range-difference
+            (gnus-uncompress-sequence (cdr expirable))
+            (cdr (assq 'unexist (gnus-info-marks info)))))
           (expiry-wait (gnus-group-find-parameter group 'expiry-wait))
           (nnmail-expiry-target
            (or (gnus-group-find-parameter group 'expiry-target)
@@ -3668,11 +3672,9 @@ Uses the process/prefix convention."
              ;; parameter.
              (let ((nnmail-expiry-wait-function nil)
                    (nnmail-expiry-wait expiry-wait))
-               (gnus-request-expire-articles
-                (gnus-uncompress-sequence (cdr expirable)) group))
+               (gnus-request-expire-articles articles-to-expire group))
            ;; Just expire using the normal expiry values.
-           (gnus-request-expire-articles
-            (gnus-uncompress-sequence (cdr expirable)) group))))
+           (gnus-request-expire-articles articles-to-expire group))))
        (gnus-close-group group))
       (gnus-message 6 "Expiring articles in %s...done"
                    (gnus-group-decoded-name group))
index 48bb99bfbcefe677f9cdfc026b03738e0980c994..084af884930ac28222db2305d7a5fb24f66c51af 100644 (file)
@@ -2301,7 +2301,27 @@ If FORCE is non-nil, the .newsrc file is read."
          (gnus-message 5 "Reading %s...done" newsrc-file)))
 
       ;; Convert old to new.
-      (gnus-convert-old-newsrc))))
+      (gnus-convert-old-newsrc)
+      (gnus-clean-old-newsrc))))
+
+(defun gnus-clean-old-newsrc (&optional force)
+  (when gnus-newsrc-file-version
+    ;; Remove totally bogus `unexists' entries.  The name is
+    ;; `unexist'.
+    (dolist (info (cdr gnus-newsrc-alist))
+      (let ((exist (assoc 'unexists (gnus-info-marks info))))
+       (when exist
+         (gnus-info-set-marks
+          info (delete exist (gnus-info-marks info))))))
+    (when (or force
+             (< (gnus-continuum-version gnus-newsrc-file-version)
+                (gnus-continuum-version "Ma Gnus v0.03")))
+      ;; Remove old `exist' marks from old nnimap groups.
+      (dolist (info (cdr gnus-newsrc-alist))
+       (let ((exist (assoc 'unexist (gnus-info-marks info))))
+         (when exist
+           (gnus-info-set-marks
+            info (delete exist (gnus-info-marks info)))))))))
 
 (defun gnus-convert-old-newsrc ()
   "Convert old newsrc formats into the current format, if needed."
index c8f593ea40342347a045e854987923d8ca5b9e70..e136d4f8173788c2b70959ca2722f6882c0c2894 100644 (file)
@@ -1524,6 +1524,9 @@ This list will always be a subset of gnus-newsgroup-undownloaded.")
 (defvar gnus-newsgroup-seen nil
   "Range of seen articles in the current newsgroup.")
 
+(defvar gnus-newsgroup-unexist nil
+  "Range of unexistent articles in the current newsgroup.")
+
 (defvar gnus-newsgroup-articles nil
   "List of articles in the current newsgroup.")
 
@@ -1571,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-unexist
     gnus-newsgroup-cached
     gnus-newsgroup-downloadable
     gnus-newsgroup-undownloaded
@@ -5789,6 +5793,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
   "Find out what articles the user wants to read."
   (let* ((only-read-p t)
         (articles
+         (gnus-list-range-difference
          ;; Select all articles if `read-all' is non-nil, or if there
          ;; are no unread articles.
          (if (or read-all
@@ -5815,7 +5820,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
            (setq only-read-p nil)
            (gnus-sorted-nunion
             (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked)
-            gnus-newsgroup-unreads)))
+            gnus-newsgroup-unreads))
+         (cdr (assq 'unexist (gnus-info-marks (gnus-get-info group))))))
         (scored-list (gnus-killed-articles gnus-newsgroup-killed articles))
         (scored (length scored-list))
         (number (length articles))
@@ -5985,7 +5991,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                          (and (numberp (car articles))
                               (> min (car articles)))))
            (pop articles))
-         (set var articles))))))))
+         (set var articles))
+        ((eq mark 'unexist)
+         (set var (cdr marks)))))))))
 
 (defun gnus-update-missing-marks (missing)
   "Go through the list of MISSING articles and remove them from the mark lists."
@@ -6061,7 +6069,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                         (gnus-active gnus-newsgroup-name) del))
              (push (list del 'del (list (cdr type))) delta-marks))))
 
-       (when list
+       (when (or list
+                 (eq (cdr type) 'unexist))
          (push (cons (cdr type) list) newmarked)))
 
       (when delta-marks
@@ -10305,16 +10314,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))
-          (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)))
@@ -12847,7 +12859,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.
-             (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)
index 2c2dbd90c5660f62404938e71373dcf103633c94..9a927a1cfabcae0db135c3ebe8a29a14c2266692 100644 (file)
@@ -2636,10 +2636,11 @@ a string, be sure to use a valid format, see RFC 2616."
     (scored . score) (saved . save)
     (cached . cache) (downloadable . download)
     (unsendable . unsend) (forwarded . forward)
-    (seen . seen)))
+    (seen . seen) (unexist . unexist)))
 
 (defconst gnus-article-special-mark-lists
   '((seen range)
+    (unexist range)
     (killed range)
     (bookmark tuple)
     (uid tuple)
@@ -2654,7 +2655,7 @@ a string, be sure to use a valid format, see RFC 2616."
 ;; `score' is not a proper mark
 ;; `bookmark': don't propagated it, or fix the bug in update-mark.
 (defconst gnus-article-unpropagated-mark-lists
-  '(seen cache download unsend score bookmark)
+  '(seen cache download unsend score bookmark unexist)
   "Marks that shouldn't be propagated to back ends.
 Typical marks are those that make no sense in a standalone back end,
 such as a mark that says whether an article is stored in the cache
index 8fdd69b47da8333cfa8f67ab5ad01d680db24b70..4d9320b995f5236b3b09caa7c9fe93383b0bda37 100644 (file)
@@ -82,7 +82,8 @@ back on `network'.")
 
 (defvoo nnimap-inbox nil
   "The mail box where incoming mail arrives and should be split out of.
-For example, \"INBOX\".")
+This can be a string or a list of strings
+For example, \"INBOX\" or (\"INBOX\" \"SENT\").")
 
 (defvoo nnimap-split-methods nil
   "How mail is split.
@@ -123,6 +124,16 @@ will fetch all parts that have types that match that string.  A
 likely value would be \"text/\" to automatically fetch all
 textual parts.")
 
+(defgroup nnimap nil
+  "IMAP for Gnus."
+  :group 'gnus)
+
+(defcustom nnimap-request-articles-find-limit nil
+  "Limit the number of articles to look for after moving an article."
+  :type 'integer
+  :version "24.3"
+  :group 'nnimap)
+
 (defvar nnimap-process nil)
 
 (defvar nnimap-status-string "")
@@ -173,7 +184,7 @@ textual parts.")
     (setq group (nnimap-decode-gnus-group group)))
   (with-current-buffer nntp-server-buffer
     (erase-buffer)
-    (when (nnimap-possibly-change-group group server)
+    (when (nnimap-change-group group server)
       (with-current-buffer (nnimap-buffer)
        (erase-buffer)
        (nnimap-wait-for-response
@@ -567,10 +578,10 @@ textual parts.")
   (when group
     (setq group (nnimap-decode-gnus-group group)))
   (with-current-buffer nntp-server-buffer
-    (let ((result (nnimap-possibly-change-group group server))
+    (let ((result (nnimap-change-group group server))
          parts structure)
       (when (stringp article)
-       (setq article (nnimap-find-article-by-message-id group article)))
+       (setq article (nnimap-find-article-by-message-id group server article)))
       (when (and result
                 article)
        (erase-buffer)
@@ -599,10 +610,10 @@ textual parts.")
 (deffoo nnimap-request-head (article &optional group server to-buffer)
   (when group
     (setq group (nnimap-decode-gnus-group group)))
-  (when (nnimap-possibly-change-group group server)
+  (when (nnimap-change-group group server)
     (with-current-buffer (nnimap-buffer)
       (when (stringp article)
-       (setq article (nnimap-find-article-by-message-id group article)))
+       (setq article (nnimap-find-article-by-message-id group server article)))
       (if (null article)
          nil
        (nnimap-get-whole-article
@@ -751,7 +762,7 @@ textual parts.")
 
 (deffoo nnimap-request-group (group &optional server dont-check info)
   (setq group (nnimap-decode-gnus-group group))
-  (let ((result (nnimap-possibly-change-group
+  (let ((result (nnimap-change-group
                 ;; Don't SELECT the group if we're going to select it
                 ;; later, anyway.
                 (if (and (not dont-check)
@@ -801,19 +812,19 @@ textual parts.")
 
 (deffoo nnimap-request-create-group (group &optional server args)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
       (car (nnimap-command "CREATE %S" (utf7-encode group t))))))
 
 (deffoo nnimap-request-delete-group (group &optional force server)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
       (car (nnimap-command "DELETE %S" (utf7-encode group t))))))
 
 (deffoo nnimap-request-rename-group (group new-name &optional server)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (with-current-buffer (nnimap-buffer)
       (nnimap-unselect-group)
       (car (nnimap-command "RENAME %S %S"
@@ -828,7 +839,7 @@ textual parts.")
 
 (deffoo nnimap-request-expunge-group (group &optional server)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group group server)
+  (when (nnimap-change-group group server)
     (with-current-buffer (nnimap-buffer)
       (car (nnimap-command "EXPUNGE")))))
 
@@ -856,6 +867,8 @@ textual parts.")
 (deffoo nnimap-request-move-article (article group server accept-form
                                             &optional last internal-move-group)
   (setq group (nnimap-decode-gnus-group group))
+  (when internal-move-group
+    (setq internal-move-group (nnimap-decode-gnus-group internal-move-group)))
   (with-temp-buffer
     (mm-disable-multibyte)
     (when (funcall (if internal-move-group
@@ -876,11 +889,12 @@ textual parts.")
                (cons internal-move-group
                      (or (nnimap-find-uid-response "COPYUID" (cadr result))
                          (nnimap-find-article-by-message-id
-                          internal-move-group message-id)))))
+                          internal-move-group server message-id
+                           nnimap-request-articles-find-limit)))))
          ;; Move the article to a different method.
          (let ((result (eval accept-form)))
            (when result
-             (nnimap-possibly-change-group group server)
+             (nnimap-change-group group server)
              (nnimap-delete-article article)
              result)))))))
 
@@ -889,7 +903,7 @@ textual parts.")
   (cond
    ((null articles)
     nil)
-   ((not (nnimap-possibly-change-group group server))
+   ((not (nnimap-change-group group server))
     articles)
    ((and force
         (eq nnmail-expiry-target 'delete))
@@ -926,7 +940,7 @@ textual parts.")
           (gnus-server-equal (gnus-group-method nnmail-expiry-target)
                              (gnus-server-to-method
                               (format "nnimap:%s" server))))
-      (and (nnimap-possibly-change-group group server)
+      (and (nnimap-change-group group server)
           (with-current-buffer (nnimap-buffer)
             (nnheader-message 7 "Expiring articles from %s: %s" group articles)
             (nnimap-command
@@ -956,7 +970,7 @@ textual parts.")
              (when target
                (push article deleted-articles))))))))
     ;; Change back to the current group again.
-    (nnimap-possibly-change-group group server)
+    (nnimap-change-group group server)
     (setq deleted-articles (nreverse deleted-articles))
     (nnimap-delete-article (gnus-compress-sequence deleted-articles))
     deleted-articles))
@@ -978,23 +992,37 @@ textual parts.")
                               (cdr (assoc "SEARCH" (cdr result))))))))))
 
 
-(defun nnimap-find-article-by-message-id (group message-id)
+(defun nnimap-find-article-by-message-id (group server message-id
+                                               &optional limit)
+  "Search for message with MESSAGE-ID in GROUP from SERVER.
+If LIMIT, first try to limit the search to the N last articles."
   (with-current-buffer (nnimap-buffer)
     (erase-buffer)
-    (unless (or (not group) (equal group (nnimap-group nnimap-object)))
-      (setf (nnimap-group nnimap-object) nil)
-      (setf (nnimap-examined nnimap-object) group)
-      (nnimap-send-command "EXAMINE %S" (utf7-encode group t)))
-    (let ((sequence
-          (nnimap-send-command "UID SEARCH HEADER Message-Id %S" message-id))
-         article result)
-      (setq result (nnimap-wait-for-response sequence))
-      (when (and result
-                (car (setq result (nnimap-parse-response))))
-       ;; Select the last instance of the message in the group.
-       (and (setq article
-                  (car (last (cdr (assoc "SEARCH" (cdr result))))))
-            (string-to-number article))))))
+    (let* ((change-group-result (nnimap-change-group group server nil t))
+           (number-of-article
+            (and (listp change-group-result)
+                 (catch 'found
+                   (dolist (result (cdr change-group-result))
+                     (when (equal "EXISTS" (cadr result))
+                       (throw 'found (car result)))))))
+           (sequence
+            (nnimap-send-command
+            "UID SEARCH%s HEADER Message-Id %S"
+            (if (and limit number-of-article)
+                ;; The -1 is because IMAP message
+                ;; numbers are one-based rather than
+                ;; zero-based.
+                (format " %s:*" (- (string-to-number number-of-article)
+                                   limit -1))
+              "")
+            message-id)))
+      (when (nnimap-wait-for-response sequence)
+        (let ((article (car (last (cdr (assoc "SEARCH"
+                                             (nnimap-parse-response)))))))
+          (if article
+              (string-to-number article)
+            (when (and limit number-of-article)
+              (nnimap-find-article-by-message-id group server message-id))))))))
 
 (defun nnimap-delete-article (articles)
   (with-current-buffer (nnimap-buffer)
@@ -1015,11 +1043,14 @@ textual parts.")
 (deffoo nnimap-request-scan (&optional group server)
   (when group
     (setq group (nnimap-decode-gnus-group group)))
-  (when (and (nnimap-possibly-change-group nil server)
+  (when (and (nnimap-change-group nil server)
             nnimap-inbox
             nnimap-split-methods)
     (nnheader-message 7 "nnimap %s splitting mail..." server)
-    (nnimap-split-incoming-mail)
+    (if (listp nnimap-inbox)
+       (dolist (nnimap-inbox nnimap-inbox)
+         (nnimap-split-incoming-mail))
+      (nnimap-split-incoming-mail))
     (nnheader-message 7 "nnimap %s splitting mail...done" server)))
 
 (defun nnimap-marks-to-flags (marks)
@@ -1031,7 +1062,7 @@ textual parts.")
 
 (deffoo nnimap-request-update-group-status (group status &optional server)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (let ((command (assoc
                    status
                    '((subscribe "SUBSCRIBE")
@@ -1042,7 +1073,7 @@ textual parts.")
 
 (deffoo nnimap-request-set-mark (group actions &optional server)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group group server)
+  (when (nnimap-change-group group server)
     (let (sequence)
       (with-current-buffer (nnimap-buffer)
        (erase-buffer)
@@ -1067,7 +1098,7 @@ textual parts.")
 
 (deffoo nnimap-request-accept-article (group &optional server last)
   (setq group (nnimap-decode-gnus-group group))
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (nnmail-check-syntax)
     (let ((message-id (message-field-value "message-id"))
          sequence message)
@@ -1099,7 +1130,8 @@ textual parts.")
              (cons group
                    (or (nnimap-find-uid-response "APPENDUID" (car result))
                        (nnimap-find-article-by-message-id
-                        group message-id))))))))))
+                        group server message-id
+                         nnimap-request-articles-find-limit))))))))))
 
 (defun nnimap-process-quirk (greeting-match type data)
   (when (and (nnimap-greeting nnimap-object)
@@ -1145,7 +1177,7 @@ textual parts.")
 (deffoo nnimap-request-replace-article (article group buffer)
   (setq group (nnimap-decode-gnus-group group))
   (let (group-art)
-    (when (and (nnimap-possibly-change-group group nil)
+    (when (and (nnimap-change-group group)
               ;; Put the article into the group.
               (with-current-buffer buffer
                 (setq group-art
@@ -1180,8 +1212,17 @@ textual parts.")
                groups))))
     (nreverse groups)))
 
+(defun nnimap-get-responses (sequences)
+  (let (responses)
+    (dolist (sequence sequences)
+      (goto-char (point-min))
+      (when (re-search-forward (format "^%d " sequence) nil t)
+        (push (list sequence (nnimap-parse-response))
+              responses)))
+    responses))
+
 (deffoo nnimap-request-list (&optional server)
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (with-current-buffer nntp-server-buffer
       (erase-buffer)
       (let ((groups
@@ -1228,7 +1269,7 @@ textual parts.")
          t)))))
 
 (deffoo nnimap-request-newgroups (date &optional server)
-  (when (nnimap-possibly-change-group nil server)
+  (when (nnimap-change-group nil server)
     (with-current-buffer nntp-server-buffer
       (erase-buffer)
       (dolist (group (with-current-buffer (nnimap-buffer)
@@ -1239,14 +1280,15 @@ textual parts.")
       t)))
 
 (deffoo nnimap-retrieve-group-data-early (server infos)
-  (when (and (nnimap-possibly-change-group nil server)
+  (when (and (nnimap-change-group nil server)
             infos)
     (with-current-buffer (nnimap-buffer)
       (erase-buffer)
       (setf (nnimap-group nnimap-object) nil)
       (setf (nnimap-initial-resync nnimap-object) 0)
       (let ((qresyncp (nnimap-capability "QRESYNC"))
-           params groups sequences active uidvalidity modseq group)
+           params groups sequences active uidvalidity modseq group
+           unexist)
        ;; Go through the infos and gather the data needed to know
        ;; what and how to request the data.
        (dolist (info infos)
@@ -1254,13 +1296,15 @@ textual parts.")
                group (nnimap-decode-gnus-group
                       (gnus-group-real-name (gnus-info-group info)))
                active (cdr (assq 'active params))
+               unexist (assq 'unexist (gnus-info-marks info))
                uidvalidity (cdr (assq 'uidvalidity params))
                modseq (cdr (assq 'modseq params)))
          (setf (nnimap-examined nnimap-object) group)
          (if (and qresyncp
                   uidvalidity
                   active
-                  modseq)
+                  modseq
+                  unexist)
              (push
               (list (nnimap-send-command "EXAMINE %S (%s (%s %s))"
                                          (utf7-encode group t)
@@ -1279,11 +1323,10 @@ textual parts.")
                     ;; is read-only or not.
                     "SELECT"))
                  start)
-             (if (and active uidvalidity)
+             (if (and active uidvalidity unexist)
                  ;; Fetch the last 100 flags.
                  (setq start (max 1 (- (cdr active) 100)))
-               (setf (nnimap-initial-resync nnimap-object)
-                     (1+ (nnimap-initial-resync nnimap-object)))
+               (incf (nnimap-initial-resync nnimap-object))
                (setq start 1))
              (push (list (nnimap-send-command "%s %S" command
                                               (utf7-encode group t))
@@ -1303,7 +1346,7 @@ textual parts.")
 
 (deffoo nnimap-finish-retrieve-group-infos (server infos sequences)
   (when (and sequences
-            (nnimap-possibly-change-group nil server t)
+            (nnimap-change-group nil server t)
             ;; Check that the process is still alive.
             (get-buffer-process (nnimap-buffer))
             (memq (process-status (get-buffer-process (nnimap-buffer)))
@@ -1462,6 +1505,25 @@ textual parts.")
                      (setq new-marks (gnus-range-nconcat old-marks new-marks)))
                    (when new-marks
                      (push (cons (car type) new-marks) marks)))))
+             ;; Keep track of non-existing articles.
+             (let* ((old-unexists (assq 'unexist marks))
+                    (active (gnus-active group))
+                    (unexists
+                     (if completep
+                         (gnus-range-difference
+                          active
+                          (gnus-compress-sequence existing))
+                       (gnus-add-to-range
+                        (cdr old-unexists)
+                        (gnus-list-range-difference
+                         existing (gnus-active group))))))
+               (when (> (car active) 1)
+                 (setq unexists (gnus-range-add
+                                 (cons 1 (1- (car active)))
+                                 unexists)))
+               (if old-unexists
+                   (setcdr old-unexists unexists)
+                 (push (cons 'unexist unexists) marks)))
              (gnus-info-set-marks info marks t))))
        ;; Tell Gnus whether there are any \Recent messages in any of
        ;; the groups.
@@ -1505,6 +1567,14 @@ textual parts.")
                      (gnus-sorted-complement existing new-marks))))
        (when ticks
          (push (cons (car type) ticks) marks)))
+      (gnus-info-set-marks info marks t))
+    ;; Add vanished to the list of unexisting articles.
+    (when vanished
+      (let* ((old-unexists (assq 'unexist marks))
+            (unexists (gnus-range-add (cdr old-unexists) vanished)))
+       (if old-unexists
+           (setcdr old-unexists unexists)
+         (push (cons 'unexist unexists) marks)))
       (gnus-info-set-marks info marks t))))
 
 (defun nnimap-imap-ranges-to-gnus-ranges (irange)
@@ -1642,7 +1712,7 @@ textual parts.")
   (setq nnimap-status-string "Read-only server")
   nil)
 
-(defvar gnus-refer-thread-use-nnir)    ; gnus-sum
+(defvar gnus-refer-thread-use-nnir) ;; gnus-sum.el
 (declare-function gnus-fetch-headers "gnus-sum"
                  (articles &optional limit force-new dependencies))
 
@@ -1653,7 +1723,7 @@ textual parts.")
     (setq group (nnimap-decode-gnus-group group)))
   (if gnus-refer-thread-use-nnir
       (nnir-search-thread header)
-    (when (nnimap-possibly-change-group group server)
+    (when (nnimap-change-group group server)
       (let* ((cmd (nnimap-make-thread-query header))
              (result (with-current-buffer (nnimap-buffer)
                        (nnimap-command  "UID SEARCH %s" cmd))))
@@ -1664,7 +1734,14 @@ textual parts.")
                                  (cdr (assoc "SEARCH" (cdr result))))))
            nil t))))))
 
-(defun nnimap-possibly-change-group (group server &optional no-reconnect)
+(defun nnimap-change-group (group &optional server no-reconnect read-only)
+  "Change group to GROUP if non-nil.
+If SERVER is set, check that server is connected, otherwise retry
+to reconnect, unless NO-RECONNECT is set to t.  Return nil if
+unsuccessful in connecting.
+If GROUP is nil, return t.
+If READ-ONLY is set, send EXAMINE rather than SELECT to the server.
+Return the server's response to the SELECT or EXAMINE command."
   (let ((open-result t))
     (when (and server
               (not (nnimap-server-opened server)))
@@ -1676,13 +1753,15 @@ textual parts.")
       t)
      (t
       (with-current-buffer (nnimap-buffer)
-       (if (equal group (nnimap-group nnimap-object))
-           t
-         (let ((result (nnimap-command "SELECT %S" (utf7-encode group t))))
-           (when (car result)
-             (setf (nnimap-group nnimap-object) group
-                   (nnimap-select-result nnimap-object) result)
-             result))))))))
+        (let ((result (nnimap-command "%s %S"
+                                      (if read-only
+                                          "EXAMINE"
+                                        "SELECT")
+                                      (utf7-encode group t))))
+          (when (car result)
+            (setf (nnimap-group nnimap-object) group
+                  (nnimap-select-result nnimap-object) result)
+            result)))))))
 
 (defun nnimap-find-connection (buffer)
   "Find the connection delivering to BUFFER."
@@ -1718,15 +1797,24 @@ textual parts.")
 (defvar nnimap-record-commands nil
   "If non-nil, log commands to the \"*imap log*\" buffer.")
 
+(defun nnimap-log-buffer ()
+  (let ((name "*imap log*"))
+    (or (get-buffer name)
+        (with-current-buffer (get-buffer-create name)
+          (when (boundp 'window-point-insertion-type)
+            (make-local-variable 'window-point-insertion-type)
+            (setq window-point-insertion-type t))
+          (current-buffer)))))
+
 (defun nnimap-log-command (command)
   (when nnimap-record-commands
-    (with-current-buffer (get-buffer-create "*imap log*")
+    (with-current-buffer (nnimap-log-buffer)
       (goto-char (point-max))
       (insert (format-time-string "%H:%M:%S")
-             " [" nnimap-address "] "
-             (if nnimap-inhibit-logging
-                 "(inhibited)\n"
-               command))))
+              " [" nnimap-address "] "
+              (if nnimap-inhibit-logging
+                  "(inhibited)\n"
+                command))))
   command)
 
 (defun nnimap-command (&rest args)
@@ -1865,15 +1953,6 @@ textual parts.")
          (forward-line 1)))
       (buffer-substring (point) end))))
 
-(defun nnimap-get-responses (sequences)
-  (let (responses)
-    (dolist (sequence sequences)
-      (goto-char (point-min))
-      (when (re-search-forward (format "^%d " sequence) nil t)
-       (push (list sequence (nnimap-parse-response))
-             responses)))
-    responses))
-
 (defvar nnimap-incoming-split-list nil)
 
 (defun nnimap-fetch-inbox (articles)
index 120149ae0fbdbf453ba679274f07d7022f61fd5e..22dee30e8fadb02bf6b4288f9912f126d42a113a 100644 (file)
@@ -288,7 +288,7 @@ is `(valuefunc member)'."
 (eval-when-compile
   (autoload 'nnimap-buffer "nnimap")
   (autoload 'nnimap-command "nnimap")
-  (autoload 'nnimap-possibly-change-group "nnimap")
+  (autoload 'nnimap-change-group "nnimap")
   (autoload 'nnimap-make-thread-query "nnimap")
   (autoload 'gnus-registry-action "gnus-registry")
   (autoload 'gnus-registry-get-id-key "gnus-registry")
@@ -973,7 +973,7 @@ details on the language and supported extensions."
           #'(lambda (group)
             (let (artlist)
               (condition-case ()
-                  (when (nnimap-possibly-change-group
+                  (when (nnimap-change-group
                          (gnus-group-short-name group) server)
                     (with-current-buffer (nnimap-buffer)
                       (message "Searching %s..." group)