second is a regexp that nnimap will try to match on the header to find
a fit.
-The first element can also be a list. In that case, the first element
-is the server the second element is the group on that server in which
-the matching article will be stored.
-
The second element can also be a function. In that case, it will be
called narrowed to the headers with the first element of the rule as
the argument. It should return a non-nil value if it thinks that the
This variable can also have a function as its value, the function will
be called with the headers narrowed and should return a group where it
-thinks the article should be splitted to.")
+thinks the article should be splitted to. See `nnimap-split-fancy'.
+
+To allow for different split rules on different virtual servers, and
+even different split rules in different inboxes on the same server,
+the syntax of this variable have been extended along the lines of:
+
+(setq nnimap-split-rule
+ '((\"my1server\" (\".*\" ((\"ding\" \"ding@gnus.org\")
+ (\"junk\" \"From:.*Simon\")))
+ (\"my2server\" (\"INBOX\" nnimap-split-fancy))
+ (\"my[34]server\" (\".*\" ((\"private\" \"To:.*Simon\")
+ (\"junk\" my-junk-func)))))
+
+The virtual server name is in fact a regexp, so that the same rules
+may apply to several servers. In the example, the servers
+\"my3server\" and \"my4server\" both use the same rules. Similarly,
+the inbox string is also a regexp. The actual splitting rules are as
+before, either a function, or a list with group/regexp or
+group/function elements.")
(defvar nnimap-split-predicate "UNSEEN UNDELETED"
"The predicate used to find articles to split.
;; Internal variables:
-(defvar nnimap-debug nil);; "*nnimap-debug*")
+(defvar nnimap-debug nil
+ "Name of buffer to record debugging info.
+For example: (setq nnimap-debug \"*nnimap-debug*\")")
(defvar nnimap-current-move-server nil)
(defvar nnimap-current-move-group nil)
(defvar nnimap-current-move-article nil)
(gnus-group-add-parameter gnusgroup (cons 'uidvalidity new-uidvalidity))
t)))
+(defun nnimap-before-find-minmax-bugworkaround ()
+ "Function called before iterating through mailboxes with
+`nnimap-find-minmax-uid'."
+ ;; XXX this is for UoW imapd problem, it doesn't notice new mail in
+ ;; currently selected mailbox without a re-select/examine.
+ (or (null (imap-current-mailbox nnimap-server-buffer))
+ (imap-mailbox-unselect nnimap-server-buffer)))
+
(defun nnimap-find-minmax-uid (group &optional examine)
"Find lowest and highest active article nummber in GROUP.
If EXAMINE is non-nil the group is selected read-only."
(if (numberp (car-safe articles))
(imap-search
(concat "UID "
- (nnimap-range-to-string
+ (imap-range-to-message-set
(gnus-compress-sequence
(append (gnus-uncompress-sequence
(and fetch-old
(let ((imap-fetch-data-hook '(nnimap-retrieve-headers-progress))
(nnimap-length (gnus-range-length articles))
(nnimap-counter 0))
- (imap-fetch (nnimap-range-to-string articles)
+ (imap-fetch (imap-range-to-message-set articles)
(concat "(UID RFC822.SIZE BODY "
(let ((headers
(append '(Subject From Date Message-Id
(imap-capability 'IMAP4rev1 nnimap-server-buffer))
(imap-close nnimap-server-buffer)
(nnheader-report 'nnimap "Server %s is not IMAP4 compliant" server))
- (let (list alist user passwd)
- (and (fboundp 'gnus-parse-netrc)
- (setq list (gnus-parse-netrc nnimap-authinfo-file)
- alist (or (and (gnus-netrc-get
- (gnus-netrc-machine list server) "machine")
- (gnus-netrc-machine list server))
- (gnus-netrc-machine list nnimap-address))
- user (gnus-netrc-get alist "login")
- passwd (gnus-netrc-get alist "password")))
+ (let* ((list (gnus-parse-netrc nnimap-authinfo-file))
+ (port (if nnimap-server-port
+ (int-to-string nnimap-server-port)
+ "imap"))
+ (alist (gnus-netrc-machine list (or nnimap-server-address
+ nnimap-address server)
+ port "imap"))
+ (user (gnus-netrc-get alist "login"))
+ (passwd (gnus-netrc-get alist "password")))
(if (imap-authenticate user passwd nnimap-server-buffer)
(prog1
(push (list server nnimap-server-buffer)
(with-current-buffer nnimap-callback-buffer
(insert
(with-current-buffer nnimap-server-buffer
- (nnimap-demule
- (if (imap-capability 'IMAP4rev1)
- ;; xxx don't just use car? alist doesn't contain
- ;; anything else now, but it might...
- (nth 2 (car (imap-message-get (imap-current-message) 'BODYDETAIL)))
- (imap-message-get (imap-current-message) 'RFC822)))))
+ (if (imap-capability 'IMAP4rev1)
+ ;; xxx don't just use car? alist doesn't contain
+ ;; anything else now, but it might...
+ (nth 2 (car (imap-message-get (imap-current-message) 'BODYDETAIL)))
+ (imap-message-get (imap-current-message) 'RFC822))))
(nnheader-ms-strip-cr)
(funcall nnimap-callback-callback-function t)))
nnimap-server-buffer))
article)))
(when article
- (gnus-message 9 "nnimap: Fetching (part of) article %d..." article)
+ (gnus-message 10 "nnimap: Fetching (part of) article %d..." article)
(if (not nnheader-callback-function)
(with-current-buffer (or to-buffer nntp-server-buffer)
(erase-buffer)
(let ((data (imap-fetch article part prop nil
nnimap-server-buffer)))
(when data
- (insert (nnimap-demule (if detail
- (nth 2 (car data))
- data)))
+ (insert (if detail (nth 2 (car data)) data))
(nnheader-ms-strip-cr)
- (gnus-message 9
+ (gnus-message 10
"nnimap: Fetching (part of) article %d...done"
article)
(if (bobp)
group (gnus-server-to-method (format "nnimap:%s" server))))
server)
(when (nnimap-possibly-change-group group server)
+ (nnimap-before-find-minmax-bugworkaround)
(let (info)
(cond (fast group)
((null (setq info (nnimap-find-minmax-uid group t)))
(erase-buffer))
(gnus-message 5 "nnimap: Generating active list%s..."
(if (> (length server) 0) (concat " for " server) ""))
+ (nnimap-before-find-minmax-bugworkaround)
(with-current-buffer nnimap-server-buffer
(dolist (pattern (nnimap-pattern-to-list-arguments nnimap-list-pattern))
(dolist (mbx (funcall nnimap-request-list-method
(gnus-message 5 "nnimap: Checking mailboxes...")
(with-current-buffer nntp-server-buffer
(erase-buffer)
+ (nnimap-before-find-minmax-bugworkaround)
(dolist (group groups)
(gnus-message 7 "nnimap: Checking mailbox %s" group)
(or (member "\\NoSelect"
(when (and range marks)
(cond ((eq what 'del)
(imap-message-flags-del
- (nnimap-range-to-string range)
+ (imap-range-to-message-set range)
(nnimap-mark-to-flag marks nil t)))
((eq what 'add)
(imap-message-flags-add
- (nnimap-range-to-string range)
+ (imap-range-to-message-set range)
(nnimap-mark-to-flag marks nil t)))
((eq what 'set)
(imap-message-flags-set
- (nnimap-range-to-string range)
+ (imap-range-to-message-set range)
(nnimap-mark-to-flag marks nil t)))))))
(gnus-message 7 "nnimap: Setting marks in %s...done" group))))
nil)
(or nnimap-split-crosspost
(throw 'split-done to-groups))))))))))
+(defun nnimap-assoc-match (key alist)
+ (let (element)
+ (while (and alist (not element))
+ (if (string-match (car (car alist)) key)
+ (setq element (car alist)))
+ (setq alist (cdr alist)))
+ element))
+
(defun nnimap-split-find-rule (server inbox)
- nnimap-split-rule)
+ (if (and (listp nnimap-split-rule) (listp (car nnimap-split-rule))
+ (list (cdar nnimap-split-rule)) (listp (cadar nnimap-split-rule)))
+ ;; extended format
+ (cadr (nnimap-assoc-match inbox (cdr (nnimap-assoc-match
+ server nnimap-split-rule))))
+ nnimap-split-rule))
(defun nnimap-split-find-inbox (server)
(if (listp nnimap-split-inbox)
(gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s..."
(if (> (length server) 0) " on " "") server)
(erase-buffer)
+ (nnimap-before-find-minmax-bugworkaround)
(dolist (pattern (nnimap-pattern-to-list-arguments
nnimap-list-pattern))
(dolist (mbx (imap-mailbox-lsub "*" (car pattern) nil
(with-current-buffer nnimap-server-buffer
(if force
(and (imap-message-flags-add
- (nnimap-range-to-string artseq) "\\Deleted")
+ (imap-range-to-message-set artseq) "\\Deleted")
(setq articles nil))
(let ((days (or (and nnmail-expiry-wait-function
(funcall nnmail-expiry-wait-function group))
nnmail-expiry-wait)))
(cond ((eq days 'immediate)
(and (imap-message-flags-add
- (nnimap-range-to-string artseq) "\\Deleted")
+ (imap-range-to-message-set artseq) "\\Deleted")
(setq articles nil)))
((numberp days)
(let ((oldarts (imap-search
(format "UID %s NOT SINCE %s"
- (nnimap-range-to-string artseq)
+ (imap-range-to-message-set artseq)
(nnimap-date-days-ago days))))
(imap-fetch-data-hook
'(nnimap-request-expire-articles-progress)))
(and oldarts
(imap-message-flags-add
- (nnimap-range-to-string
+ (imap-range-to-message-set
(gnus-compress-sequence oldarts))
"\\Deleted")
(setq articles (gnus-set-difference
(cons (cons key value) (nnimap-remassoc key alist))
(nnimap-remassoc key alist)))
-(defun nnimap-range-to-string (range)
- (mapconcat
- (lambda (item)
- (if (consp item)
- (format "%d:%d"
- (car item) (cdr item))
- (format "%d" item)))
- (if (and (listp range) (not (listp (cdr range))))
- (list range);; make (1 . 2) into ((1 . 2))
- range)
- ","))
-
(when nnimap-debug
(require 'trace)
(buffer-disable-undo (get-buffer-create nnimap-debug))
nnimap-possibly-change-server
nnimap-verify-uidvalidity
nnimap-find-minmax-uid
+ nnimap-before-find-minmax-bugworkaround
nnimap-possibly-change-group
;;nnimap-replace-whitespace
nnimap-retrieve-headers-progress
nnimap-mark-permanent-p
nnimap-remassoc
nnimap-update-alist-soft
- nnimap-range-to-string
)))
(provide 'nnimap)