Merge changes made in Gnus trunk

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.
This commit is contained in:
Katsumi Yamaoka 2013-07-02 10:38:58 +00:00
parent 646b949918
commit eaa610c3b4
9 changed files with 371 additions and 95 deletions

View 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.

View 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

View 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

View 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))

View 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."

View 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)

View 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

View 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)

View 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)