diff options
| author | Gnus developers | 2010-10-10 00:15:21 +0000 |
|---|---|---|
| committer | Katsumi Yamaoka | 2010-10-10 00:15:21 +0000 |
| commit | f7aa248a5b1ce15ac2a3b70b4a55833d9d1eb44b (patch) | |
| tree | b99adc70fa490b39906ab483b5478066d81d149a | |
| parent | e836e5cd0462864de01c9873a327169f7706bd3a (diff) | |
| download | emacs-f7aa248a5b1ce15ac2a3b70b4a55833d9d1eb44b.tar.gz emacs-f7aa248a5b1ce15ac2a3b70b4a55833d9d1eb44b.zip | |
Merge changes made in Gnus trunk.
nnimap.el (nnimap-open-connection): If we have gnutls loaded, then try to use that for the tls stream.
nnimap.el (nnimap-retrieve-group-data-early): Rework the marks code to heed UIDVALIDITY and find out which groups are read-only and not.
nnimap.el (nnimap-get-flags): Use the same marks parsing code as the rest of nnimap.
nnimap.el (nnmail-expiry-target-group): Say that every expiry target group is the "last".
nnir.el (nnir-engines): Fix too many arguments.
nnimap.el: Start implementing QRESYNC support.
gnus.el (gnus-group-set-parameter): Fix typo.
shr.el: Rework the way things are indented by <li> slightly.
spam.el (gnus-summary-mode-map): Bind to "$".
| -rw-r--r-- | doc/misc/ChangeLog | 4 | ||||
| -rw-r--r-- | doc/misc/gnus.texi | 10 | ||||
| -rw-r--r-- | lisp/gnus/ChangeLog | 28 | ||||
| -rw-r--r-- | lisp/gnus/gnus.el | 22 | ||||
| -rw-r--r-- | lisp/gnus/nnimap.el | 355 | ||||
| -rw-r--r-- | lisp/gnus/nnir.el | 1 | ||||
| -rw-r--r-- | lisp/gnus/nnmail.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/shr.el | 14 | ||||
| -rw-r--r-- | lisp/gnus/spam.el | 3 |
9 files changed, 294 insertions, 145 deletions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index b3c52d5c36a..d54b3875edf 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog | |||
| @@ -1,3 +1,7 @@ | |||
| 1 | 2010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * gnus.texi (Spam Package Introduction): Mention `$'. | ||
| 4 | |||
| 1 | 2010-10-09 Eli Zaretskii <eliz@gnu.org> | 5 | 2010-10-09 Eli Zaretskii <eliz@gnu.org> |
| 2 | 6 | ||
| 3 | * makefile.w32-in (emacsdir): New variable. | 7 | * makefile.w32-in (emacsdir): New variable. |
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 4b3defaa4a3..1a1f0d48eb9 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi | |||
| @@ -23750,12 +23750,14 @@ yourself, so that the message is processed as spam when you exit the | |||
| 23750 | group: | 23750 | group: |
| 23751 | 23751 | ||
| 23752 | @table @kbd | 23752 | @table @kbd |
| 23753 | @item M-d | 23753 | @item $ |
| 23754 | @itemx M-d | ||
| 23754 | @itemx M s x | 23755 | @itemx M s x |
| 23755 | @itemx S x | 23756 | @itemx S x |
| 23756 | @kindex M-d | 23757 | @kindex $ (Summary) |
| 23757 | @kindex S x | 23758 | @kindex M-d (Summary) |
| 23758 | @kindex M s x | 23759 | @kindex S x (Summary) |
| 23760 | @kindex M s x (Summary) | ||
| 23759 | @findex gnus-summary-mark-as-spam | 23761 | @findex gnus-summary-mark-as-spam |
| 23760 | @findex gnus-summary-mark-as-spam | 23762 | @findex gnus-summary-mark-as-spam |
| 23761 | Mark current article as spam, showing it with the @samp{$} mark | 23763 | Mark current article as spam, showing it with the @samp{$} mark |
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 7947aff31bc..3b2a61e3d3d 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,31 @@ | |||
| 1 | 2010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * spam.el (gnus-summary-mode-map): Bind to "$". Suggested by Russ | ||
| 4 | Allbery. | ||
| 5 | |||
| 6 | * shr.el: Rework the way things are indented by <li> slightly. | ||
| 7 | |||
| 8 | * gnus.el (gnus-group-set-parameter): Fix typo. | ||
| 9 | |||
| 10 | * nnimap.el: Start implementing QRESYNC support. | ||
| 11 | |||
| 12 | 2010-10-09 Julien Danjou <julien@danjou.info> | ||
| 13 | |||
| 14 | * nnir.el (nnir-engines): Fix too many arguments. | ||
| 15 | |||
| 16 | 2010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 17 | |||
| 18 | * nnmail.el (nnmail-expiry-target-group): Say that every expiry target | ||
| 19 | group is the "last", so that the backends like nnfolder actually save | ||
| 20 | their folders. | ||
| 21 | |||
| 22 | * nnimap.el (nnimap-open-connection): If we have gnutls loaded, then | ||
| 23 | try to use that for the tls stream. | ||
| 24 | (nnimap-retrieve-group-data-early): Rework the marks code to heed | ||
| 25 | UIDVALIDITY and find out which groups are read-only and not. | ||
| 26 | (nnimap-get-flags): Use the same marks parsing code as the rest of | ||
| 27 | nnimap. | ||
| 28 | |||
| 1 | 2010-10-09 Julien Danjou <julien@danjou.info> | 29 | 2010-10-09 Julien Danjou <julien@danjou.info> |
| 2 | 30 | ||
| 3 | * nnir.el (nnir-read-parm): Fix call to gnus-completing-read. | 31 | * nnir.el (nnir-read-parm): Fix call to gnus-completing-read. |
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index f6ffdf64ffb..d4bbfe129c4 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el | |||
| @@ -3391,14 +3391,14 @@ that that variable is buffer-local to the summary buffers." | |||
| 3391 | (defun gnus-news-group-p (group &optional article) | 3391 | (defun gnus-news-group-p (group &optional article) |
| 3392 | "Return non-nil if GROUP (and ARTICLE) come from a news server." | 3392 | "Return non-nil if GROUP (and ARTICLE) come from a news server." |
| 3393 | (cond ((gnus-member-of-valid 'post group) ;Ordinary news group | 3393 | (cond ((gnus-member-of-valid 'post group) ;Ordinary news group |
| 3394 | t) ;is news of course. | 3394 | t) ;is news of course. |
| 3395 | ((not (gnus-member-of-valid 'post-mail group)) ;Non-combined. | 3395 | ((not (gnus-member-of-valid 'post-mail group)) ;Non-combined. |
| 3396 | nil) ;must be mail then. | 3396 | nil) ;must be mail then. |
| 3397 | ((vectorp article) ;Has header info. | 3397 | ((vectorp article) ;Has header info. |
| 3398 | (eq (gnus-request-type group (mail-header-id article)) 'news)) | 3398 | (eq (gnus-request-type group (mail-header-id article)) 'news)) |
| 3399 | ((null article) ;Hasn't header info | 3399 | ((null article) ;Hasn't header info |
| 3400 | (eq (gnus-request-type group) 'news)) ;(unknown ==> mail) | 3400 | (eq (gnus-request-type group) 'news)) ;(unknown ==> mail) |
| 3401 | ((< article 0) ;Virtual message | 3401 | ((< article 0) ;Virtual message |
| 3402 | nil) ;we don't know, guess mail. | 3402 | nil) ;we don't know, guess mail. |
| 3403 | (t ;Has positive number | 3403 | (t ;Has positive number |
| 3404 | (eq (gnus-request-type group article) 'news)))) ;use it. | 3404 | (eq (gnus-request-type group article) 'news)))) ;use it. |
| @@ -3923,8 +3923,11 @@ If ALLOW-LIST, also allow list as a result." | |||
| 3923 | group 'params)))) | 3923 | group 'params)))) |
| 3924 | 3924 | ||
| 3925 | (defun gnus-group-set-parameter (group name value) | 3925 | (defun gnus-group-set-parameter (group name value) |
| 3926 | "Set parameter NAME to VALUE in GROUP." | 3926 | "Set parameter NAME to VALUE in GROUP. |
| 3927 | (let ((info (gnus-get-info group))) | 3927 | GROUP can also be an INFO structure." |
| 3928 | (let ((info (if (listp group) | ||
| 3929 | group | ||
| 3930 | (gnus-get-info group)))) | ||
| 3928 | (when info | 3931 | (when info |
| 3929 | (gnus-group-remove-parameter group name) | 3932 | (gnus-group-remove-parameter group name) |
| 3930 | (let ((old-params (gnus-info-params info)) | 3933 | (let ((old-params (gnus-info-params info)) |
| @@ -3934,11 +3937,14 @@ If ALLOW-LIST, also allow list as a result." | |||
| 3934 | (not (eq (caar old-params) name))) | 3937 | (not (eq (caar old-params) name))) |
| 3935 | (setq new-params (append new-params (list (car old-params))))) | 3938 | (setq new-params (append new-params (list (car old-params))))) |
| 3936 | (setq old-params (cdr old-params))) | 3939 | (setq old-params (cdr old-params))) |
| 3937 | (gnus-group-set-info new-params group 'params))))) | 3940 | (gnus-group-set-info new-params (gnus-info-group info) 'params))))) |
| 3938 | 3941 | ||
| 3939 | (defun gnus-group-remove-parameter (group name) | 3942 | (defun gnus-group-remove-parameter (group name) |
| 3940 | "Remove parameter NAME from GROUP." | 3943 | "Remove parameter NAME from GROUP. |
| 3941 | (let ((info (gnus-get-info group))) | 3944 | GROUP can also be an INFO structure." |
| 3945 | (let ((info (if (listp group) | ||
| 3946 | group | ||
| 3947 | (gnus-get-info group)))) | ||
| 3942 | (when info | 3948 | (when info |
| 3943 | (let ((params (gnus-info-params info))) | 3949 | (let ((params (gnus-info-params info))) |
| 3944 | (when params | 3950 | (when params |
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index f8eb6659ad6..b30e5868669 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el | |||
| @@ -317,8 +317,7 @@ textual parts.") | |||
| 317 | 'starttls)) | 317 | 'starttls)) |
| 318 | '("imap")) | 318 | '("imap")) |
| 319 | ((memq nnimap-stream '(ssl tls)) | 319 | ((memq nnimap-stream '(ssl tls)) |
| 320 | (funcall (if (and nil | 320 | (funcall (if (fboundp 'open-gnutls-stream) |
| 321 | (fboundp 'open-gnutls-stream)) | ||
| 322 | 'open-gnutls-stream | 321 | 'open-gnutls-stream |
| 323 | 'open-tls-stream) | 322 | 'open-tls-stream) |
| 324 | "*nnimap*" (current-buffer) nnimap-address | 323 | "*nnimap*" (current-buffer) nnimap-address |
| @@ -338,7 +337,8 @@ textual parts.") | |||
| 338 | '(open run)))) | 337 | '(open run)))) |
| 339 | (nnheader-report 'nnimap "Unable to contact %s:%s via %s" | 338 | (nnheader-report 'nnimap "Unable to contact %s:%s via %s" |
| 340 | nnimap-address port nnimap-stream) | 339 | nnimap-address port nnimap-stream) |
| 341 | (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil) | 340 | (gnus-set-process-query-on-exit-flag |
| 341 | (nnimap-process nnimap-object) nil) | ||
| 342 | (if (not (setq connection-result (nnimap-wait-for-connection))) | 342 | (if (not (setq connection-result (nnimap-wait-for-connection))) |
| 343 | (nnheader-report 'nnimap | 343 | (nnheader-report 'nnimap |
| 344 | "%s" (buffer-substring | 344 | "%s" (buffer-substring |
| @@ -626,8 +626,10 @@ textual parts.") | |||
| 626 | (setq marks | 626 | (setq marks |
| 627 | (nnimap-flags-to-marks | 627 | (nnimap-flags-to-marks |
| 628 | (nnimap-parse-flags | 628 | (nnimap-parse-flags |
| 629 | (list (list group-sequence flag-sequence 1 group))))) | 629 | (list (list group-sequence flag-sequence |
| 630 | (when info | 630 | 1 group "SELECT"))))) |
| 631 | (when (and info | ||
| 632 | marks) | ||
| 631 | (nnimap-update-infos marks (list info))) | 633 | (nnimap-update-infos marks (list info))) |
| 632 | (goto-char (point-max)) | 634 | (goto-char (point-max)) |
| 633 | (let ((uidnext (nth 5 (car marks)))) | 635 | (let ((uidnext (nth 5 (car marks)))) |
| @@ -655,7 +657,8 @@ textual parts.") | |||
| 655 | (deffoo nnimap-request-rename-group (group new-name &optional server) | 657 | (deffoo nnimap-request-rename-group (group new-name &optional server) |
| 656 | (when (nnimap-possibly-change-group nil server) | 658 | (when (nnimap-possibly-change-group nil server) |
| 657 | (with-current-buffer (nnimap-buffer) | 659 | (with-current-buffer (nnimap-buffer) |
| 658 | (car (nnimap-command "RENAME %S %S" (utf7-encode group t) (utf7-encode new-name t)))))) | 660 | (car (nnimap-command "RENAME %S %S" |
| 661 | (utf7-encode group t) (utf7-encode new-name t)))))) | ||
| 659 | 662 | ||
| 660 | (deffoo nnimap-request-expunge-group (group &optional server) | 663 | (deffoo nnimap-request-expunge-group (group &optional server) |
| 661 | (when (nnimap-possibly-change-group group server) | 664 | (when (nnimap-possibly-change-group group server) |
| @@ -664,16 +667,19 @@ textual parts.") | |||
| 664 | 667 | ||
| 665 | (defun nnimap-get-flags (spec) | 668 | (defun nnimap-get-flags (spec) |
| 666 | (let ((articles nil) | 669 | (let ((articles nil) |
| 667 | elems) | 670 | elems end) |
| 668 | (with-current-buffer (nnimap-buffer) | 671 | (with-current-buffer (nnimap-buffer) |
| 669 | (erase-buffer) | 672 | (erase-buffer) |
| 670 | (nnimap-wait-for-response (nnimap-send-command | 673 | (nnimap-wait-for-response (nnimap-send-command |
| 671 | "UID FETCH %s FLAGS" spec)) | 674 | "UID FETCH %s FLAGS" spec)) |
| 675 | (setq end (point)) | ||
| 676 | (subst-char-in-region (point-min) (point-max) | ||
| 677 | ?\\ ?% t) | ||
| 672 | (goto-char (point-min)) | 678 | (goto-char (point-min)) |
| 673 | (while (re-search-forward "^\\* [0-9]+ FETCH (\\(.*\\))" nil t) | 679 | (while (search-forward " FETCH " end t) |
| 674 | (setq elems (nnimap-parse-line (match-string 1))) | 680 | (setq elems (read (current-buffer))) |
| 675 | (push (cons (string-to-number (cadr (member "UID" elems))) | 681 | (push (cons (cadr (memq 'UID elems)) |
| 676 | (cadr (member "FLAGS" elems))) | 682 | (cadr (memq 'FLAGS elems))) |
| 677 | articles))) | 683 | articles))) |
| 678 | (nreverse articles))) | 684 | (nreverse articles))) |
| 679 | 685 | ||
| @@ -940,41 +946,45 @@ textual parts.") | |||
| 940 | (deffoo nnimap-retrieve-group-data-early (server infos) | 946 | (deffoo nnimap-retrieve-group-data-early (server infos) |
| 941 | (when (nnimap-possibly-change-group nil server) | 947 | (when (nnimap-possibly-change-group nil server) |
| 942 | (with-current-buffer (nnimap-buffer) | 948 | (with-current-buffer (nnimap-buffer) |
| 949 | (erase-buffer) | ||
| 950 | (setf (nnimap-group nnimap-object) nil) | ||
| 943 | ;; QRESYNC handling isn't implemented. | 951 | ;; QRESYNC handling isn't implemented. |
| 944 | (let ((qresyncp (member "notQRESYNC" (nnimap-capabilities nnimap-object))) | 952 | (let ((qresyncp (member "notQRESYNC" (nnimap-capabilities nnimap-object))) |
| 945 | marks groups sequences) | 953 | params groups sequences active uidvalidity modseq group) |
| 946 | ;; Go through the infos and gather the data needed to know | 954 | ;; Go through the infos and gather the data needed to know |
| 947 | ;; what and how to request the data. | 955 | ;; what and how to request the data. |
| 948 | (dolist (info infos) | 956 | (dolist (info infos) |
| 949 | (setq marks (gnus-info-marks info)) | 957 | (setq params (gnus-info-params info) |
| 950 | (push (list (gnus-group-real-name (gnus-info-group info)) | 958 | group (gnus-group-real-name (gnus-info-group info)) |
| 951 | (cdr (assq 'active marks)) | 959 | active (cdr (assq 'active params)) |
| 952 | (cdr (assq 'uid marks))) | 960 | uidvalidity (cdr (assq 'uidvalidity params)) |
| 953 | groups)) | 961 | modseq (cdr (assq 'modseq params))) |
| 954 | ;; Then request the data. | ||
| 955 | (erase-buffer) | ||
| 956 | (setf (nnimap-group nnimap-object) nil) | ||
| 957 | (dolist (elem groups) | ||
| 958 | (if (and qresyncp | 962 | (if (and qresyncp |
| 959 | (nth 2 elem)) | 963 | uidvalidity |
| 964 | modseq) | ||
| 960 | (push | 965 | (push |
| 961 | (list 'qresync | 966 | (list (nnimap-send-command "EXAMINE %S (QRESYNC (%s %s))" |
| 962 | (nnimap-send-command "EXAMINE %S (QRESYNC (%s %s))" | 967 | group uidvalidity modseq) |
| 963 | (car elem) | 968 | 'qresync |
| 964 | (car (nth 2 elem)) | 969 | nil group 'qresync) |
| 965 | (cdr (nth 2 elem))) | ||
| 966 | nil | ||
| 967 | (car elem)) | ||
| 968 | sequences) | 970 | sequences) |
| 969 | (let ((start | 971 | (let ((start |
| 970 | (if (nth 1 elem) | 972 | (if (and active uidvalidity) |
| 971 | ;; Fetch the last 100 flags. | 973 | ;; Fetch the last 100 flags. |
| 972 | (max 1 (- (cdr (nth 1 elem)) 100)) | 974 | (max 1 (- (cdr active) 100)) |
| 973 | 1))) | 975 | 1)) |
| 974 | (push (list (nnimap-send-command "EXAMINE %S" (car elem)) | 976 | (command |
| 977 | (if uidvalidity | ||
| 978 | "EXAMINE" | ||
| 979 | ;; If we don't have a UIDVALIDITY, then this is | ||
| 980 | ;; the first time we've seen the group, so we | ||
| 981 | ;; have to do a SELECT (which is slower than an | ||
| 982 | ;; examine), but will tell us whether the group | ||
| 983 | ;; is read-only or not. | ||
| 984 | "SELECT"))) | ||
| 985 | (push (list (nnimap-send-command "%s %S" command group) | ||
| 975 | (nnimap-send-command "UID FETCH %d:* FLAGS" start) | 986 | (nnimap-send-command "UID FETCH %d:* FLAGS" start) |
| 976 | start | 987 | start group command) |
| 977 | (car elem)) | ||
| 978 | sequences))) | 988 | sequences))) |
| 979 | ;; Some servers apparently can't have many outstanding | 989 | ;; Some servers apparently can't have many outstanding |
| 980 | ;; commands, so throttle them. | 990 | ;; commands, so throttle them. |
| @@ -988,10 +998,13 @@ textual parts.") | |||
| 988 | (nnimap-possibly-change-group nil server)) | 998 | (nnimap-possibly-change-group nil server)) |
| 989 | (with-current-buffer (nnimap-buffer) | 999 | (with-current-buffer (nnimap-buffer) |
| 990 | ;; Wait for the final data to trickle in. | 1000 | ;; Wait for the final data to trickle in. |
| 991 | (when (nnimap-wait-for-response (cadar sequences) t) | 1001 | (when (nnimap-wait-for-response (if (eq (cadar sequences) 'qresync) |
| 992 | ;; Now we should have all the data we need, no matter whether | 1002 | (caar sequences) |
| 993 | ;; we're QRESYNCING, fetching all the flags from scratch, or | 1003 | (cadar sequences)) |
| 994 | ;; just fetching the last 100 flags per group. | 1004 | t) |
| 1005 | ;; Now we should have most of the data we need, no matter | ||
| 1006 | ;; whether we're QRESYNCING, fetching all the flags from | ||
| 1007 | ;; scratch, or just fetching the last 100 flags per group. | ||
| 995 | (nnimap-update-infos (nnimap-flags-to-marks | 1008 | (nnimap-update-infos (nnimap-flags-to-marks |
| 996 | (nnimap-parse-flags | 1009 | (nnimap-parse-flags |
| 997 | (nreverse sequences))) | 1010 | (nreverse sequences))) |
| @@ -1011,17 +1024,33 @@ textual parts.") | |||
| 1011 | 1024 | ||
| 1012 | (defun nnimap-update-infos (flags infos) | 1025 | (defun nnimap-update-infos (flags infos) |
| 1013 | (dolist (info infos) | 1026 | (dolist (info infos) |
| 1014 | (let ((group (gnus-group-real-name (gnus-info-group info)))) | 1027 | (let* ((group (gnus-group-real-name (gnus-info-group info))) |
| 1015 | (nnimap-update-info info (cdr (assoc group flags)))))) | 1028 | (marks (cdr (assoc group flags)))) |
| 1029 | (when marks | ||
| 1030 | (nnimap-update-info info marks))))) | ||
| 1016 | 1031 | ||
| 1017 | (defun nnimap-update-info (info marks) | 1032 | (defun nnimap-update-info (info marks) |
| 1018 | (when (and marks | 1033 | (destructuring-bind (existing flags high low uidnext start-article |
| 1019 | ;; Ignore groups with no UIDNEXT/marks. This happens for | 1034 | permanent-flags uidvalidity |
| 1020 | ;; completely empty groups. | 1035 | vanished highestmodseq) marks |
| 1021 | (or (car marks) | 1036 | (cond |
| 1022 | (nth 4 marks))) | 1037 | ;; Ignore groups with no UIDNEXT/marks. This happens for |
| 1023 | (destructuring-bind (existing flags high low uidnext start-article | 1038 | ;; completely empty groups. |
| 1024 | permanent-flags) marks | 1039 | ((and (not existing) |
| 1040 | (not uidnext)) | ||
| 1041 | ) | ||
| 1042 | ;; We have a mismatch between the old and new UIDVALIDITY | ||
| 1043 | ;; identifiers, so we have to re-request the group info (the next | ||
| 1044 | ;; time). This virtually never happens. | ||
| 1045 | ((let ((old-uidvalidity | ||
| 1046 | (cdr (assq 'uidvalidity (gnus-info-params info))))) | ||
| 1047 | (and old-uidvalidity | ||
| 1048 | (not (equal old-uidvalidity uidvalidity)) | ||
| 1049 | (> start-article 1))) | ||
| 1050 | (gnus-group-remove-parameter info 'uidvalidity) | ||
| 1051 | (gnus-group-remove-parameter info 'modseq)) | ||
| 1052 | ;; We have the data needed to update. | ||
| 1053 | (t | ||
| 1025 | (let ((group (gnus-info-group info)) | 1054 | (let ((group (gnus-info-group info)) |
| 1026 | (completep (and start-article | 1055 | (completep (and start-article |
| 1027 | (= start-article 1)))) | 1056 | (= start-article 1)))) |
| @@ -1046,52 +1075,89 @@ textual parts.") | |||
| 1046 | group | 1075 | group |
| 1047 | (cons (car (gnus-active group)) | 1076 | (cons (car (gnus-active group)) |
| 1048 | (or high (1- uidnext))))) | 1077 | (or high (1- uidnext))))) |
| 1049 | ;; Then update the list of read articles. | 1078 | ;; See whether this is a read-only group. |
| 1050 | (let* ((unread | 1079 | (unless (eq permanent-flags 'not-scanned) |
| 1051 | (gnus-compress-sequence | 1080 | (gnus-group-set-parameter |
| 1052 | (gnus-set-difference | 1081 | info 'permanent-flags |
| 1053 | (gnus-set-difference | 1082 | (if (memq '%* permanent-flags) |
| 1054 | existing | 1083 | t |
| 1055 | (cdr (assoc '%Seen flags))) | 1084 | nil))) |
| 1056 | (cdr (assoc '%Flagged flags))))) | 1085 | ;; Update marks and read articles if this isn't a |
| 1057 | (read (gnus-range-difference | 1086 | ;; read-only IMAP group. |
| 1058 | (cons start-article high) unread))) | 1087 | (when (cdr (assq 'permanent-flags (gnus-info-params info))) |
| 1059 | (when (> start-article 1) | 1088 | (if (and highestmodseq |
| 1060 | (setq read | 1089 | (not start-article)) |
| 1061 | (gnus-range-nconcat | 1090 | ;; We've gotten the data by QRESYNCing. |
| 1062 | (if (> start-article 1) | 1091 | (nnimap-update-qresync-info |
| 1063 | (gnus-sorted-range-intersection | 1092 | info (nnimap-imap-ranges-to-gnus-ranges vanished) flags) |
| 1064 | (cons 1 (1- start-article)) | 1093 | ;; Do normal non-QRESYNC flag updates. |
| 1065 | (gnus-info-read info)) | 1094 | ;; Update the list of read articles. |
| 1066 | (gnus-info-read info)) | 1095 | (let* ((unread |
| 1067 | read))) | 1096 | (gnus-compress-sequence |
| 1068 | (gnus-info-set-read info read) | 1097 | (gnus-set-difference |
| 1069 | ;; Update the marks. | 1098 | (gnus-set-difference |
| 1070 | (setq marks (gnus-info-marks info)) | 1099 | existing |
| 1071 | ;; Note the active level for the next run-through. | 1100 | (cdr (assoc '%Seen flags))) |
| 1072 | (let ((active (assq 'active marks))) | 1101 | (cdr (assoc '%Flagged flags))))) |
| 1073 | (if active | 1102 | (read (gnus-range-difference |
| 1074 | (setcdr active (gnus-active group)) | 1103 | (cons start-article high) unread))) |
| 1075 | (push (cons 'active (gnus-active group)) marks))) | 1104 | (when (> start-article 1) |
| 1076 | (dolist (type (cdr nnimap-mark-alist)) | 1105 | (setq read |
| 1077 | (let ((old-marks (assoc (car type) marks)) | 1106 | (gnus-range-nconcat |
| 1078 | (new-marks | 1107 | (if (> start-article 1) |
| 1079 | (gnus-compress-sequence | 1108 | (gnus-sorted-range-intersection |
| 1080 | (cdr (or (assoc (caddr type) flags) ; %Flagged | 1109 | (cons 1 (1- start-article)) |
| 1081 | (assoc (intern (cadr type) obarray) flags) | 1110 | (gnus-info-read info)) |
| 1082 | (assoc (cadr type) flags)))))) ; "\Flagged" | 1111 | (gnus-info-read info)) |
| 1083 | (setq marks (delq old-marks marks)) | 1112 | read))) |
| 1084 | (pop old-marks) | 1113 | (gnus-info-set-read info read) |
| 1085 | (when (and old-marks | 1114 | ;; Update the marks. |
| 1086 | (> start-article 1)) | 1115 | (setq marks (gnus-info-marks info)) |
| 1087 | (setq old-marks (gnus-range-difference | 1116 | (dolist (type (cdr nnimap-mark-alist)) |
| 1088 | old-marks | 1117 | (let ((old-marks (assoc (car type) marks)) |
| 1089 | (cons start-article high))) | 1118 | (new-marks |
| 1090 | (setq new-marks (gnus-range-nconcat old-marks new-marks))) | 1119 | (gnus-compress-sequence |
| 1091 | (when new-marks | 1120 | (cdr (or (assoc (caddr type) flags) ; %Flagged |
| 1092 | (push (cons (car type) new-marks) marks))) | 1121 | (assoc (intern (cadr type) obarray) flags) |
| 1093 | (gnus-info-set-marks info marks t) | 1122 | (assoc (cadr type) flags)))))) ; "\Flagged" |
| 1094 | (nnimap-store-info info (gnus-active group)))))))) | 1123 | (setq marks (delq old-marks marks)) |
| 1124 | (pop old-marks) | ||
| 1125 | (when (and old-marks | ||
| 1126 | (> start-article 1)) | ||
| 1127 | (setq old-marks (gnus-range-difference | ||
| 1128 | old-marks | ||
| 1129 | (cons start-article high))) | ||
| 1130 | (setq new-marks (gnus-range-nconcat old-marks new-marks))) | ||
| 1131 | (when new-marks | ||
| 1132 | (push (cons (car type) new-marks) marks))) | ||
| 1133 | (gnus-info-set-marks info marks t))))) | ||
| 1134 | ;; Note the active level for the next run-through. | ||
| 1135 | (gnus-group-set-parameter info 'active (gnus-active group)) | ||
| 1136 | (gnus-group-set-parameter info 'uidvalidity uidvalidity) | ||
| 1137 | (gnus-group-set-parameter info 'modseq highestmodseq) | ||
| 1138 | (nnimap-store-info info (gnus-active group))))))) | ||
| 1139 | |||
| 1140 | (defun nnimap-update-qresync-info (info vanished flags) | ||
| 1141 | ;; Add all the vanished articles to the list of read articles. | ||
| 1142 | (gnus-info-set-read | ||
| 1143 | info | ||
| 1144 | (gnus-range-add (gnus-info-read info) | ||
| 1145 | vanished)) | ||
| 1146 | ) | ||
| 1147 | |||
| 1148 | (defun nnimap-imap-ranges-to-gnus-ranges (irange) | ||
| 1149 | (if (zerop (length irange)) | ||
| 1150 | nil | ||
| 1151 | (let ((result nil)) | ||
| 1152 | (dolist (elem (split-string irange ",")) | ||
| 1153 | (push | ||
| 1154 | (if (string-match ":" elem) | ||
| 1155 | (let ((numbers (split-string elem ":"))) | ||
| 1156 | (cons (string-to-number (car numbers)) | ||
| 1157 | (string-to-number (cadr numbers)))) | ||
| 1158 | (string-to-number elem)) | ||
| 1159 | result)) | ||
| 1160 | (nreverse result)))) | ||
| 1095 | 1161 | ||
| 1096 | (defun nnimap-store-info (info active) | 1162 | (defun nnimap-store-info (info active) |
| 1097 | (let* ((group (gnus-group-real-name (gnus-info-group info))) | 1163 | (let* ((group (gnus-group-real-name (gnus-info-group info))) |
| @@ -1101,13 +1167,17 @@ textual parts.") | |||
| 1101 | (push (list group info active) nnimap-current-infos)))) | 1167 | (push (list group info active) nnimap-current-infos)))) |
| 1102 | 1168 | ||
| 1103 | (defun nnimap-flags-to-marks (groups) | 1169 | (defun nnimap-flags-to-marks (groups) |
| 1104 | (let (data group totalp uidnext articles start-article mark permanent-flags) | 1170 | (let (data group totalp uidnext articles start-article mark permanent-flags |
| 1171 | uidvalidity vanished highestmodseq) | ||
| 1105 | (dolist (elem groups) | 1172 | (dolist (elem groups) |
| 1106 | (setq group (car elem) | 1173 | (setq group (car elem) |
| 1107 | uidnext (nth 1 elem) | 1174 | uidnext (nth 1 elem) |
| 1108 | start-article (nth 2 elem) | 1175 | start-article (nth 2 elem) |
| 1109 | permanent-flags (nth 3 elem) | 1176 | permanent-flags (nth 3 elem) |
| 1110 | articles (nthcdr 4 elem)) | 1177 | uidvalidity (nth 4 elem) |
| 1178 | vanished (nth 5 elem) | ||
| 1179 | highestmodseq (nth 6 elem) | ||
| 1180 | articles (nthcdr 7 elem)) | ||
| 1111 | (let ((high (caar articles)) | 1181 | (let ((high (caar articles)) |
| 1112 | marks low existing) | 1182 | marks low existing) |
| 1113 | (dolist (article articles) | 1183 | (dolist (article articles) |
| @@ -1119,7 +1189,7 @@ textual parts.") | |||
| 1119 | (push (list flag (car article)) marks) | 1189 | (push (list flag (car article)) marks) |
| 1120 | (setcdr mark (cons (car article) (cdr mark)))))) | 1190 | (setcdr mark (cons (car article) (cdr mark)))))) |
| 1121 | (push (list group existing marks high low uidnext start-article | 1191 | (push (list group existing marks high low uidnext start-article |
| 1122 | permanent-flags) | 1192 | permanent-flags uidvalidity vanished highestmodseq) |
| 1123 | data))) | 1193 | data))) |
| 1124 | data)) | 1194 | data)) |
| 1125 | 1195 | ||
| @@ -1128,38 +1198,69 @@ textual parts.") | |||
| 1128 | ;; Change \Delete etc to %Delete, so that the reader can read it. | 1198 | ;; Change \Delete etc to %Delete, so that the reader can read it. |
| 1129 | (subst-char-in-region (point-min) (point-max) | 1199 | (subst-char-in-region (point-min) (point-max) |
| 1130 | ?\\ ?% t) | 1200 | ?\\ ?% t) |
| 1131 | (let (start end articles groups uidnext elems permanent-flags) | 1201 | (let (start end articles groups uidnext elems permanent-flags |
| 1202 | uidvalidity vanished highestmodseq) | ||
| 1132 | (dolist (elem sequences) | 1203 | (dolist (elem sequences) |
| 1133 | (destructuring-bind (group-sequence flag-sequence totalp group) elem | 1204 | (destructuring-bind (group-sequence flag-sequence totalp group command) |
| 1205 | elem | ||
| 1134 | (setq start (point)) | 1206 | (setq start (point)) |
| 1135 | ;; The EXAMINE was successful. | 1207 | (when (and |
| 1136 | (when (and (search-forward (format "\n%d OK " group-sequence) nil t) | 1208 | ;; The EXAMINE was successful. |
| 1137 | (progn | 1209 | (search-forward (format "\n%d OK " group-sequence) nil t) |
| 1138 | (forward-line 1) | 1210 | (progn |
| 1139 | (setq end (point)) | 1211 | (forward-line 1) |
| 1140 | (goto-char start) | 1212 | (setq end (point)) |
| 1141 | (setq permanent-flags | 1213 | (goto-char start) |
| 1214 | (setq permanent-flags | ||
| 1215 | (if (equal command "SELECT") | ||
| 1142 | (and (search-forward "PERMANENTFLAGS " | 1216 | (and (search-forward "PERMANENTFLAGS " |
| 1143 | (or end (point-min)) t) | 1217 | (or end (point-min)) t) |
| 1144 | (read (current-buffer)))) | 1218 | (read (current-buffer))) |
| 1145 | (goto-char start) | 1219 | 'not-scanned)) |
| 1146 | (setq uidnext | 1220 | (goto-char start) |
| 1147 | (and (search-forward "UIDNEXT " | 1221 | (setq uidnext |
| 1148 | (or end (point-min)) t) | 1222 | (and (search-forward "UIDNEXT " |
| 1149 | (read (current-buffer)))) | 1223 | (or end (point-min)) t) |
| 1150 | (goto-char end) | 1224 | (read (current-buffer)))) |
| 1151 | (forward-line -1)) | 1225 | (goto-char start) |
| 1152 | ;; The UID FETCH FLAGS was successful. | 1226 | (setq uidvalidity |
| 1153 | (search-forward (format "\n%d OK " flag-sequence) nil t)) | 1227 | (and (re-search-forward "UIDVALIDITY \\([0-9]+\\)" |
| 1154 | (setq start (point)) | 1228 | (or end (point-min)) t) |
| 1155 | (goto-char end) | 1229 | ;; Store UIDVALIDITY as a string, as it's |
| 1230 | ;; too big for 32-bit Emacsen, usually. | ||
| 1231 | (match-string 1))) | ||
| 1232 | (goto-char start) | ||
| 1233 | (setq vanished | ||
| 1234 | (and (eq flag-sequence 'qresync) | ||
| 1235 | (re-search-forward "VANISHED.* \\([0-9:,]+\\)" | ||
| 1236 | (or end (point-min)) t) | ||
| 1237 | (match-string 1))) | ||
| 1238 | (goto-char start) | ||
| 1239 | (setq highestmodseq | ||
| 1240 | (and (search-forward "HIGHESTMODSEQ " | ||
| 1241 | (or end (point-min)) t) | ||
| 1242 | (read (current-buffer)))) | ||
| 1243 | (goto-char end) | ||
| 1244 | (forward-line -1)) | ||
| 1245 | ;; The UID FETCH FLAGS was successful. | ||
| 1246 | (or (eq flag-sequence 'qresync) | ||
| 1247 | (search-forward (format "\n%d OK " flag-sequence) nil t))) | ||
| 1248 | (if (eq flag-sequence 'qresync) | ||
| 1249 | (progn | ||
| 1250 | (goto-char start) | ||
| 1251 | (setq start end)) | ||
| 1252 | (setq start (point)) | ||
| 1253 | (goto-char end)) | ||
| 1156 | (while (search-forward " FETCH " start t) | 1254 | (while (search-forward " FETCH " start t) |
| 1157 | (setq elems (read (current-buffer))) | 1255 | (setq elems (read (current-buffer))) |
| 1158 | (push (cons (cadr (memq 'UID elems)) | 1256 | (push (cons (cadr (memq 'UID elems)) |
| 1159 | (cadr (memq 'FLAGS elems))) | 1257 | (cadr (memq 'FLAGS elems))) |
| 1160 | articles)) | 1258 | articles)) |
| 1161 | (push (nconc (list group uidnext totalp permanent-flags) articles) | 1259 | (push (nconc (list group uidnext totalp permanent-flags uidvalidity |
| 1260 | vanished highestmodseq) | ||
| 1261 | articles) | ||
| 1162 | groups) | 1262 | groups) |
| 1263 | (goto-char end) | ||
| 1163 | (setq articles nil)))) | 1264 | (setq articles nil)))) |
| 1164 | groups)) | 1265 | groups)) |
| 1165 | 1266 | ||
| @@ -1293,13 +1394,15 @@ textual parts.") | |||
| 1293 | (push | 1394 | (push |
| 1294 | (cond | 1395 | (cond |
| 1295 | ((eql char ?\[) | 1396 | ((eql char ?\[) |
| 1296 | (split-string (buffer-substring | 1397 | (split-string |
| 1297 | (1+ (point)) | 1398 | (buffer-substring |
| 1298 | (1- (search-forward "]" (line-end-position) 'move))))) | 1399 | (1+ (point)) |
| 1400 | (1- (search-forward "]" (line-end-position) 'move))))) | ||
| 1299 | ((eql char ?\() | 1401 | ((eql char ?\() |
| 1300 | (split-string (buffer-substring | 1402 | (split-string |
| 1301 | (1+ (point)) | 1403 | (buffer-substring |
| 1302 | (1- (search-forward ")" (line-end-position) 'move))))) | 1404 | (1+ (point)) |
| 1405 | (1- (search-forward ")" (line-end-position) 'move))))) | ||
| 1303 | ((eql char ?\") | 1406 | ((eql char ?\") |
| 1304 | (forward-char 1) | 1407 | (forward-char 1) |
| 1305 | (buffer-substring | 1408 | (buffer-substring |
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index 6d64935550f..86acad16638 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el | |||
| @@ -377,7 +377,6 @@ result, `gnus-retrieve-headers' will be called instead.") | |||
| 377 | ((criteria | 377 | ((criteria |
| 378 | "Search in: " ; Prompt | 378 | "Search in: " ; Prompt |
| 379 | ,(mapcar 'car nnir-imap-search-arguments) ; alist for completing | 379 | ,(mapcar 'car nnir-imap-search-arguments) ; alist for completing |
| 380 | nil ; no filtering | ||
| 381 | nil ; allow any user input | 380 | nil ; allow any user input |
| 382 | nil ; initial value | 381 | nil ; initial value |
| 383 | nnir-imap-search-argument-history ; the history to use | 382 | nnir-imap-search-argument-history ; the history to use |
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index 463f87e44fc..01cab6febe3 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el | |||
| @@ -1914,7 +1914,7 @@ If TIME is nil, then return the cutoff time for oldness instead." | |||
| 1914 | (unless (eq target 'delete) | 1914 | (unless (eq target 'delete) |
| 1915 | (when (or (gnus-request-group target) | 1915 | (when (or (gnus-request-group target) |
| 1916 | (gnus-request-create-group target)) | 1916 | (gnus-request-create-group target)) |
| 1917 | (let ((group-art (gnus-request-accept-article target nil nil t))) | 1917 | (let ((group-art (gnus-request-accept-article target nil t t))) |
| 1918 | (when (consp group-art) | 1918 | (when (consp group-art) |
| 1919 | (gnus-group-mark-article-read target (cdr group-art)))))))) | 1919 | (gnus-group-mark-article-read target (cdr group-art)))))))) |
| 1920 | 1920 | ||
diff --git a/lisp/gnus/shr.el b/lisp/gnus/shr.el index 8f246a06e36..0700621a912 100644 --- a/lisp/gnus/shr.el +++ b/lisp/gnus/shr.el | |||
| @@ -230,7 +230,7 @@ redirects somewhere else." | |||
| 230 | 230 | ||
| 231 | (defun shr-ensure-paragraph () | 231 | (defun shr-ensure-paragraph () |
| 232 | (unless (bobp) | 232 | (unless (bobp) |
| 233 | (if (bolp) | 233 | (if (<= (current-column) shr-indentation) |
| 234 | (unless (save-excursion | 234 | (unless (save-excursion |
| 235 | (forward-line -1) | 235 | (forward-line -1) |
| 236 | (looking-at " *$")) | 236 | (looking-at " *$")) |
| @@ -242,7 +242,8 @@ redirects somewhere else." | |||
| 242 | (insert "\n\n"))))) | 242 | (insert "\n\n"))))) |
| 243 | 243 | ||
| 244 | (defun shr-indent () | 244 | (defun shr-indent () |
| 245 | (insert (make-string shr-indentation ? ))) | 245 | (when (> shr-indentation 0) |
| 246 | (insert (make-string shr-indentation ? )))) | ||
| 246 | 247 | ||
| 247 | (defun shr-fontize-cont (cont &rest types) | 248 | (defun shr-fontize-cont (cont &rest types) |
| 248 | (let (shr-start) | 249 | (let (shr-start) |
| @@ -332,6 +333,7 @@ Return a string with image data." | |||
| 332 | 333 | ||
| 333 | (defun shr-tag-p (cont) | 334 | (defun shr-tag-p (cont) |
| 334 | (shr-ensure-paragraph) | 335 | (shr-ensure-paragraph) |
| 336 | (shr-indent) | ||
| 335 | (shr-generic cont) | 337 | (shr-generic cont) |
| 336 | (shr-ensure-paragraph)) | 338 | (shr-ensure-paragraph)) |
| 337 | 339 | ||
| @@ -404,11 +406,13 @@ Return a string with image data." | |||
| 404 | (defun shr-tag-pre (cont) | 406 | (defun shr-tag-pre (cont) |
| 405 | (let ((shr-folding-mode 'none)) | 407 | (let ((shr-folding-mode 'none)) |
| 406 | (shr-ensure-newline) | 408 | (shr-ensure-newline) |
| 409 | (shr-indent) | ||
| 407 | (shr-generic cont) | 410 | (shr-generic cont) |
| 408 | (shr-ensure-newline))) | 411 | (shr-ensure-newline))) |
| 409 | 412 | ||
| 410 | (defun shr-tag-blockquote (cont) | 413 | (defun shr-tag-blockquote (cont) |
| 411 | (shr-ensure-paragraph) | 414 | (shr-ensure-paragraph) |
| 415 | (shr-indent) | ||
| 412 | (let ((shr-indentation (+ shr-indentation 4))) | 416 | (let ((shr-indentation (+ shr-indentation 4))) |
| 413 | (shr-generic cont)) | 417 | (shr-generic cont)) |
| 414 | (shr-ensure-paragraph)) | 418 | (shr-ensure-paragraph)) |
| @@ -426,7 +430,8 @@ Return a string with image data." | |||
| 426 | (shr-ensure-paragraph)) | 430 | (shr-ensure-paragraph)) |
| 427 | 431 | ||
| 428 | (defun shr-tag-li (cont) | 432 | (defun shr-tag-li (cont) |
| 429 | (shr-ensure-newline) | 433 | (shr-ensure-paragraph) |
| 434 | (shr-indent) | ||
| 430 | (let* ((bullet | 435 | (let* ((bullet |
| 431 | (if (numberp shr-list-mode) | 436 | (if (numberp shr-list-mode) |
| 432 | (prog1 | 437 | (prog1 |
| @@ -439,7 +444,8 @@ Return a string with image data." | |||
| 439 | 444 | ||
| 440 | (defun shr-tag-br (cont) | 445 | (defun shr-tag-br (cont) |
| 441 | (unless (bobp) | 446 | (unless (bobp) |
| 442 | (insert "\n")) | 447 | (insert "\n") |
| 448 | (shr-indent)) | ||
| 443 | (shr-generic cont)) | 449 | (shr-generic cont)) |
| 444 | 450 | ||
| 445 | (defun shr-tag-h1 (cont) | 451 | (defun shr-tag-h1 (cont) |
diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index b7908e5507b..9e193ccea84 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el | |||
| @@ -689,7 +689,8 @@ order for SpamAssassin to recognize the new registered spam." | |||
| 689 | "Sx" gnus-summary-mark-as-spam | 689 | "Sx" gnus-summary-mark-as-spam |
| 690 | "Mst" spam-generic-score | 690 | "Mst" spam-generic-score |
| 691 | "Msx" gnus-summary-mark-as-spam | 691 | "Msx" gnus-summary-mark-as-spam |
| 692 | "\M-d" gnus-summary-mark-as-spam) | 692 | "\M-d" gnus-summary-mark-as-spam |
| 693 | "$" gnus-summary-mark-as-spam) | ||
| 693 | 694 | ||
| 694 | (defvar spam-cache-lookups t | 695 | (defvar spam-cache-lookups t |
| 695 | "Whether spam.el will try to cache lookups using `spam-caches'.") | 696 | "Whether spam.el will try to cache lookups using `spam-caches'.") |