Mercurial > emacs
diff lisp/gnus/nnimap.el @ 110486:1ad1adb298a3
Merge Changes made in Gnus trunk.
gnus-html.el (gnus-html-get-image-data): Search also for \r\n\r\n to get the start of data.
gnus-html.el: Use gnus-html-encode-url to encode URL.
gnus-sum.el (gnus-update-marks): Add sanity check to not delete marks outside the active range.
gnus.el: Try to keep the server/method cache unique.
gnus-html.el (gnus-html-rescale-image): Use window-inside-pixel-edges rather than window-pixel-edges.
gnus-html.el (gnus-html-put-image): Stop using markers.
gnus-html.el (gnus-html-image-fetched): Search also for \r\n\r\n to get the start of data.
nnimap.el: Expunge IMAP groups by default on article deletion.
gnus-int.el (gnus-request-expire-articles): Inhibit the daemon, since this command might take a while.
nnimap.el (nnimap-request-list): Set the current nnimap group to nil, since EXAMINE changes it on the server.
nnmail.el, nnimap.el: Allow nnimap to just delete 'junk messages when splitting.
nnimap.el (nnimap-parse-flags): Make IMAP flags parsing much faster by using `read'.
nnimap.el (nnimap-make-process-buffer): Record the server name.
gnus-html.el (gnus-html-image-fetched): Only cache if gnus-html-image-automatic-caching is set.
gnus-html.el (gnus-html-image-fetched): Check for errors.
gnus-start.el (gnus-read-active-for-groups): Only run -request-scan once per method on `g'.
nnimap.el (nnimap-request-expire-articles): If nnmail-expiry-wait is immediate, then expire all articles.
gnus-group.el (gnus-group-get-icon): Compute icon to return.
gnus-group.el (gnus-group-icon-list): Fix bad docstring information.
nnimap.el (nnimap-update-info): Fix up various off-by-one errors when syncing flags in nnimap.
time-date.el (date-to-time): Speed up date-to-time.
gnus-start.el (gnus-get-unread-articles): Don't have `gnus-get-unread-articles-in-group' update info.
gnus-group.el: Remove gnus-group-highlight-line from the default hook list.
gnus-group.el (gnus-group-highlight-line): Typo fix: beg, not start.
gnus-group.el (gnus-group-insert-group-line): Pass the real group name so that it gets the right data.
gnus-int.el (gnus-open-server): Add tracing for performance debugging.
nnimap.el (nnimap-parse-flags): Parse the data in any order.
nnimap.el (nnimap-update-info): Fix up code slightly.
author | Katsumi Yamaoka <yamaoka@jpl.org> |
---|---|
date | Thu, 23 Sep 2010 00:30:37 +0000 |
parents | 437c7aaf08fd |
children | 4ead2c32359c |
line wrap: on
line diff
--- a/lisp/gnus/nnimap.el Thu Sep 23 01:14:00 2010 +0200 +++ b/lisp/gnus/nnimap.el Thu Sep 23 00:30:37 2010 +0000 @@ -62,11 +62,6 @@ (defvoo nnimap-inbox nil "The mail box where incoming mail arrives and should be split out of.") -(defvoo nnimap-expunge-inbox nil - "If non-nil, expunge the inbox after fetching mail. -This is always done if the server supports UID EXPUNGE, but it's -not done by default on servers that doesn't support that command.") - (defvoo nnimap-authenticator nil "How nnimap authenticate itself to the server. Possible choices are nil (use default methods) or `anonymous'.") @@ -78,7 +73,11 @@ likely value would be \"text/\" to automatically fetch all textual parts.") -(defvoo nnimap-expunge nil) +(defvoo nnimap-expunge t + "If non-nil, expunge articles after deleting them. +This is always done if the server supports UID EXPUNGE, but it's +not done by default on servers that doesn't support that command.") + (defvoo nnimap-connection-alist nil) @@ -92,14 +91,14 @@ "Internal variable with default value for `nnimap-split-download-body'.") (defstruct nnimap - group process commands capabilities select-result newlinep) + group process commands capabilities select-result newlinep server) (defvar nnimap-object nil) (defvar nnimap-mark-alist - '((read "\\Seen") - (tick "\\Flagged") - (reply "\\Answered") + '((read "\\Seen" %Seen) + (tick "\\Flagged" %Flagged) + (reply "\\Answered" %Answered) (expire "gnus-expire") (dormant "gnus-dormant") (score "gnus-score") @@ -213,7 +212,8 @@ (buffer-disable-undo) (gnus-add-buffer) (set (make-local-variable 'after-change-functions) nil) - (set (make-local-variable 'nnimap-object) (make-nnimap)) + (set (make-local-variable 'nnimap-object) + (make-nnimap :server (nnoo-current-server 'nnimap))) (push (list buffer (current-buffer)) nnimap-connection-alist) (current-buffer))) @@ -421,8 +421,9 @@ (goto-char (point-max)) (cond (marks - (setq high (nth 3 (car marks)) - low (nth 4 (car marks)))) + (let ((uidnext (nth 5 (car marks)))) + (setq high (or (nth 3 (car marks)) (1- uidnext)) + low (or (nth 4 (car marks)) uidnext)))) ((re-search-backward "UIDNEXT \\([0-9]+\\)" nil t) (setq high (1- (string-to-number (match-string 1))) low 1))))) @@ -502,7 +503,8 @@ nil) (t (let ((deletable-articles - (if force + (if (or force + (eq nnmail-expiry-wait 'immediate)) articles (gnus-sorted-intersection articles @@ -587,9 +589,9 @@ (deffoo nnimap-request-scan (&optional group server) (when (and (nnimap-possibly-change-group nil server) - (equal group nnimap-inbox) nnimap-inbox nnimap-split-methods) + (message "nnimap %s splitting mail..." server) (nnimap-split-incoming-mail))) (defun nnimap-marks-to-flags (marks) @@ -667,6 +669,7 @@ sequences responses) (when groups (with-current-buffer (nnimap-buffer) + (setf (nnimap-group nnimap-object) nil) (dolist (group groups) (push (list (nnimap-send-command "EXAMINE %S" (utf7-encode group t)) group) @@ -716,6 +719,7 @@ groups)) ;; Then request the data. (erase-buffer) + (setf (nnimap-group nnimap-object) nil) (dolist (elem groups) (if (and qresyncp (nth 2 elem)) @@ -773,7 +777,8 @@ (defun nnimap-update-info (info marks) (when marks - (destructuring-bind (existing flags high low uidnext start-article) marks + (destructuring-bind (existing flags high low uidnext start-article + permanent-flags) marks (let ((group (gnus-info-group info)) (completep (and start-article (= start-article 1)))) @@ -784,16 +789,18 @@ (if high (cons low high) ;; No articles in this group. - (cons (1- uidnext) uidnext))) - (setcdr (gnus-active group) high)) + (cons uidnext (1- uidnext)))) + (setcdr (gnus-active group) (or high (1- uidnext)))) + (unless high + (setq high (1- uidnext))) ;; Then update the list of read articles. (let* ((unread (gnus-compress-sequence (gnus-set-difference (gnus-set-difference existing - (cdr (assoc "\\Seen" flags))) - (cdr (assoc "\\Flagged" flags))))) + (cdr (assoc '%Seen flags))) + (cdr (assoc '%Flagged flags))))) (read (gnus-range-difference (cons start-article high) unread))) (when (> start-article 1) @@ -815,8 +822,10 @@ (push (cons 'active (gnus-active group)) marks))) (dolist (type (cdr nnimap-mark-alist)) (let ((old-marks (assoc (car type) marks)) - (new-marks (gnus-compress-sequence - (cdr (assoc (cadr type) flags))))) + (new-marks + (gnus-compress-sequence + (cdr (or (assoc (caddr type) flags) ; %Flagged + (assoc (cadr type) flags)))))) ; "\Flagged" (setq marks (delq old-marks marks)) (pop old-marks) (when (and old-marks @@ -838,12 +847,13 @@ (push (list group info active) nnimap-current-infos)))) (defun nnimap-flags-to-marks (groups) - (let (data group totalp uidnext articles start-article mark) + (let (data group totalp uidnext articles start-article mark permanent-flags) (dolist (elem groups) (setq group (car elem) - uidnext (cadr elem) - start-article (caddr elem) - articles (cdddr elem)) + uidnext (nth 1 elem) + start-article (nth 2 elem) + permanent-flags (nth 3 elem) + articles (nthcdr 4 elem)) (let ((high (caar articles)) marks low existing) (dolist (article articles) @@ -853,36 +863,49 @@ (setq mark (assoc flag marks)) (if (not mark) (push (list flag (car article)) marks) - (setcdr mark (cons (car article) (cdr mark))))) - (push (list group existing marks high low uidnext start-article) - data)))) + (setcdr mark (cons (car article) (cdr mark)))))) + (push (list group existing marks high low uidnext start-article + permanent-flags) + data))) data)) (defun nnimap-parse-flags (sequences) (goto-char (point-min)) - (let (start end articles groups uidnext elems) + ;; Change \Delete etc to %Delete, so that the reader can read it. + (subst-char-in-region (point-min) (point-max) + ?\\ ?% t) + (let (start end articles groups uidnext elems permanent-flags) (dolist (elem sequences) (destructuring-bind (group-sequence flag-sequence totalp group) elem + (setq start (point)) ;; The EXAMINE was successful. (when (and (search-forward (format "\n%d OK " group-sequence) nil t) (progn (forward-line 1) - (setq start (point)) - (if (re-search-backward "UIDNEXT \\([0-9]+\\)" - (or end (point-min)) t) - (setq uidnext (string-to-number (match-string 1))) - (setq uidnext nil)) - (goto-char start)) + (setq end (point)) + (goto-char start) + (setq permanent-flags + (and (search-forward "PERMANENTFLAGS " + (or end (point-min)) t) + (read (current-buffer)))) + (goto-char start) + (setq uidnext + (and (search-forward "UIDNEXT " + (or end (point-min)) t) + (read (current-buffer)))) + (goto-char end) + (forward-line -1)) ;; The UID FETCH FLAGS was successful. (search-forward (format "\n%d OK " flag-sequence) nil t)) - (setq end (point)) - (goto-char start) - (while (re-search-forward "^\\* [0-9]+ FETCH (\\(.*\\))" end t) - (setq elems (nnimap-parse-line (match-string 1))) - (push (cons (string-to-number (cadr (member "UID" elems))) - (cadr (member "FLAGS" elems))) + (setq start (point)) + (goto-char end) + (while (search-forward " FETCH " start t) + (setq elems (read (current-buffer))) + (push (cons (cadr (memq 'UID elems)) + (cadr (memq 'FLAGS elems))) articles)) - (push (nconc (list group uidnext totalp) articles) groups) + (push (nconc (list group uidnext totalp permanent-flags) articles) + groups) (setq articles nil)))) groups)) @@ -1085,32 +1108,38 @@ (nnmail-split-incoming (current-buffer) #'nnimap-save-mail-spec nil nil - #'nnimap-dummy-active-number) + #'nnimap-dummy-active-number + #'nnimap-save-mail-spec) (when nnimap-incoming-split-list (let ((specs (nnimap-make-split-specs nnimap-incoming-split-list)) - sequences) + sequences junk-articles) ;; Create any groups that doesn't already exist on the ;; server first. (dolist (spec specs) - (unless (member (car spec) groups) + (when (and (not (member (car spec) groups)) + (not (eq (car spec) 'junk))) (nnimap-command "CREATE %S" (utf7-encode (car spec) t)))) ;; Then copy over all the messages. (erase-buffer) (dolist (spec specs) (let ((group (car spec)) (ranges (cdr spec))) - (push (list (nnimap-send-command "UID COPY %s %S" - (nnimap-article-ranges ranges) - (utf7-encode group t)) - ranges) - sequences))) + (if (eq group 'junk) + (setq junk-articles ranges) + (push (list (nnimap-send-command + "UID COPY %s %S" + (nnimap-article-ranges ranges) + (utf7-encode group t)) + ranges) + sequences)))) ;; Wait for the last COPY response... (when sequences (nnimap-wait-for-response (caar sequences)) ;; And then mark the successful copy actions as deleted, ;; and possibly expunge them. (nnimap-mark-and-expunge-incoming - (nnimap-parse-copied-articles sequences))))))))) + (nnimap-parse-copied-articles sequences)) + (nnimap-mark-and-expunge-incoming junk-articles)))))))) (defun nnimap-mark-and-expunge-incoming (range) (when range @@ -1125,7 +1154,7 @@ (setq sequence (nnimap-send-command "UID EXPUNGE %s" range))) ;; If it doesn't support UID EXPUNGE, then we only expunge if the ;; user has configured it. - (nnimap-expunge-inbox + (nnimap-expunge (setq sequence (nnimap-send-command "EXPUNGE")))) (nnimap-wait-for-response sequence)))) @@ -1142,8 +1171,8 @@ (let (new) (dolist (elem flags) (when (or (null (cdr elem)) - (and (not (member "\\Deleted" (cdr elem))) - (not (member "\\Seen" (cdr elem))))) + (and (not (memq '%Deleted (cdr elem))) + (not (memq '%Seen (cdr elem))))) (push (car elem) new))) (gnus-compress-sequence (nreverse new)))) @@ -1190,7 +1219,10 @@ (if (not (re-search-forward "X-nnimap-article: \\([0-9]+\\)" nil t)) (error "Invalid nnimap mail") (setq article (string-to-number (match-string 1)))) - (push (list article group-art) + (push (list article + (if (eq group-art 'junk) + (list (cons 'junk 1)) + group-art)) nnimap-incoming-split-list))) (provide 'nnimap)