diff options
49 files changed, 1289 insertions, 2264 deletions
diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el index 5b44c0b9937..a0be0ca8ba4 100644 --- a/lisp/gnus/auth-source.el +++ b/lisp/gnus/auth-source.el | |||
| @@ -107,7 +107,8 @@ Only relevant if `auth-source-debug' is not nil." | |||
| 107 | :version "23.2" ;; No Gnus | 107 | :version "23.2" ;; No Gnus |
| 108 | :type `boolean) | 108 | :type `boolean) |
| 109 | 109 | ||
| 110 | (defcustom auth-sources '((:source "~/.authinfo.gpg")) | 110 | (defcustom auth-sources '((:source "~/.authinfo.gpg") |
| 111 | (:source "~/.authinfo")) | ||
| 111 | "List of authentication sources. | 112 | "List of authentication sources. |
| 112 | 113 | ||
| 113 | The default will get login and password information from a .gpg | 114 | The default will get login and password information from a .gpg |
| @@ -311,20 +312,23 @@ Return structure as specified by MODE." | |||
| 311 | (setq result | 312 | (setq result |
| 312 | (mapcar | 313 | (mapcar |
| 313 | (lambda (m) | 314 | (lambda (m) |
| 314 | (if (equal "password" m) | 315 | (cond |
| 315 | (let ((passwd (read-passwd "Password: "))) | 316 | ((equal "password" m) |
| 316 | (cond | 317 | (let ((passwd (read-passwd |
| 317 | ;; Secret Service API. | 318 | (format "Password for %s on %s: " prot host)))) |
| 318 | ((consp source) | 319 | (cond |
| 319 | (apply | 320 | ;; Secret Service API. |
| 320 | 'secrets-create-item | 321 | ((consp source) |
| 321 | (auth-get-source entry) name passwd spec)) | 322 | (apply |
| 322 | (t)) ;; netrc not implemented yes. | 323 | 'secrets-create-item |
| 323 | passwd) | 324 | (auth-get-source entry) name passwd spec)) |
| 324 | (or | 325 | (t)) ;; netrc not implemented yes. |
| 325 | ;; the originally requested :user | 326 | passwd)) |
| 326 | user | 327 | ((equal "login" m) |
| 327 | "unknown-user"))) | 328 | (or user |
| 329 | (read-string (format "User name for %s on %s: " prot host)))) | ||
| 330 | (t | ||
| 331 | "unknownuser"))) | ||
| 328 | (if (consp mode) mode (list mode)))) | 332 | (if (consp mode) mode (list mode)))) |
| 329 | (if (consp mode) result (car result)))) | 333 | (if (consp mode) result (car result)))) |
| 330 | 334 | ||
diff --git a/lisp/gnus/earcon.el b/lisp/gnus/earcon.el index 2578abc073d..2086f86c417 100644 --- a/lisp/gnus/earcon.el +++ b/lisp/gnus/earcon.el | |||
| @@ -151,8 +151,7 @@ If N is negative, move backward instead." | |||
| 151 | 151 | ||
| 152 | (defun earcon-button-push (marker) | 152 | (defun earcon-button-push (marker) |
| 153 | ;; Push button starting at MARKER. | 153 | ;; Push button starting at MARKER. |
| 154 | (save-excursion | 154 | (with-current-buffer gnus-article-buffer |
| 155 | (set-buffer gnus-article-buffer) | ||
| 156 | (goto-char marker) | 155 | (goto-char marker) |
| 157 | (let* ((entry (earcon-button-entry)) | 156 | (let* ((entry (earcon-button-entry)) |
| 158 | (inhibit-point-motion-hooks t) | 157 | (inhibit-point-motion-hooks t) |
| @@ -214,8 +213,7 @@ If N is negative, move backward instead." | |||
| 214 | (defun gnus-earcon-display () | 213 | (defun gnus-earcon-display () |
| 215 | "Play sounds in message buffers." | 214 | "Play sounds in message buffers." |
| 216 | (interactive) | 215 | (interactive) |
| 217 | (save-excursion | 216 | (with-current-buffer gnus-article-buffer |
| 218 | (set-buffer gnus-article-buffer) | ||
| 219 | (goto-char (point-min)) | 217 | (goto-char (point-min)) |
| 220 | ;; Skip headers | 218 | ;; Skip headers |
| 221 | (unless (search-forward "\n\n" nil t) | 219 | (unless (search-forward "\n\n" nil t) |
diff --git a/lisp/gnus/flow-fill.el b/lisp/gnus/flow-fill.el index c4c64db7ed1..2420577ea45 100644 --- a/lisp/gnus/flow-fill.el +++ b/lisp/gnus/flow-fill.el | |||
| @@ -97,8 +97,7 @@ RFC 2646 suggests 66 characters for readability." | |||
| 97 | 97 | ||
| 98 | ;;;###autoload | 98 | ;;;###autoload |
| 99 | (defun fill-flowed (&optional buffer delete-space) | 99 | (defun fill-flowed (&optional buffer delete-space) |
| 100 | (save-excursion | 100 | (with-current-buffer (or (current-buffer) buffer) |
| 101 | (set-buffer (or (current-buffer) buffer)) | ||
| 102 | (goto-char (point-min)) | 101 | (goto-char (point-min)) |
| 103 | ;; Remove space stuffing. | 102 | ;; Remove space stuffing. |
| 104 | (while (re-search-forward "^\\( \\|>+ $\\)" nil t) | 103 | (while (re-search-forward "^\\( \\|>+ $\\)" nil t) |
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index bbfdc66af99..6dcc77cdfb9 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el | |||
| @@ -305,8 +305,7 @@ buffer. Automatically blocks multiple updates due to recursion." | |||
| 305 | `(prog1 (let ((gnus-agent-inhibit-update-total-fetched-for t)) ,@body) | 305 | `(prog1 (let ((gnus-agent-inhibit-update-total-fetched-for t)) ,@body) |
| 306 | (when (and gnus-agent-need-update-total-fetched-for | 306 | (when (and gnus-agent-need-update-total-fetched-for |
| 307 | (not gnus-agent-inhibit-update-total-fetched-for)) | 307 | (not gnus-agent-inhibit-update-total-fetched-for)) |
| 308 | (save-excursion | 308 | (with-current-buffer gnus-group-buffer |
| 309 | (set-buffer gnus-group-buffer) | ||
| 310 | (setq gnus-agent-need-update-total-fetched-for nil) | 309 | (setq gnus-agent-need-update-total-fetched-for nil) |
| 311 | (gnus-group-update-group ,group t))))) | 310 | (gnus-group-update-group ,group t))))) |
| 312 | 311 | ||
| @@ -474,8 +473,7 @@ manipulated as follows: | |||
| 474 | (defun gnus-agent-stop-fetch () | 473 | (defun gnus-agent-stop-fetch () |
| 475 | "Save all data structures and clean up." | 474 | "Save all data structures and clean up." |
| 476 | (setq gnus-agent-spam-hashtb nil) | 475 | (setq gnus-agent-spam-hashtb nil) |
| 477 | (save-excursion | 476 | (with-current-buffer nntp-server-buffer |
| 478 | (set-buffer nntp-server-buffer) | ||
| 479 | (widen))) | 477 | (widen))) |
| 480 | 478 | ||
| 481 | (defmacro gnus-agent-with-fetch (&rest forms) | 479 | (defmacro gnus-agent-with-fetch (&rest forms) |
| @@ -1608,8 +1606,7 @@ downloaded into the agent." | |||
| 1608 | nntp-server-buffer (point-min) (point-max)) | 1606 | nntp-server-buffer (point-min) (point-max)) |
| 1609 | (setq pos (nreverse pos))))) | 1607 | (setq pos (nreverse pos))))) |
| 1610 | ;; Then save these articles into the Agent. | 1608 | ;; Then save these articles into the Agent. |
| 1611 | (save-excursion | 1609 | (with-current-buffer nntp-server-buffer |
| 1612 | (set-buffer nntp-server-buffer) | ||
| 1613 | (while pos | 1610 | (while pos |
| 1614 | (narrow-to-region (cdar pos) (or (cdadr pos) (point-max))) | 1611 | (narrow-to-region (cdar pos) (or (cdadr pos) (point-max))) |
| 1615 | (goto-char (point-min)) | 1612 | (goto-char (point-min)) |
| @@ -1693,8 +1690,7 @@ downloaded into the agent." | |||
| 1693 | (setq date (or date t)) | 1690 | (setq date (or date t)) |
| 1694 | 1691 | ||
| 1695 | (let (gnus-agent-article-alist group alist beg end) | 1692 | (let (gnus-agent-article-alist group alist beg end) |
| 1696 | (save-excursion | 1693 | (with-current-buffer gnus-agent-overview-buffer |
| 1697 | (set-buffer gnus-agent-overview-buffer) | ||
| 1698 | (when (nnheader-find-nov-line article) | 1694 | (when (nnheader-find-nov-line article) |
| 1699 | (forward-word 1) | 1695 | (forward-word 1) |
| 1700 | (setq beg (point)) | 1696 | (setq beg (point)) |
| @@ -1705,9 +1701,8 @@ downloaded into the agent." | |||
| 1705 | (push (setq alist (list group (gnus-agent-load-alist (caar crosses)))) | 1701 | (push (setq alist (list group (gnus-agent-load-alist (caar crosses)))) |
| 1706 | gnus-agent-group-alist)) | 1702 | gnus-agent-group-alist)) |
| 1707 | (setcdr alist (cons (cons (cdar crosses) date) (cdr alist))) | 1703 | (setcdr alist (cons (cons (cdar crosses) date) (cdr alist))) |
| 1708 | (save-excursion | 1704 | (with-current-buffer (gnus-get-buffer-create |
| 1709 | (set-buffer (gnus-get-buffer-create (format " *Gnus agent overview %s*" | 1705 | (format " *Gnus agent overview %s*"group)) |
| 1710 | group))) | ||
| 1711 | (when (= (point-max) (point-min)) | 1706 | (when (= (point-max) (point-min)) |
| 1712 | (push (cons group (current-buffer)) gnus-agent-buffer-alist) | 1707 | (push (cons group (current-buffer)) gnus-agent-buffer-alist) |
| 1713 | (ignore-errors | 1708 | (ignore-errors |
| @@ -1939,9 +1934,7 @@ article numbers will be returned." | |||
| 1939 | 10 "gnus-agent-fetch-headers: undownloaded articles are '%s'" | 1934 | 10 "gnus-agent-fetch-headers: undownloaded articles are '%s'" |
| 1940 | (gnus-compress-sequence articles t)) | 1935 | (gnus-compress-sequence articles t)) |
| 1941 | 1936 | ||
| 1942 | (save-excursion | 1937 | (with-current-buffer nntp-server-buffer |
| 1943 | (set-buffer nntp-server-buffer) | ||
| 1944 | |||
| 1945 | (if articles | 1938 | (if articles |
| 1946 | (progn | 1939 | (progn |
| 1947 | (gnus-message 7 "Fetching headers for %s..." | 1940 | (gnus-message 7 "Fetching headers for %s..." |
| @@ -2767,8 +2760,7 @@ The following commands are available: | |||
| 2767 | 2760 | ||
| 2768 | (defun gnus-category-setup-buffer () | 2761 | (defun gnus-category-setup-buffer () |
| 2769 | (unless (get-buffer gnus-category-buffer) | 2762 | (unless (get-buffer gnus-category-buffer) |
| 2770 | (save-excursion | 2763 | (with-current-buffer (gnus-get-buffer-create gnus-category-buffer) |
| 2771 | (set-buffer (gnus-get-buffer-create gnus-category-buffer)) | ||
| 2772 | (gnus-category-mode)))) | 2764 | (gnus-category-mode)))) |
| 2773 | 2765 | ||
| 2774 | (defun gnus-category-prepare () | 2766 | (defun gnus-category-prepare () |
diff --git a/lisp/gnus/gnus-async.el b/lisp/gnus/gnus-async.el index 979e67120d1..a2ab54bea8b 100644 --- a/lisp/gnus/gnus-async.el +++ b/lisp/gnus/gnus-async.el | |||
| @@ -145,8 +145,7 @@ that was fetched." | |||
| 145 | (when (and (gnus-buffer-live-p summary) | 145 | (when (and (gnus-buffer-live-p summary) |
| 146 | gnus-asynchronous | 146 | gnus-asynchronous |
| 147 | (gnus-group-asynchronous-p group)) | 147 | (gnus-group-asynchronous-p group)) |
| 148 | (save-excursion | 148 | (with-current-buffer gnus-summary-buffer |
| 149 | (set-buffer gnus-summary-buffer) | ||
| 150 | (let ((next (caadr (gnus-data-find-list article)))) | 149 | (let ((next (caadr (gnus-data-find-list article)))) |
| 151 | (when next | 150 | (when next |
| 152 | (if (not (fboundp 'run-with-idle-timer)) | 151 | (if (not (fboundp 'run-with-idle-timer)) |
| @@ -205,8 +204,7 @@ that was fetched." | |||
| 205 | 204 | ||
| 206 | (when (and do-fetch article) | 205 | (when (and do-fetch article) |
| 207 | ;; We want to fetch some more articles. | 206 | ;; We want to fetch some more articles. |
| 208 | (save-excursion | 207 | (with-current-buffer summary |
| 209 | (set-buffer summary) | ||
| 210 | (let (mark) | 208 | (let (mark) |
| 211 | (gnus-async-set-buffer) | 209 | (gnus-async-set-buffer) |
| 212 | (goto-char (point-max)) | 210 | (goto-char (point-max)) |
diff --git a/lisp/gnus/gnus-bcklg.el b/lisp/gnus/gnus-bcklg.el index b3851858513..68233328802 100644 --- a/lisp/gnus/gnus-bcklg.el +++ b/lisp/gnus/gnus-bcklg.el | |||
| @@ -40,8 +40,7 @@ | |||
| 40 | (defun gnus-backlog-buffer () | 40 | (defun gnus-backlog-buffer () |
| 41 | "Return the backlog buffer." | 41 | "Return the backlog buffer." |
| 42 | (or (get-buffer gnus-backlog-buffer) | 42 | (or (get-buffer gnus-backlog-buffer) |
| 43 | (save-excursion | 43 | (with-current-buffer (gnus-get-buffer-create gnus-backlog-buffer) |
| 44 | (set-buffer (gnus-get-buffer-create gnus-backlog-buffer)) | ||
| 45 | (buffer-disable-undo) | 44 | (buffer-disable-undo) |
| 46 | (setq buffer-read-only t) | 45 | (setq buffer-read-only t) |
| 47 | (get-buffer gnus-backlog-buffer)))) | 46 | (get-buffer gnus-backlog-buffer)))) |
| @@ -76,8 +75,7 @@ | |||
| 76 | (gnus-backlog-remove-oldest-article)) | 75 | (gnus-backlog-remove-oldest-article)) |
| 77 | (push ident gnus-backlog-articles) | 76 | (push ident gnus-backlog-articles) |
| 78 | ;; Insert the new article. | 77 | ;; Insert the new article. |
| 79 | (save-excursion | 78 | (with-current-buffer (gnus-backlog-buffer) |
| 80 | (set-buffer (gnus-backlog-buffer)) | ||
| 81 | (let (buffer-read-only) | 79 | (let (buffer-read-only) |
| 82 | (goto-char (point-max)) | 80 | (goto-char (point-max)) |
| 83 | (unless (bolp) | 81 | (unless (bolp) |
| @@ -90,8 +88,7 @@ | |||
| 90 | (gnus-error 3 "Article %d is blank" number)))))))) | 88 | (gnus-error 3 "Article %d is blank" number)))))))) |
| 91 | 89 | ||
| 92 | (defun gnus-backlog-remove-oldest-article () | 90 | (defun gnus-backlog-remove-oldest-article () |
| 93 | (save-excursion | 91 | (with-current-buffer (gnus-backlog-buffer) |
| 94 | (set-buffer (gnus-backlog-buffer)) | ||
| 95 | (goto-char (point-min)) | 92 | (goto-char (point-min)) |
| 96 | (if (zerop (buffer-size)) | 93 | (if (zerop (buffer-size)) |
| 97 | () ; The buffer is empty. | 94 | () ; The buffer is empty. |
| @@ -114,8 +111,7 @@ | |||
| 114 | beg end) | 111 | beg end) |
| 115 | (when (memq ident gnus-backlog-articles) | 112 | (when (memq ident gnus-backlog-articles) |
| 116 | ;; It was in the backlog. | 113 | ;; It was in the backlog. |
| 117 | (save-excursion | 114 | (with-current-buffer (gnus-backlog-buffer) |
| 118 | (set-buffer (gnus-backlog-buffer)) | ||
| 119 | (let (buffer-read-only) | 115 | (let (buffer-read-only) |
| 120 | (when (setq beg (text-property-any | 116 | (when (setq beg (text-property-any |
| 121 | (point-min) (point-max) 'gnus-backlog | 117 | (point-min) (point-max) 'gnus-backlog |
| @@ -138,8 +134,7 @@ | |||
| 138 | beg end) | 134 | beg end) |
| 139 | (when (memq ident gnus-backlog-articles) | 135 | (when (memq ident gnus-backlog-articles) |
| 140 | ;; It was in the backlog. | 136 | ;; It was in the backlog. |
| 141 | (save-excursion | 137 | (with-current-buffer (gnus-backlog-buffer) |
| 142 | (set-buffer (gnus-backlog-buffer)) | ||
| 143 | (if (not (setq beg (text-property-any | 138 | (if (not (setq beg (text-property-any |
| 144 | (point-min) (point-max) 'gnus-backlog | 139 | (point-min) (point-max) 'gnus-backlog |
| 145 | ident))) | 140 | ident))) |
| @@ -150,8 +145,7 @@ | |||
| 150 | (setq end | 145 | (setq end |
| 151 | (next-single-property-change | 146 | (next-single-property-change |
| 152 | (1+ beg) 'gnus-backlog (current-buffer) (point-max))))) | 147 | (1+ beg) 'gnus-backlog (current-buffer) (point-max))))) |
| 153 | (save-excursion | 148 | (with-current-buffer (or (current-buffer) buffer) |
| 154 | (and buffer (set-buffer buffer)) | ||
| 155 | (let ((buffer-read-only nil)) | 149 | (let ((buffer-read-only nil)) |
| 156 | (erase-buffer) | 150 | (erase-buffer) |
| 157 | (insert-buffer-substring gnus-backlog-buffer beg end))) | 151 | (insert-buffer-substring gnus-backlog-buffer beg end))) |
diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el index e3f33be8819..4b2d6705707 100644 --- a/lisp/gnus/gnus-cache.el +++ b/lisp/gnus/gnus-cache.el | |||
| @@ -180,8 +180,7 @@ it's not cached." | |||
| 180 | ;; Save the article in the cache. | 180 | ;; Save the article in the cache. |
| 181 | (if (file-exists-p file) | 181 | (if (file-exists-p file) |
| 182 | t ; The article already is saved. | 182 | t ; The article already is saved. |
| 183 | (save-excursion | 183 | (with-current-buffer nntp-server-buffer |
| 184 | (set-buffer nntp-server-buffer) | ||
| 185 | (require 'gnus-art) | 184 | (require 'gnus-art) |
| 186 | (let ((gnus-use-cache nil) | 185 | (let ((gnus-use-cache nil) |
| 187 | (gnus-article-decode-hook nil)) | 186 | (gnus-article-decode-hook nil)) |
| @@ -554,8 +553,7 @@ system for example was used.") | |||
| 554 | (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) | 553 | (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) |
| 555 | beg end) | 554 | beg end) |
| 556 | (gnus-cache-save-buffers) | 555 | (gnus-cache-save-buffers) |
| 557 | (save-excursion | 556 | (with-current-buffer cache-buf |
| 558 | (set-buffer cache-buf) | ||
| 559 | (erase-buffer) | 557 | (erase-buffer) |
| 560 | (let ((coding-system-for-read gnus-cache-overview-coding-system) | 558 | (let ((coding-system-for-read gnus-cache-overview-coding-system) |
| 561 | (file-name-coding-system nnmail-pathname-coding-system)) | 559 | (file-name-coding-system nnmail-pathname-coding-system)) |
| @@ -844,8 +842,7 @@ supported." | |||
| 844 | ,@body) | 842 | ,@body) |
| 845 | (when (and gnus-cache-need-update-total-fetched-for | 843 | (when (and gnus-cache-need-update-total-fetched-for |
| 846 | (not gnus-cache-inhibit-update-total-fetched-for)) | 844 | (not gnus-cache-inhibit-update-total-fetched-for)) |
| 847 | (save-excursion | 845 | (with-current-buffer gnus-group-buffer |
| 848 | (set-buffer gnus-group-buffer) | ||
| 849 | (setq gnus-cache-need-update-total-fetched-for nil) | 846 | (setq gnus-cache-need-update-total-fetched-for nil) |
| 850 | (gnus-group-update-group ,group t))))) | 847 | (gnus-group-update-group ,group t))))) |
| 851 | 848 | ||
diff --git a/lisp/gnus/gnus-demon.el b/lisp/gnus/gnus-demon.el index caf9f8784b9..67c1c8ba3bc 100644 --- a/lisp/gnus/gnus-demon.el +++ b/lisp/gnus/gnus-demon.el | |||
| @@ -291,11 +291,9 @@ minutes, the connection is closed." | |||
| 291 | (let ((win (current-window-configuration))) | 291 | (let ((win (current-window-configuration))) |
| 292 | (unwind-protect | 292 | (unwind-protect |
| 293 | (save-window-excursion | 293 | (save-window-excursion |
| 294 | (save-excursion | 294 | (when (gnus-alive-p) |
| 295 | (when (gnus-alive-p) | 295 | (with-current-buffer gnus-group-buffer |
| 296 | (save-excursion | 296 | (gnus-group-get-new-news)))) |
| 297 | (set-buffer gnus-group-buffer) | ||
| 298 | (gnus-group-get-new-news))))) | ||
| 299 | (set-window-configuration win)))) | 297 | (set-window-configuration win)))) |
| 300 | 298 | ||
| 301 | (defun gnus-demon-add-scan-timestamps () | 299 | (defun gnus-demon-add-scan-timestamps () |
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index d805f3104d2..389b1a22a8b 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el | |||
| @@ -179,10 +179,7 @@ If it is down, start it up (again)." | |||
| 179 | (format " on %s" (nth 1 method))))) | 179 | (format " on %s" (nth 1 method))))) |
| 180 | (gnus-run-hooks 'gnus-open-server-hook) | 180 | (gnus-run-hooks 'gnus-open-server-hook) |
| 181 | (prog1 | 181 | (prog1 |
| 182 | (condition-case () | 182 | (setq result (gnus-open-server method)) |
| 183 | (setq result (gnus-open-server method)) | ||
| 184 | (quit (message "Quit gnus-check-server") | ||
| 185 | nil)) | ||
| 186 | (unless silent | 183 | (unless silent |
| 187 | (gnus-message 5 "Opening %s server%s...%s" (car method) | 184 | (gnus-message 5 "Opening %s server%s...%s" (car method) |
| 188 | (if (equal (nth 1 method) "") "" | 185 | (if (equal (nth 1 method) "") "" |
| @@ -225,6 +222,10 @@ If it is down, start it up (again)." | |||
| 225 | ;;; Interface functions to the backends. | 222 | ;;; Interface functions to the backends. |
| 226 | ;;; | 223 | ;;; |
| 227 | 224 | ||
| 225 | (defun gnus-method-denied-p (method) | ||
| 226 | (eq (nth 1 (assoc method gnus-opened-servers)) | ||
| 227 | 'denied)) | ||
| 228 | |||
| 228 | (defun gnus-open-server (gnus-command-method) | 229 | (defun gnus-open-server (gnus-command-method) |
| 229 | "Open a connection to GNUS-COMMAND-METHOD." | 230 | "Open a connection to GNUS-COMMAND-METHOD." |
| 230 | (when (stringp gnus-command-method) | 231 | (when (stringp gnus-command-method) |
| @@ -319,6 +320,22 @@ If it is down, start it up (again)." | |||
| 319 | (funcall (gnus-get-function gnus-command-method 'request-list) | 320 | (funcall (gnus-get-function gnus-command-method 'request-list) |
| 320 | (nth 1 gnus-command-method))) | 321 | (nth 1 gnus-command-method))) |
| 321 | 322 | ||
| 323 | (defun gnus-finish-retrieve-group-infos (gnus-command-method infos data) | ||
| 324 | "Read and update infos from GNUS-COMMAND-METHOD." | ||
| 325 | (when (stringp gnus-command-method) | ||
| 326 | (setq gnus-command-method (gnus-server-to-method gnus-command-method))) | ||
| 327 | (funcall (gnus-get-function gnus-command-method 'finish-retrieve-group-infos) | ||
| 328 | (nth 1 gnus-command-method) | ||
| 329 | infos data)) | ||
| 330 | |||
| 331 | (defun gnus-retrieve-group-data-early (gnus-command-method infos) | ||
| 332 | "Start early async retrival of data from GNUS-COMMAND-METHOD." | ||
| 333 | (when (stringp gnus-command-method) | ||
| 334 | (setq gnus-command-method (gnus-server-to-method gnus-command-method))) | ||
| 335 | (funcall (gnus-get-function gnus-command-method 'retrieve-group-data-early) | ||
| 336 | (nth 1 gnus-command-method) | ||
| 337 | infos)) | ||
| 338 | |||
| 322 | (defun gnus-request-list-newsgroups (gnus-command-method) | 339 | (defun gnus-request-list-newsgroups (gnus-command-method) |
| 323 | "Request the newsgroups file from GNUS-COMMAND-METHOD." | 340 | "Request the newsgroups file from GNUS-COMMAND-METHOD." |
| 324 | (when (stringp gnus-command-method) | 341 | (when (stringp gnus-command-method) |
| @@ -490,8 +507,7 @@ If BUFFER, insert the article in that group." | |||
| 490 | (setq res (gnus-request-article article group) | 507 | (setq res (gnus-request-article article group) |
| 491 | clean-up t))) | 508 | clean-up t))) |
| 492 | (when clean-up | 509 | (when clean-up |
| 493 | (save-excursion | 510 | (with-current-buffer nntp-server-buffer |
| 494 | (set-buffer nntp-server-buffer) | ||
| 495 | (goto-char (point-min)) | 511 | (goto-char (point-min)) |
| 496 | (when (search-forward "\n\n" nil t) | 512 | (when (search-forward "\n\n" nil t) |
| 497 | (delete-region (1- (point)) (point-max))) | 513 | (delete-region (1- (point)) (point-max))) |
| @@ -523,8 +539,7 @@ If BUFFER, insert the article in that group." | |||
| 523 | (setq res (gnus-request-article article group) | 539 | (setq res (gnus-request-article article group) |
| 524 | clean-up t))) | 540 | clean-up t))) |
| 525 | (when clean-up | 541 | (when clean-up |
| 526 | (save-excursion | 542 | (with-current-buffer nntp-server-buffer |
| 527 | (set-buffer nntp-server-buffer) | ||
| 528 | (goto-char (point-min)) | 543 | (goto-char (point-min)) |
| 529 | (when (search-forward "\n\n" nil t) | 544 | (when (search-forward "\n\n" nil t) |
| 530 | (delete-region (point-min) (1- (point)))))) | 545 | (delete-region (point-min) (1- (point)))))) |
diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index fc564490fc9..5483a741f2f 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el | |||
| @@ -349,8 +349,7 @@ If NEWSGROUP is nil, return the global kill file instead." | |||
| 349 | 349 | ||
| 350 | (defun gnus-expunge (marks) | 350 | (defun gnus-expunge (marks) |
| 351 | "Remove lines marked with MARKS." | 351 | "Remove lines marked with MARKS." |
| 352 | (save-excursion | 352 | (with-current-buffer gnus-summary-buffer |
| 353 | (set-buffer gnus-summary-buffer) | ||
| 354 | (gnus-summary-limit-to-marks marks 'reverse))) | 353 | (gnus-summary-limit-to-marks marks 'reverse))) |
| 355 | 354 | ||
| 356 | (defun gnus-apply-kill-file-unless-scored () | 355 | (defun gnus-apply-kill-file-unless-scored () |
| @@ -442,8 +441,7 @@ Returns the number of articles marked as read." | |||
| 442 | (progn | 441 | (progn |
| 443 | (delete-region beg (point)) | 442 | (delete-region beg (point)) |
| 444 | (insert (or (eval form) ""))) | 443 | (insert (or (eval form) ""))) |
| 445 | (save-excursion | 444 | (with-current-buffer gnus-summary-buffer |
| 446 | (set-buffer gnus-summary-buffer) | ||
| 447 | (ignore-errors (eval form))))) | 445 | (ignore-errors (eval form))))) |
| 448 | (and (buffer-modified-p) | 446 | (and (buffer-modified-p) |
| 449 | gnus-kill-save-kill-file | 447 | gnus-kill-save-kill-file |
| @@ -555,8 +553,7 @@ COMMAND must be a Lisp expression or a string representing a key sequence." | |||
| 555 | (and (eq 'quote (car (nth 2 object))) | 553 | (and (eq 'quote (car (nth 2 object))) |
| 556 | (not (consp (cdadr (nth 2 object)))))) | 554 | (not (consp (cdadr (nth 2 object)))))) |
| 557 | (concat "\n" (gnus-prin1-to-string object)) | 555 | (concat "\n" (gnus-prin1-to-string object)) |
| 558 | (save-excursion | 556 | (with-current-buffer (gnus-get-buffer-create "*Gnus PP*") |
| 559 | (set-buffer (gnus-get-buffer-create "*Gnus PP*")) | ||
| 560 | (buffer-disable-undo) | 557 | (buffer-disable-undo) |
| 561 | (erase-buffer) | 558 | (erase-buffer) |
| 562 | (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) | 559 | (insert (format "\n(%S %S\n '(" (nth 0 object) (nth 1 object))) |
| @@ -610,8 +607,7 @@ COMMAND must be a Lisp expression or a string representing a key sequence." | |||
| 610 | 6 "Searching for article: %d..." (mail-header-number header)) | 607 | 6 "Searching for article: %d..." (mail-header-number header)) |
| 611 | (gnus-article-setup-buffer) | 608 | (gnus-article-setup-buffer) |
| 612 | (gnus-article-prepare (mail-header-number header) t) | 609 | (gnus-article-prepare (mail-header-number header) t) |
| 613 | (when (save-excursion | 610 | (when (with-current-buffer gnus-article-buffer |
| 614 | (set-buffer gnus-article-buffer) | ||
| 615 | (goto-char (point-min)) | 611 | (goto-char (point-min)) |
| 616 | (setq did-kill (re-search-forward regexp nil t))) | 612 | (setq did-kill (re-search-forward regexp nil t))) |
| 617 | (cond ((stringp form) ;Keyboard macro. | 613 | (cond ((stringp form) ;Keyboard macro. |
diff --git a/lisp/gnus/gnus-logic.el b/lisp/gnus/gnus-logic.el index e6d28ae26aa..9637ebfb387 100644 --- a/lisp/gnus/gnus-logic.el +++ b/lisp/gnus/gnus-logic.el | |||
| @@ -179,8 +179,7 @@ | |||
| 179 | (defun gnus-advanced-body (header match type) | 179 | (defun gnus-advanced-body (header match type) |
| 180 | (when (string= header "all") | 180 | (when (string= header "all") |
| 181 | (setq header "article")) | 181 | (setq header "article")) |
| 182 | (save-excursion | 182 | (with-current-buffer nntp-server-buffer |
| 183 | (set-buffer nntp-server-buffer) | ||
| 184 | (let* ((request-func (cond ((string= "head" header) | 183 | (let* ((request-func (cond ((string= "head" header) |
| 185 | 'gnus-request-head) | 184 | 'gnus-request-head) |
| 186 | ((string= "body" header) | 185 | ((string= "body" header) |
diff --git a/lisp/gnus/gnus-range.el b/lisp/gnus/gnus-range.el index 5eb8080ac0a..a4262df5328 100644 --- a/lisp/gnus/gnus-range.el +++ b/lisp/gnus/gnus-range.el | |||
| @@ -59,6 +59,36 @@ If RANGE is a single range, return (RANGE). Otherwise, return RANGE." | |||
| 59 | (setq list2 (cdr list2))) | 59 | (setq list2 (cdr list2))) |
| 60 | list1)) | 60 | list1)) |
| 61 | 61 | ||
| 62 | (defun gnus-range-nconcat (&rest ranges) | ||
| 63 | "Return a range comprising all the RANGES, which are pre-sorted. | ||
| 64 | RANGES will be destructively altered." | ||
| 65 | (setq ranges (delete nil ranges)) | ||
| 66 | (let* ((result (gnus-range-normalize (pop ranges))) | ||
| 67 | (last (last result))) | ||
| 68 | (dolist (range ranges) | ||
| 69 | (setq range (gnus-range-normalize range)) | ||
| 70 | ;; Normalize the single-number case, so that we don't need to | ||
| 71 | ;; special-case that so much. | ||
| 72 | (when (numberp (car last)) | ||
| 73 | (setcar last (cons (car last) (car last)))) | ||
| 74 | (when (numberp (car range)) | ||
| 75 | (setcar range (cons (car range) (car range)))) | ||
| 76 | (if (= (1+ (cdar last)) (caar range)) | ||
| 77 | (progn | ||
| 78 | (setcdr (car last) (cdar range)) | ||
| 79 | (setcdr last (cdr range))) | ||
| 80 | (setcdr last range) | ||
| 81 | ;; Denormalize back, since we couldn't join the ranges up. | ||
| 82 | (when (= (caar range) (cdar range)) | ||
| 83 | (setcar range (caar range))) | ||
| 84 | (when (= (caar last) (cdar last)) | ||
| 85 | (setcar last (caar last)))) | ||
| 86 | (setq last (last last))) | ||
| 87 | (if (and (consp (car result)) | ||
| 88 | (= (length result) 1)) | ||
| 89 | (car result) | ||
| 90 | result))) | ||
| 91 | |||
| 62 | (defun gnus-range-difference (range1 range2) | 92 | (defun gnus-range-difference (range1 range2) |
| 63 | "Return the range of elements in RANGE1 that do not appear in RANGE2. | 93 | "Return the range of elements in RANGE1 that do not appear in RANGE2. |
| 64 | Both ranges must be in ascending order." | 94 | Both ranges must be in ascending order." |
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 8ba6c169bc4..a30847b0e2b 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el | |||
| @@ -241,8 +241,7 @@ considered precious) will not be trimmed." | |||
| 241 | "Save the registry cache file." | 241 | "Save the registry cache file." |
| 242 | (interactive) | 242 | (interactive) |
| 243 | (let ((file gnus-registry-cache-file)) | 243 | (let ((file gnus-registry-cache-file)) |
| 244 | (save-excursion | 244 | (with-current-buffer (gnus-get-buffer-create " *Gnus-registry-cache*") |
| 245 | (set-buffer (gnus-get-buffer-create " *Gnus-registry-cache*")) | ||
| 246 | (make-local-variable 'version-control) | 245 | (make-local-variable 'version-control) |
| 247 | (setq version-control gnus-backup-startup-file) | 246 | (setq version-control gnus-backup-startup-file) |
| 248 | (setq buffer-file-name file) | 247 | (setq buffer-file-name file) |
| @@ -674,8 +673,7 @@ Consults `gnus-registry-unfollowed-groups' and | |||
| 674 | word words) | 673 | word words) |
| 675 | (if (or (not (gnus-registry-fetch-extra id 'keywords)) | 674 | (if (or (not (gnus-registry-fetch-extra id 'keywords)) |
| 676 | force) | 675 | force) |
| 677 | (save-excursion | 676 | (with-current-buffer gnus-article-buffer |
| 678 | (set-buffer gnus-article-buffer) | ||
| 679 | (article-goto-body) | 677 | (article-goto-body) |
| 680 | (save-window-excursion | 678 | (save-window-excursion |
| 681 | (save-restriction | 679 | (save-restriction |
diff --git a/lisp/gnus/gnus-score.el b/lisp/gnus/gnus-score.el index bd4a39eb7b1..5cd60ddaabf 100644 --- a/lisp/gnus/gnus-score.el +++ b/lisp/gnus/gnus-score.el | |||
| @@ -708,8 +708,7 @@ file for the command instead of the current score file." | |||
| 708 | 708 | ||
| 709 | ;; Change score file to the "all.SCORE" file. | 709 | ;; Change score file to the "all.SCORE" file. |
| 710 | (when (eq symp 'a) | 710 | (when (eq symp 'a) |
| 711 | (save-excursion | 711 | (with-current-buffer gnus-summary-buffer |
| 712 | (set-buffer gnus-summary-buffer) | ||
| 713 | (gnus-score-load-file | 712 | (gnus-score-load-file |
| 714 | ;; This is a kludge; yes... | 713 | ;; This is a kludge; yes... |
| 715 | (cond | 714 | (cond |
| @@ -735,14 +734,12 @@ file for the command instead of the current score file." | |||
| 735 | 734 | ||
| 736 | (when (eq symp 'a) | 735 | (when (eq symp 'a) |
| 737 | ;; We change the score file back to the previous one. | 736 | ;; We change the score file back to the previous one. |
| 738 | (save-excursion | 737 | (with-current-buffer gnus-summary-buffer |
| 739 | (set-buffer gnus-summary-buffer) | ||
| 740 | (gnus-score-load-file current-score-file))))) | 738 | (gnus-score-load-file current-score-file))))) |
| 741 | 739 | ||
| 742 | (defun gnus-score-insert-help (string alist idx) | 740 | (defun gnus-score-insert-help (string alist idx) |
| 743 | (setq gnus-score-help-winconf (current-window-configuration)) | 741 | (setq gnus-score-help-winconf (current-window-configuration)) |
| 744 | (save-excursion | 742 | (with-current-buffer (gnus-get-buffer-create "*Score Help*") |
| 745 | (set-buffer (gnus-get-buffer-create "*Score Help*")) | ||
| 746 | (buffer-disable-undo) | 743 | (buffer-disable-undo) |
| 747 | (delete-windows-on (current-buffer)) | 744 | (delete-windows-on (current-buffer)) |
| 748 | (erase-buffer) | 745 | (erase-buffer) |
| @@ -1270,8 +1267,7 @@ If FORMAT, also format the current score file." | |||
| 1270 | exclude-files)) | 1267 | exclude-files)) |
| 1271 | gnus-scores-exclude-files)) | 1268 | gnus-scores-exclude-files)) |
| 1272 | (when local | 1269 | (when local |
| 1273 | (save-excursion | 1270 | (with-current-buffer gnus-summary-buffer |
| 1274 | (set-buffer gnus-summary-buffer) | ||
| 1275 | (while local | 1271 | (while local |
| 1276 | (and (consp (car local)) | 1272 | (and (consp (car local)) |
| 1277 | (symbolp (caar local)) | 1273 | (symbolp (caar local)) |
| @@ -1528,8 +1524,7 @@ If FORMAT, also format the current score file." | |||
| 1528 | (cons (cons header (or gnus-summary-default-score 0)) | 1524 | (cons (cons header (or gnus-summary-default-score 0)) |
| 1529 | gnus-scores-articles)))) | 1525 | gnus-scores-articles)))) |
| 1530 | 1526 | ||
| 1531 | (save-excursion | 1527 | (with-current-buffer (gnus-get-buffer-create "*Headers*") |
| 1532 | (set-buffer (gnus-get-buffer-create "*Headers*")) | ||
| 1533 | (buffer-disable-undo) | 1528 | (buffer-disable-undo) |
| 1534 | (when (gnus-buffer-live-p gnus-summary-buffer) | 1529 | (when (gnus-buffer-live-p gnus-summary-buffer) |
| 1535 | (message-clone-locals gnus-summary-buffer)) | 1530 | (message-clone-locals gnus-summary-buffer)) |
| @@ -1854,8 +1849,7 @@ score in `gnus-newsgroup-scored' by SCORE." | |||
| 1854 | 1849 | ||
| 1855 | ;; Change score file to the adaptive score file. All entries that | 1850 | ;; Change score file to the adaptive score file. All entries that |
| 1856 | ;; this function makes will be put into this file. | 1851 | ;; this function makes will be put into this file. |
| 1857 | (save-excursion | 1852 | (with-current-buffer gnus-summary-buffer |
| 1858 | (set-buffer gnus-summary-buffer) | ||
| 1859 | (gnus-score-load-file | 1853 | (gnus-score-load-file |
| 1860 | (or gnus-newsgroup-adaptive-score-file | 1854 | (or gnus-newsgroup-adaptive-score-file |
| 1861 | (gnus-score-file-name | 1855 | (gnus-score-file-name |
| @@ -1946,15 +1940,13 @@ score in `gnus-newsgroup-scored' by SCORE." | |||
| 1946 | (setq rest entries))) | 1940 | (setq rest entries))) |
| 1947 | (setq entries rest)))) | 1941 | (setq entries rest)))) |
| 1948 | ;; We change the score file back to the previous one. | 1942 | ;; We change the score file back to the previous one. |
| 1949 | (save-excursion | 1943 | (with-current-buffer gnus-summary-buffer |
| 1950 | (set-buffer gnus-summary-buffer) | ||
| 1951 | (gnus-score-load-file current-score-file)) | 1944 | (gnus-score-load-file current-score-file)) |
| 1952 | (list (cons "references" news))))) | 1945 | (list (cons "references" news))))) |
| 1953 | 1946 | ||
| 1954 | (defun gnus-score-add-followups (header score scores &optional thread) | 1947 | (defun gnus-score-add-followups (header score scores &optional thread) |
| 1955 | "Add a score entry to the adapt file." | 1948 | "Add a score entry to the adapt file." |
| 1956 | (save-excursion | 1949 | (with-current-buffer gnus-summary-buffer |
| 1957 | (set-buffer gnus-summary-buffer) | ||
| 1958 | (let* ((id (mail-header-id header)) | 1950 | (let* ((id (mail-header-id header)) |
| 1959 | (scores (car scores)) | 1951 | (scores (car scores)) |
| 1960 | entry dont) | 1952 | entry dont) |
| @@ -2282,8 +2274,7 @@ score in `gnus-newsgroup-scored' by SCORE." | |||
| 2282 | "Create adaptive score rules for this newsgroup." | 2274 | "Create adaptive score rules for this newsgroup." |
| 2283 | (when gnus-newsgroup-adaptive | 2275 | (when gnus-newsgroup-adaptive |
| 2284 | ;; We change the score file to the adaptive score file. | 2276 | ;; We change the score file to the adaptive score file. |
| 2285 | (save-excursion | 2277 | (with-current-buffer gnus-summary-buffer |
| 2286 | (set-buffer gnus-summary-buffer) | ||
| 2287 | (gnus-score-load-file | 2278 | (gnus-score-load-file |
| 2288 | (or gnus-newsgroup-adaptive-score-file | 2279 | (or gnus-newsgroup-adaptive-score-file |
| 2289 | (gnus-home-score-file gnus-newsgroup-name t) | 2280 | (gnus-home-score-file gnus-newsgroup-name t) |
| @@ -2697,8 +2688,7 @@ GROUP using BNews sys file syntax." | |||
| 2697 | (trans (cdr (assq ?: nnheader-file-name-translation-alist))) | 2688 | (trans (cdr (assq ?: nnheader-file-name-translation-alist))) |
| 2698 | (group-trans (nnheader-translate-file-chars group t)) | 2689 | (group-trans (nnheader-translate-file-chars group t)) |
| 2699 | ofiles not-match regexp) | 2690 | ofiles not-match regexp) |
| 2700 | (save-excursion | 2691 | (with-current-buffer (gnus-get-buffer-create "*gnus score files*") |
| 2701 | (set-buffer (gnus-get-buffer-create "*gnus score files*")) | ||
| 2702 | (buffer-disable-undo) | 2692 | (buffer-disable-undo) |
| 2703 | ;; Go through all score file names and create regexp with them | 2693 | ;; Go through all score file names and create regexp with them |
| 2704 | ;; as the source. | 2694 | ;; as the source. |
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 1c06a774203..e25d31ec87e 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el | |||
| @@ -594,8 +594,7 @@ Can be used to turn version control on or off." | |||
| 594 | (defun gnus-subscribe-hierarchically (newgroup) | 594 | (defun gnus-subscribe-hierarchically (newgroup) |
| 595 | "Subscribe new NEWGROUP and insert it in hierarchical newsgroup order." | 595 | "Subscribe new NEWGROUP and insert it in hierarchical newsgroup order." |
| 596 | ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams) | 596 | ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams) |
| 597 | (save-excursion | 597 | (with-current-buffer (nnheader-find-file-noselect gnus-current-startup-file) |
| 598 | (set-buffer (nnheader-find-file-noselect gnus-current-startup-file)) | ||
| 599 | (prog1 | 598 | (prog1 |
| 600 | (let ((groupkey newgroup) before) | 599 | (let ((groupkey newgroup) before) |
| 601 | (while (and (not before) groupkey) | 600 | (while (and (not before) groupkey) |
| @@ -857,8 +856,7 @@ prompt the user for the name of an NNTP server to use." | |||
| 857 | ;; it's not needed). | 856 | ;; it's not needed). |
| 858 | ;; (set-window-point (get-buffer-window (current-buffer)) (point-max)) | 857 | ;; (set-window-point (get-buffer-window (current-buffer)) (point-max)) |
| 859 | (bury-buffer gnus-dribble-buffer) | 858 | (bury-buffer gnus-dribble-buffer) |
| 860 | (save-excursion | 859 | (with-current-buffer gnus-group-buffer |
| 861 | (set-buffer gnus-group-buffer) | ||
| 862 | (gnus-group-set-mode-line)) | 860 | (gnus-group-set-mode-line)) |
| 863 | (set-buffer obuf)))) | 861 | (set-buffer obuf)))) |
| 864 | 862 | ||
| @@ -871,10 +869,9 @@ prompt the user for the name of an NNTP server to use." | |||
| 871 | (let ((dribble-file (gnus-dribble-file-name))) | 869 | (let ((dribble-file (gnus-dribble-file-name))) |
| 872 | (unless (file-exists-p (file-name-directory dribble-file)) | 870 | (unless (file-exists-p (file-name-directory dribble-file)) |
| 873 | (make-directory (file-name-directory dribble-file) t)) | 871 | (make-directory (file-name-directory dribble-file) t)) |
| 874 | (save-excursion | 872 | (with-current-buffer (setq gnus-dribble-buffer |
| 875 | (set-buffer (setq gnus-dribble-buffer | 873 | (gnus-get-buffer-create |
| 876 | (gnus-get-buffer-create | 874 | (file-name-nondirectory dribble-file))) |
| 877 | (file-name-nondirectory dribble-file)))) | ||
| 878 | (set (make-local-variable 'file-precious-flag) t) | 875 | (set (make-local-variable 'file-precious-flag) t) |
| 879 | (erase-buffer) | 876 | (erase-buffer) |
| 880 | (setq buffer-file-name dribble-file) | 877 | (setq buffer-file-name dribble-file) |
| @@ -923,8 +920,7 @@ prompt the user for the name of an NNTP server to use." | |||
| 923 | (when (file-exists-p (gnus-dribble-file-name)) | 920 | (when (file-exists-p (gnus-dribble-file-name)) |
| 924 | (delete-file (gnus-dribble-file-name))) | 921 | (delete-file (gnus-dribble-file-name))) |
| 925 | (when gnus-dribble-buffer | 922 | (when gnus-dribble-buffer |
| 926 | (save-excursion | 923 | (with-current-buffer gnus-dribble-buffer |
| 927 | (set-buffer gnus-dribble-buffer) | ||
| 928 | (let ((auto (make-auto-save-file-name))) | 924 | (let ((auto (make-auto-save-file-name))) |
| 929 | (when (file-exists-p auto) | 925 | (when (file-exists-p auto) |
| 930 | (delete-file auto)) | 926 | (delete-file auto)) |
| @@ -934,14 +930,12 @@ prompt the user for the name of an NNTP server to use." | |||
| 934 | (defun gnus-dribble-save () | 930 | (defun gnus-dribble-save () |
| 935 | (when (and gnus-dribble-buffer | 931 | (when (and gnus-dribble-buffer |
| 936 | (buffer-name gnus-dribble-buffer)) | 932 | (buffer-name gnus-dribble-buffer)) |
| 937 | (save-excursion | 933 | (with-current-buffer gnus-dribble-buffer |
| 938 | (set-buffer gnus-dribble-buffer) | ||
| 939 | (save-buffer)))) | 934 | (save-buffer)))) |
| 940 | 935 | ||
| 941 | (defun gnus-dribble-clear () | 936 | (defun gnus-dribble-clear () |
| 942 | (when (gnus-buffer-exists-p gnus-dribble-buffer) | 937 | (when (gnus-buffer-exists-p gnus-dribble-buffer) |
| 943 | (save-excursion | 938 | (with-current-buffer gnus-dribble-buffer |
| 944 | (set-buffer gnus-dribble-buffer) | ||
| 945 | (erase-buffer) | 939 | (erase-buffer) |
| 946 | (set-buffer-modified-p nil) | 940 | (set-buffer-modified-p nil) |
| 947 | (setq buffer-saved-size (buffer-size))))) | 941 | (setq buffer-saved-size (buffer-size))))) |
| @@ -1302,8 +1296,7 @@ for new groups, and subscribe the new groups as zombies." | |||
| 1302 | (when (gnus-active group) | 1296 | (when (gnus-active group) |
| 1303 | (gnus-group-change-level | 1297 | (gnus-group-change-level |
| 1304 | group gnus-level-default-subscribed gnus-level-killed))) | 1298 | group gnus-level-default-subscribed gnus-level-killed))) |
| 1305 | (save-excursion | 1299 | (with-current-buffer gnus-group-buffer |
| 1306 | (set-buffer gnus-group-buffer) | ||
| 1307 | ;; Don't error if the group already exists. This happens when a | 1300 | ;; Don't error if the group already exists. This happens when a |
| 1308 | ;; first-time user types 'F'. -- didier | 1301 | ;; first-time user types 'F'. -- didier |
| 1309 | (gnus-group-make-help-group t)) | 1302 | (gnus-group-make-help-group t)) |
| @@ -1734,7 +1727,7 @@ If SCAN, request a scan of that group as well." | |||
| 1734 | 'primary) | 1727 | 'primary) |
| 1735 | (t | 1728 | (t |
| 1736 | 'foreign))) | 1729 | 'foreign))) |
| 1737 | (push (setq method-group-list (list method method-type nil)) | 1730 | (push (setq method-group-list (list method method-type nil nil)) |
| 1738 | type-cache)) | 1731 | type-cache)) |
| 1739 | ;; Only add groups that need updating. | 1732 | ;; Only add groups that need updating. |
| 1740 | (if (<= (gnus-info-level info) | 1733 | (if (<= (gnus-info-level info) |
| @@ -1760,19 +1753,28 @@ If SCAN, request a scan of that group as well." | |||
| 1760 | (< (gnus-method-rank (cadr c1) (car c1)) | 1753 | (< (gnus-method-rank (cadr c1) (car c1)) |
| 1761 | (gnus-method-rank (cadr c2) (car c2)))))) | 1754 | (gnus-method-rank (cadr c2) (car c2)))))) |
| 1762 | 1755 | ||
| 1763 | (while type-cache | 1756 | ;; Start early async retrieval of data. |
| 1764 | (setq method (nth 0 (car type-cache)) | 1757 | (dolist (elem type-cache) |
| 1765 | method-type (nth 1 (car type-cache)) | 1758 | (destructuring-bind (method method-type infos dummy) elem |
| 1766 | infos (nth 2 (car type-cache))) | 1759 | (when (and method infos |
| 1767 | (pop type-cache) | 1760 | (not (gnus-method-denied-p method)) |
| 1768 | 1761 | (gnus-check-backend-function | |
| 1769 | (when (and method | 1762 | 'retrieve-group-data-early (car method))) |
| 1770 | infos) | 1763 | (when (gnus-check-backend-function 'request-scan (car method)) |
| 1771 | ;; See if any of the groups from this method require updating. | 1764 | (dolist (info infos) |
| 1772 | (gnus-read-active-for-groups method infos) | 1765 | (gnus-request-scan (gnus-info-group info) method))) |
| 1773 | (dolist (info infos) | 1766 | (setcar (nthcdr 3 elem) |
| 1774 | (inline (gnus-get-unread-articles-in-group | 1767 | (gnus-retrieve-group-data-early method infos))))) |
| 1775 | info (gnus-active (gnus-info-group info))))))) | 1768 | |
| 1769 | ;; Do the rest of the retrieval. | ||
| 1770 | (dolist (elem type-cache) | ||
| 1771 | (destructuring-bind (method method-type infos early-data) elem | ||
| 1772 | (when (and method infos) | ||
| 1773 | ;; See if any of the groups from this method require updating. | ||
| 1774 | (gnus-read-active-for-groups method infos early-data) | ||
| 1775 | (dolist (info infos) | ||
| 1776 | (inline (gnus-get-unread-articles-in-group | ||
| 1777 | info (gnus-active (gnus-info-group info)))))))) | ||
| 1776 | (gnus-message 6 "Checking new news...done"))) | 1778 | (gnus-message 6 "Checking new news...done"))) |
| 1777 | 1779 | ||
| 1778 | (defun gnus-method-rank (type method) | 1780 | (defun gnus-method-rank (type method) |
| @@ -1796,9 +1798,14 @@ If SCAN, request a scan of that group as well." | |||
| 1796 | (t | 1798 | (t |
| 1797 | 100))) | 1799 | 100))) |
| 1798 | 1800 | ||
| 1799 | (defun gnus-read-active-for-groups (method infos) | 1801 | (defun gnus-read-active-for-groups (method infos early-data) |
| 1800 | (with-current-buffer nntp-server-buffer | 1802 | (with-current-buffer nntp-server-buffer |
| 1801 | (cond | 1803 | (cond |
| 1804 | ((and | ||
| 1805 | (gnus-check-backend-function 'finish-retrieve-group-infos (car method)) | ||
| 1806 | (or (not (gnus-agent-method-p method)) | ||
| 1807 | (gnus-online method))) | ||
| 1808 | (gnus-finish-retrieve-group-infos method infos early-data)) | ||
| 1802 | ((gnus-check-backend-function 'retrieve-groups (car method)) | 1809 | ((gnus-check-backend-function 'retrieve-groups (car method)) |
| 1803 | (when (gnus-check-backend-function 'request-scan (car method)) | 1810 | (when (gnus-check-backend-function 'request-scan (car method)) |
| 1804 | (dolist (info infos) | 1811 | (dolist (info infos) |
| @@ -1867,8 +1874,7 @@ If SCAN, request a scan of that group as well." | |||
| 1867 | 1874 | ||
| 1868 | (defun gnus-parse-active () | 1875 | (defun gnus-parse-active () |
| 1869 | "Parse active info in the nntp server buffer." | 1876 | "Parse active info in the nntp server buffer." |
| 1870 | (save-excursion | 1877 | (with-current-buffer nntp-server-buffer |
| 1871 | (set-buffer nntp-server-buffer) | ||
| 1872 | (goto-char (point-min)) | 1878 | (goto-char (point-min)) |
| 1873 | ;; Parse the result we got from `gnus-request-group'. | 1879 | ;; Parse the result we got from `gnus-request-group'. |
| 1874 | (when (looking-at "[0-9]+ [0-9]+ \\([0-9]+\\) [0-9]+") | 1880 | (when (looking-at "[0-9]+ [0-9]+ \\([0-9]+\\) [0-9]+") |
| @@ -2022,8 +2028,7 @@ If SCAN, request a scan of that group as well." | |||
| 2022 | (list "archive"))))) | 2028 | (list "archive"))))) |
| 2023 | method) | 2029 | method) |
| 2024 | (setq gnus-have-read-active-file nil) | 2030 | (setq gnus-have-read-active-file nil) |
| 2025 | (save-excursion | 2031 | (with-current-buffer nntp-server-buffer |
| 2026 | (set-buffer nntp-server-buffer) | ||
| 2027 | (while (setq method (pop methods)) | 2032 | (while (setq method (pop methods)) |
| 2028 | ;; Only do each method once, in case the methods appear more | 2033 | ;; Only do each method once, in case the methods appear more |
| 2029 | ;; than once in this list. | 2034 | ;; than once in this list. |
| @@ -2089,8 +2094,7 @@ If SCAN, request a scan of that group as well." | |||
| 2089 | (defun gnus-read-active-file-2 (groups method) | 2094 | (defun gnus-read-active-file-2 (groups method) |
| 2090 | "Read an active file for GROUPS in METHOD using `gnus-retrieve-groups'." | 2095 | "Read an active file for GROUPS in METHOD using `gnus-retrieve-groups'." |
| 2091 | (when groups | 2096 | (when groups |
| 2092 | (save-excursion | 2097 | (with-current-buffer nntp-server-buffer |
| 2093 | (set-buffer nntp-server-buffer) | ||
| 2094 | (gnus-check-server method) | 2098 | (gnus-check-server method) |
| 2095 | (let ((list-type (gnus-retrieve-groups groups method))) | 2099 | (let ((list-type (gnus-retrieve-groups groups method))) |
| 2096 | (cond ((not list-type) | 2100 | (cond ((not list-type) |
| @@ -2771,8 +2775,7 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 2771 | (not force) | 2775 | (not force) |
| 2772 | (or (not gnus-dribble-buffer) | 2776 | (or (not gnus-dribble-buffer) |
| 2773 | (not (buffer-name gnus-dribble-buffer)) | 2777 | (not (buffer-name gnus-dribble-buffer)) |
| 2774 | (zerop (save-excursion | 2778 | (zerop (with-current-buffer gnus-dribble-buffer |
| 2775 | (set-buffer gnus-dribble-buffer) | ||
| 2776 | (buffer-size))))) | 2779 | (buffer-size))))) |
| 2777 | (gnus-message 4 "(No changes need to be saved)") | 2780 | (gnus-message 4 "(No changes need to be saved)") |
| 2778 | (gnus-run-hooks 'gnus-save-newsrc-hook) | 2781 | (gnus-run-hooks 'gnus-save-newsrc-hook) |
| @@ -2906,8 +2909,7 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 2906 | 2909 | ||
| 2907 | (defun gnus-gnus-to-newsrc-format () | 2910 | (defun gnus-gnus-to-newsrc-format () |
| 2908 | ;; Generate and save the .newsrc file. | 2911 | ;; Generate and save the .newsrc file. |
| 2909 | (save-excursion | 2912 | (with-current-buffer (create-file-buffer gnus-current-startup-file) |
| 2910 | (set-buffer (create-file-buffer gnus-current-startup-file)) | ||
| 2911 | (let ((newsrc (cdr gnus-newsrc-alist)) | 2913 | (let ((newsrc (cdr gnus-newsrc-alist)) |
| 2912 | (standard-output (current-buffer)) | 2914 | (standard-output (current-buffer)) |
| 2913 | info ranges range method) | 2915 | info ranges range method) |
| @@ -2980,8 +2982,7 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 2980 | (gnus-run-hooks 'gnus-slave-mode-hook)) | 2982 | (gnus-run-hooks 'gnus-slave-mode-hook)) |
| 2981 | 2983 | ||
| 2982 | (defun gnus-slave-save-newsrc () | 2984 | (defun gnus-slave-save-newsrc () |
| 2983 | (save-excursion | 2985 | (with-current-buffer gnus-dribble-buffer |
| 2984 | (set-buffer gnus-dribble-buffer) | ||
| 2985 | (let ((slave-name | 2986 | (let ((slave-name |
| 2986 | (mm-make-temp-file (concat gnus-current-startup-file "-slave-"))) | 2987 | (mm-make-temp-file (concat gnus-current-startup-file "-slave-"))) |
| 2987 | (modes (ignore-errors | 2988 | (modes (ignore-errors |
| @@ -3005,8 +3006,7 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 3005 | (if (not slave-files) | 3006 | (if (not slave-files) |
| 3006 | () ; There are no slave files to read. | 3007 | () ; There are no slave files to read. |
| 3007 | (gnus-message 7 "Reading slave newsrcs...") | 3008 | (gnus-message 7 "Reading slave newsrcs...") |
| 3008 | (save-excursion | 3009 | (with-current-buffer (gnus-get-buffer-create " *gnus slave*") |
| 3009 | (set-buffer (gnus-get-buffer-create " *gnus slave*")) | ||
| 3010 | (setq slave-files | 3010 | (setq slave-files |
| 3011 | (sort (mapcar (lambda (file) | 3011 | (sort (mapcar (lambda (file) |
| 3012 | (list (nth 5 (file-attributes file)) file)) | 3012 | (list (nth 5 (file-attributes file)) file)) |
| @@ -3126,8 +3126,7 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 3126 | (defun gnus-group-get-description (group) | 3126 | (defun gnus-group-get-description (group) |
| 3127 | "Get the description of a group by sending XGTITLE to the server." | 3127 | "Get the description of a group by sending XGTITLE to the server." |
| 3128 | (when (gnus-request-group-description group) | 3128 | (when (gnus-request-group-description group) |
| 3129 | (save-excursion | 3129 | (with-current-buffer nntp-server-buffer |
| 3130 | (set-buffer nntp-server-buffer) | ||
| 3131 | (goto-char (point-min)) | 3130 | (goto-char (point-min)) |
| 3132 | (when (looking-at "[^ \t]+[ \t]+\\(.*\\)") | 3131 | (when (looking-at "[^ \t]+[ \t]+\\(.*\\)") |
| 3133 | (match-string 1))))) | 3132 | (match-string 1))))) |
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index df20456b278..3c3a0590536 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el | |||
| @@ -5504,11 +5504,11 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 5504 | (mm-decode-coding-string (gnus-status-message group) charset)))) | 5504 | (mm-decode-coding-string (gnus-status-message group) charset)))) |
| 5505 | 5505 | ||
| 5506 | (unless (gnus-request-group group t) | 5506 | (unless (gnus-request-group group t) |
| 5507 | (when (equal major-mode 'gnus-summary-mode) | 5507 | (when (equal major-mode 'gnus-summary-mode) |
| 5508 | (gnus-kill-buffer (current-buffer))) | 5508 | (gnus-kill-buffer (current-buffer))) |
| 5509 | (error "Couldn't request group %s: %s" | 5509 | (error "Couldn't request group %s: %s" |
| 5510 | (mm-decode-coding-string group charset) | 5510 | (mm-decode-coding-string group charset) |
| 5511 | (mm-decode-coding-string (gnus-status-message group) charset))) | 5511 | (mm-decode-coding-string (gnus-status-message group) charset))) |
| 5512 | 5512 | ||
| 5513 | (when gnus-agent | 5513 | (when gnus-agent |
| 5514 | (gnus-agent-possibly-alter-active group (gnus-active group) info) | 5514 | (gnus-agent-possibly-alter-active group (gnus-active group) info) |
| @@ -7394,7 +7394,7 @@ If prefix argument NO-ARTICLE is non-nil, no article is selected initially." | |||
| 7394 | "Go to the first subject satisfying any non-nil constraint. | 7394 | "Go to the first subject satisfying any non-nil constraint. |
| 7395 | If UNREAD is non-nil, the article should be unread. | 7395 | If UNREAD is non-nil, the article should be unread. |
| 7396 | If UNDOWNLOADED is non-nil, the article should be undownloaded. | 7396 | If UNDOWNLOADED is non-nil, the article should be undownloaded. |
| 7397 | If UNSEEN is non-nil, the article should be unseen. | 7397 | If UNSEEN is non-nil, the article should be unseen as well as unread. |
| 7398 | Returns the article selected or nil if there are no matching articles." | 7398 | Returns the article selected or nil if there are no matching articles." |
| 7399 | (interactive "P") | 7399 | (interactive "P") |
| 7400 | (cond | 7400 | (cond |
| @@ -7417,7 +7417,8 @@ Returns the article selected or nil if there are no matching articles." | |||
| 7417 | (and undownloaded | 7417 | (and undownloaded |
| 7418 | (memq num gnus-newsgroup-undownloaded)) | 7418 | (memq num gnus-newsgroup-undownloaded)) |
| 7419 | (and unseen | 7419 | (and unseen |
| 7420 | (memq num gnus-newsgroup-unseen))))))) | 7420 | (memq num gnus-newsgroup-unseen) |
| 7421 | (memq num gnus-newsgroup-unreads))))))) | ||
| 7421 | (setq data (cdr data))) | 7422 | (setq data (cdr data))) |
| 7422 | (prog1 | 7423 | (prog1 |
| 7423 | (if data | 7424 | (if data |
| @@ -7908,8 +7909,8 @@ Return nil if there are no unseen articles." | |||
| 7908 | (gnus-summary-position-point))) | 7909 | (gnus-summary-position-point))) |
| 7909 | 7910 | ||
| 7910 | (defun gnus-summary-first-unseen-or-unread-subject () | 7911 | (defun gnus-summary-first-unseen-or-unread-subject () |
| 7911 | "Place the point on the subject line of the first unseen article or, | 7912 | "Place the point on the subject line of the first unseen and unread article. |
| 7912 | if all article have been seen, on the subject line of the first unread | 7913 | If all article have been seen, on the subject line of the first unread |
| 7913 | article." | 7914 | article." |
| 7914 | (interactive) | 7915 | (interactive) |
| 7915 | (prog1 | 7916 | (prog1 |
| @@ -9690,7 +9691,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." | |||
| 9690 | to-newsgroup (list 'quote select-method) | 9691 | to-newsgroup (list 'quote select-method) |
| 9691 | (not articles) t) ; Accept form | 9692 | (not articles) t) ; Accept form |
| 9692 | (not articles) ; Only save nov last time | 9693 | (not articles) ; Only save nov last time |
| 9693 | move-is-internal))) ; is this move internal? | 9694 | (and move-is-internal |
| 9695 | (gnus-group-real-name to-newsgroup))))) ; is this move internal? | ||
| 9694 | ;; Copy the article. | 9696 | ;; Copy the article. |
| 9695 | ((eq action 'copy) | 9697 | ((eq action 'copy) |
| 9696 | (with-current-buffer copy-buf | 9698 | (with-current-buffer copy-buf |
| @@ -9821,8 +9823,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." | |||
| 9821 | (gnus-add-marked-articles | 9823 | (gnus-add-marked-articles |
| 9822 | to-group 'expire (list to-article) info)) | 9824 | to-group 'expire (list to-article) info)) |
| 9823 | 9825 | ||
| 9824 | (gnus-request-set-mark | 9826 | (when to-marks |
| 9825 | to-group (list (list (list to-article) 'add to-marks)))) | 9827 | (gnus-request-set-mark |
| 9828 | to-group (list (list (list to-article) 'add to-marks))))) | ||
| 9826 | 9829 | ||
| 9827 | (gnus-dribble-enter | 9830 | (gnus-dribble-enter |
| 9828 | (concat "(gnus-group-set-info '" | 9831 | (concat "(gnus-group-set-info '" |
diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el index 89e61bcb598..7c710357b9d 100644 --- a/lisp/gnus/gnus-topic.el +++ b/lisp/gnus/gnus-topic.el | |||
| @@ -148,8 +148,7 @@ See Info node `(gnus)Formatting Variables'." | |||
| 148 | 148 | ||
| 149 | (defun gnus-group-parent-topic (group) | 149 | (defun gnus-group-parent-topic (group) |
| 150 | "Return the topic GROUP is member of by looking at the group buffer." | 150 | "Return the topic GROUP is member of by looking at the group buffer." |
| 151 | (save-excursion | 151 | (with-current-buffer gnus-group-buffer |
| 152 | (set-buffer gnus-group-buffer) | ||
| 153 | (if (gnus-group-goto-group group) | 152 | (if (gnus-group-goto-group group) |
| 154 | (gnus-current-topic) | 153 | (gnus-current-topic) |
| 155 | (gnus-group-topic group)))) | 154 | (gnus-group-topic group)))) |
| @@ -912,8 +911,7 @@ articles in the topic and its subtopics." | |||
| 912 | 911 | ||
| 913 | (defun gnus-topic-change-level (group level oldlevel &optional previous) | 912 | (defun gnus-topic-change-level (group level oldlevel &optional previous) |
| 914 | "Run when changing levels to enter/remove groups from topics." | 913 | "Run when changing levels to enter/remove groups from topics." |
| 915 | (save-excursion | 914 | (with-current-buffer gnus-group-buffer |
| 916 | (set-buffer gnus-group-buffer) | ||
| 917 | (let ((buffer-read-only nil)) | 915 | (let ((buffer-read-only nil)) |
| 918 | (unless gnus-topic-inhibit-change-level | 916 | (unless gnus-topic-inhibit-change-level |
| 919 | (gnus-group-goto-group (or (car (nth 2 previous)) group)) | 917 | (gnus-group-goto-group (or (car (nth 2 previous)) group)) |
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el index 7cdb70a3580..334f0eea7db 100644 --- a/lisp/gnus/gnus-util.el +++ b/lisp/gnus/gnus-util.el | |||
| @@ -1115,8 +1115,7 @@ FILENAME exists and is Babyl format." | |||
| 1115 | (gnus-yes-or-no-p | 1115 | (gnus-yes-or-no-p |
| 1116 | (concat "\"" filename "\" does not exist, create it? "))) | 1116 | (concat "\"" filename "\" does not exist, create it? "))) |
| 1117 | (let ((file-buffer (create-file-buffer filename))) | 1117 | (let ((file-buffer (create-file-buffer filename))) |
| 1118 | (save-excursion | 1118 | (with-current-buffer file-buffer |
| 1119 | (set-buffer file-buffer) | ||
| 1120 | (if (fboundp 'rmail-insert-rmail-file-header) | 1119 | (if (fboundp 'rmail-insert-rmail-file-header) |
| 1121 | (rmail-insert-rmail-file-header)) | 1120 | (rmail-insert-rmail-file-header)) |
| 1122 | (let ((require-final-newline nil) | 1121 | (let ((require-final-newline nil) |
| @@ -1194,8 +1193,7 @@ FILENAME exists and is Babyl format." | |||
| 1194 | (gnus-y-or-n-p | 1193 | (gnus-y-or-n-p |
| 1195 | (concat "\"" filename "\" does not exist, create it? "))) | 1194 | (concat "\"" filename "\" does not exist, create it? "))) |
| 1196 | (let ((file-buffer (create-file-buffer filename))) | 1195 | (let ((file-buffer (create-file-buffer filename))) |
| 1197 | (save-excursion | 1196 | (with-current-buffer file-buffer |
| 1198 | (set-buffer file-buffer) | ||
| 1199 | (let ((require-final-newline nil) | 1197 | (let ((require-final-newline nil) |
| 1200 | (coding-system-for-write mm-text-coding-system)) | 1198 | (coding-system-for-write mm-text-coding-system)) |
| 1201 | (gnus-write-buffer filename))) | 1199 | (gnus-write-buffer filename))) |
| @@ -1274,8 +1272,7 @@ This function saves the current buffer." | |||
| 1274 | "Say whether Gnus is running or not." | 1272 | "Say whether Gnus is running or not." |
| 1275 | (and (boundp 'gnus-group-buffer) | 1273 | (and (boundp 'gnus-group-buffer) |
| 1276 | (get-buffer gnus-group-buffer) | 1274 | (get-buffer gnus-group-buffer) |
| 1277 | (save-excursion | 1275 | (with-current-buffer gnus-group-buffer |
| 1278 | (set-buffer gnus-group-buffer) | ||
| 1279 | (eq major-mode 'gnus-group-mode)))) | 1276 | (eq major-mode 'gnus-group-mode)))) |
| 1280 | 1277 | ||
| 1281 | (defun gnus-remove-if (predicate list) | 1278 | (defun gnus-remove-if (predicate list) |
diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el index 35120eae767..614a52c176c 100644 --- a/lisp/gnus/gnus-uu.el +++ b/lisp/gnus/gnus-uu.el | |||
| @@ -827,8 +827,7 @@ When called interactively, prompt for REGEXP." | |||
| 827 | (defun gnus-uu-save-article (buffer in-state) | 827 | (defun gnus-uu-save-article (buffer in-state) |
| 828 | (cond | 828 | (cond |
| 829 | (gnus-uu-save-separate-articles | 829 | (gnus-uu-save-separate-articles |
| 830 | (save-excursion | 830 | (with-current-buffer buffer |
| 831 | (set-buffer buffer) | ||
| 832 | (let ((coding-system-for-write mm-text-coding-system)) | 831 | (let ((coding-system-for-write mm-text-coding-system)) |
| 833 | (gnus-write-buffer | 832 | (gnus-write-buffer |
| 834 | (concat gnus-uu-saved-article-name gnus-current-article))) | 833 | (concat gnus-uu-saved-article-name gnus-current-article))) |
| @@ -838,8 +837,7 @@ When called interactively, prompt for REGEXP." | |||
| 838 | ((eq in-state 'last) (list 'end)) | 837 | ((eq in-state 'last) (list 'end)) |
| 839 | (t (list 'middle))))) | 838 | (t (list 'middle))))) |
| 840 | ((not gnus-uu-save-in-digest) | 839 | ((not gnus-uu-save-in-digest) |
| 841 | (save-excursion | 840 | (with-current-buffer buffer |
| 842 | (set-buffer buffer) | ||
| 843 | (write-region (point-min) (point-max) gnus-uu-saved-article-name t) | 841 | (write-region (point-min) (point-max) gnus-uu-saved-article-name t) |
| 844 | (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) | 842 | (cond ((eq in-state 'first) (list gnus-uu-saved-article-name 'begin)) |
| 845 | ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name | 843 | ((eq in-state 'first-and-last) (list gnus-uu-saved-article-name |
| @@ -857,11 +855,9 @@ When called interactively, prompt for REGEXP." | |||
| 857 | (eq in-state 'first-and-last)) | 855 | (eq in-state 'first-and-last)) |
| 858 | (progn | 856 | (progn |
| 859 | (setq state (list 'begin)) | 857 | (setq state (list 'begin)) |
| 860 | (save-excursion | 858 | (with-current-buffer (gnus-get-buffer-create "*gnus-uu-body*") |
| 861 | (set-buffer (gnus-get-buffer-create "*gnus-uu-body*")) | ||
| 862 | (erase-buffer)) | 859 | (erase-buffer)) |
| 863 | (save-excursion | 860 | (with-current-buffer (gnus-get-buffer-create "*gnus-uu-pre*") |
| 864 | (set-buffer (gnus-get-buffer-create "*gnus-uu-pre*")) | ||
| 865 | (erase-buffer) | 861 | (erase-buffer) |
| 866 | (insert (format | 862 | (insert (format |
| 867 | "Date: %s\nFrom: %s\nSubject: %s Digest\n\n" | 863 | "Date: %s\nFrom: %s\nSubject: %s Digest\n\n" |
| @@ -873,8 +869,7 @@ When called interactively, prompt for REGEXP." | |||
| 873 | (insert "Topics:\n"))) | 869 | (insert "Topics:\n"))) |
| 874 | (when (not (eq in-state 'end)) | 870 | (when (not (eq in-state 'end)) |
| 875 | (setq state (list 'middle)))) | 871 | (setq state (list 'middle)))) |
| 876 | (save-excursion | 872 | (with-current-buffer "*gnus-uu-body*" |
| 877 | (set-buffer "*gnus-uu-body*") | ||
| 878 | (goto-char (setq beg (point-max))) | 873 | (goto-char (setq beg (point-max))) |
| 879 | (save-excursion | 874 | (save-excursion |
| 880 | (save-restriction | 875 | (save-restriction |
| @@ -940,8 +935,7 @@ When called interactively, prompt for REGEXP." | |||
| 940 | (when (re-search-forward "^Subject: \\(.*\\)$" nil t) | 935 | (when (re-search-forward "^Subject: \\(.*\\)$" nil t) |
| 941 | (setq subj (buffer-substring (match-beginning 1) (match-end 1)))) | 936 | (setq subj (buffer-substring (match-beginning 1) (match-end 1)))) |
| 942 | (when subj | 937 | (when subj |
| 943 | (save-excursion | 938 | (with-current-buffer "*gnus-uu-pre*" |
| 944 | (set-buffer "*gnus-uu-pre*") | ||
| 945 | (insert (format " %s\n" subj))))) | 939 | (insert (format " %s\n" subj))))) |
| 946 | (when (or (eq in-state 'last) | 940 | (when (or (eq in-state 'last) |
| 947 | (eq in-state 'first-and-last)) | 941 | (eq in-state 'first-and-last)) |
| @@ -951,8 +945,7 @@ When called interactively, prompt for REGEXP." | |||
| 951 | (insert-buffer-substring "*gnus-uu-pre*") | 945 | (insert-buffer-substring "*gnus-uu-pre*") |
| 952 | (goto-char (point-max)) | 946 | (goto-char (point-max)) |
| 953 | (insert-buffer-substring "*gnus-uu-body*")) | 947 | (insert-buffer-substring "*gnus-uu-body*")) |
| 954 | (save-excursion | 948 | (with-current-buffer "*gnus-uu-pre*" |
| 955 | (set-buffer "*gnus-uu-pre*") | ||
| 956 | (insert (format "\n\n%s\n\n" (make-string 70 ?-))) | 949 | (insert (format "\n\n%s\n\n" (make-string 70 ?-))) |
| 957 | (if gnus-uu-digest-buffer | 950 | (if gnus-uu-digest-buffer |
| 958 | (with-current-buffer gnus-uu-digest-buffer | 951 | (with-current-buffer gnus-uu-digest-buffer |
| @@ -960,8 +953,7 @@ When called interactively, prompt for REGEXP." | |||
| 960 | (insert-buffer-substring "*gnus-uu-pre*")) | 953 | (insert-buffer-substring "*gnus-uu-pre*")) |
| 961 | (let ((coding-system-for-write mm-text-coding-system)) | 954 | (let ((coding-system-for-write mm-text-coding-system)) |
| 962 | (gnus-write-buffer gnus-uu-saved-article-name)))) | 955 | (gnus-write-buffer gnus-uu-saved-article-name)))) |
| 963 | (save-excursion | 956 | (with-current-buffer "*gnus-uu-body*" |
| 964 | (set-buffer "*gnus-uu-body*") | ||
| 965 | (goto-char (point-max)) | 957 | (goto-char (point-max)) |
| 966 | (insert | 958 | (insert |
| 967 | (concat (setq end-string (format "End of %s Digest" name)) | 959 | (concat (setq end-string (format "End of %s Digest" name)) |
| @@ -993,8 +985,7 @@ When called interactively, prompt for REGEXP." | |||
| 993 | 985 | ||
| 994 | (defun gnus-uu-binhex-article (buffer in-state) | 986 | (defun gnus-uu-binhex-article (buffer in-state) |
| 995 | (let (state start-char) | 987 | (let (state start-char) |
| 996 | (save-excursion | 988 | (with-current-buffer buffer |
| 997 | (set-buffer buffer) | ||
| 998 | (widen) | 989 | (widen) |
| 999 | (goto-char (point-min)) | 990 | (goto-char (point-min)) |
| 1000 | (when (not (re-search-forward gnus-uu-binhex-begin-line nil t)) | 991 | (when (not (re-search-forward gnus-uu-binhex-begin-line nil t)) |
| @@ -1030,8 +1021,7 @@ When called interactively, prompt for REGEXP." | |||
| 1030 | ;; yEnc | 1021 | ;; yEnc |
| 1031 | 1022 | ||
| 1032 | (defun gnus-uu-yenc-article (buffer in-state) | 1023 | (defun gnus-uu-yenc-article (buffer in-state) |
| 1033 | (save-excursion | 1024 | (with-current-buffer gnus-original-article-buffer |
| 1034 | (set-buffer gnus-original-article-buffer) | ||
| 1035 | (widen) | 1025 | (widen) |
| 1036 | (let ((file-name (yenc-extract-filename)) | 1026 | (let ((file-name (yenc-extract-filename)) |
| 1037 | state start-char) | 1027 | state start-char) |
| @@ -1065,8 +1055,7 @@ When called interactively, prompt for REGEXP." | |||
| 1065 | (defun gnus-uu-decode-postscript-article (process-buffer in-state) | 1055 | (defun gnus-uu-decode-postscript-article (process-buffer in-state) |
| 1066 | (let ((state (list 'ok)) | 1056 | (let ((state (list 'ok)) |
| 1067 | start-char end-char file-name) | 1057 | start-char end-char file-name) |
| 1068 | (save-excursion | 1058 | (with-current-buffer process-buffer |
| 1069 | (set-buffer process-buffer) | ||
| 1070 | (goto-char (point-min)) | 1059 | (goto-char (point-min)) |
| 1071 | (if (not (re-search-forward gnus-uu-postscript-begin-string nil t)) | 1060 | (if (not (re-search-forward gnus-uu-postscript-begin-string nil t)) |
| 1072 | (setq state (list 'wrong-type)) | 1061 | (setq state (list 'wrong-type)) |
| @@ -1128,8 +1117,7 @@ When called interactively, prompt for REGEXP." | |||
| 1128 | ;; replaces the last thing that looks like "2/3" with "[0-9]+/3" | 1117 | ;; replaces the last thing that looks like "2/3" with "[0-9]+/3" |
| 1129 | ;; or, if it can't find something like that, tries "2 of 3", then | 1118 | ;; or, if it can't find something like that, tries "2 of 3", then |
| 1130 | ;; finally just replaces the next to last number with "[0-9]+". | 1119 | ;; finally just replaces the next to last number with "[0-9]+". |
| 1131 | (save-excursion | 1120 | (with-current-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name) |
| 1132 | (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) | ||
| 1133 | (buffer-disable-undo) | 1121 | (buffer-disable-undo) |
| 1134 | (erase-buffer) | 1122 | (erase-buffer) |
| 1135 | (insert (regexp-quote string)) | 1123 | (insert (regexp-quote string)) |
| @@ -1228,8 +1216,7 @@ When called interactively, prompt for REGEXP." | |||
| 1228 | ;; decoded in. Returns the list of expanded strings. | 1216 | ;; decoded in. Returns the list of expanded strings. |
| 1229 | (let ((out-list string-list) | 1217 | (let ((out-list string-list) |
| 1230 | string) | 1218 | string) |
| 1231 | (save-excursion | 1219 | (with-current-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name) |
| 1232 | (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) | ||
| 1233 | (buffer-disable-undo) | 1220 | (buffer-disable-undo) |
| 1234 | (while string-list | 1221 | (while string-list |
| 1235 | (erase-buffer) | 1222 | (erase-buffer) |
| @@ -1332,11 +1319,9 @@ When called interactively, prompt for REGEXP." | |||
| 1332 | (gnus-summary-display-article article) | 1319 | (gnus-summary-display-article article) |
| 1333 | 1320 | ||
| 1334 | ;; Push the article to the processing function. | 1321 | ;; Push the article to the processing function. |
| 1335 | (save-excursion | 1322 | (with-current-buffer gnus-original-article-buffer |
| 1336 | (set-buffer gnus-original-article-buffer) | ||
| 1337 | (let ((buffer-read-only nil)) | 1323 | (let ((buffer-read-only nil)) |
| 1338 | (save-excursion | 1324 | (with-current-buffer gnus-summary-buffer |
| 1339 | (set-buffer gnus-summary-buffer) | ||
| 1340 | (setq process-state | 1325 | (setq process-state |
| 1341 | (funcall process-function | 1326 | (funcall process-function |
| 1342 | gnus-original-article-buffer state))))) | 1327 | gnus-original-article-buffer state))))) |
| @@ -1477,8 +1462,7 @@ When called interactively, prompt for REGEXP." | |||
| 1477 | 1462 | ||
| 1478 | (defun gnus-uu-uustrip-article (process-buffer in-state) | 1463 | (defun gnus-uu-uustrip-article (process-buffer in-state) |
| 1479 | ;; Uudecodes a file asynchronously. | 1464 | ;; Uudecodes a file asynchronously. |
| 1480 | (save-excursion | 1465 | (with-current-buffer process-buffer |
| 1481 | (set-buffer process-buffer) | ||
| 1482 | (let ((state (list 'wrong-type)) | 1466 | (let ((state (list 'wrong-type)) |
| 1483 | process-connection-type case-fold-search buffer-read-only | 1467 | process-connection-type case-fold-search buffer-read-only |
| 1484 | files start-char) | 1468 | files start-char) |
| @@ -1600,8 +1584,7 @@ Gnus might fail to display all of it.") | |||
| 1600 | (defun gnus-uu-unshar-article (process-buffer in-state) | 1584 | (defun gnus-uu-unshar-article (process-buffer in-state) |
| 1601 | (let ((state (list 'ok)) | 1585 | (let ((state (list 'ok)) |
| 1602 | start-char) | 1586 | start-char) |
| 1603 | (save-excursion | 1587 | (with-current-buffer process-buffer |
| 1604 | (set-buffer process-buffer) | ||
| 1605 | (goto-char (point-min)) | 1588 | (goto-char (point-min)) |
| 1606 | (if (not (re-search-forward gnus-uu-shar-begin-string nil t)) | 1589 | (if (not (re-search-forward gnus-uu-shar-begin-string nil t)) |
| 1607 | (setq state (list 'wrong-type)) | 1590 | (setq state (list 'wrong-type)) |
| @@ -1688,8 +1671,7 @@ Gnus might fail to display all of it.") | |||
| 1688 | 1671 | ||
| 1689 | (setq command (format "cd %s ; %s" dir (gnus-uu-command action file-path))) | 1672 | (setq command (format "cd %s ; %s" dir (gnus-uu-command action file-path))) |
| 1690 | 1673 | ||
| 1691 | (save-excursion | 1674 | (with-current-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name) |
| 1692 | (set-buffer (gnus-get-buffer-create gnus-uu-output-buffer-name)) | ||
| 1693 | (erase-buffer)) | 1675 | (erase-buffer)) |
| 1694 | 1676 | ||
| 1695 | (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path)) | 1677 | (gnus-message 5 "Unpacking: %s..." (gnus-uu-command action file-path)) |
| @@ -2039,9 +2021,8 @@ If no file has been included, the user will be asked for a file." | |||
| 2039 | (setq file-name file-path)) | 2021 | (setq file-name file-path)) |
| 2040 | 2022 | ||
| 2041 | (unwind-protect | 2023 | (unwind-protect |
| 2042 | (if (save-excursion | 2024 | (if (with-current-buffer |
| 2043 | (set-buffer (setq uubuf | 2025 | (setq uubuf (gnus-get-buffer-create uuencode-buffer-name)) |
| 2044 | (gnus-get-buffer-create uuencode-buffer-name))) | ||
| 2045 | (erase-buffer) | 2026 | (erase-buffer) |
| 2046 | (funcall gnus-uu-post-encode-method file-path file-name)) | 2027 | (funcall gnus-uu-post-encode-method file-path file-name)) |
| 2047 | (insert-buffer-substring uubuf) | 2028 | (insert-buffer-substring uubuf) |
| @@ -2073,8 +2054,8 @@ If no file has been included, the user will be asked for a file." | |||
| 2073 | (setq beg-binary (point)) | 2054 | (setq beg-binary (point)) |
| 2074 | (setq end-binary (point-max)) | 2055 | (setq end-binary (point-max)) |
| 2075 | 2056 | ||
| 2076 | (save-excursion | 2057 | (with-current-buffer |
| 2077 | (set-buffer (setq uubuf (gnus-get-buffer-create encoded-buffer-name))) | 2058 | (setq uubuf (gnus-get-buffer-create encoded-buffer-name)) |
| 2078 | (erase-buffer) | 2059 | (erase-buffer) |
| 2079 | (insert-buffer-substring post-buf beg-binary end-binary) | 2060 | (insert-buffer-substring post-buf beg-binary end-binary) |
| 2080 | (goto-char (point-min)) | 2061 | (goto-char (point-min)) |
| @@ -2129,8 +2110,7 @@ If no file has been included, the user will be asked for a file." | |||
| 2129 | (insert (format " (%d/%d)" i parts))) | 2110 | (insert (format " (%d/%d)" i parts))) |
| 2130 | 2111 | ||
| 2131 | (goto-char (point-max)) | 2112 | (goto-char (point-max)) |
| 2132 | (save-excursion | 2113 | (with-current-buffer uubuf |
| 2133 | (set-buffer uubuf) | ||
| 2134 | (goto-char beg) | 2114 | (goto-char beg) |
| 2135 | (if (= i parts) | 2115 | (if (= i parts) |
| 2136 | (goto-char (point-max)) | 2116 | (goto-char (point-max)) |
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 797f8a44bd1..2173d713d11 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el | |||
| @@ -2743,6 +2743,8 @@ a string, be sure to use a valid format, see RFC 2616." | |||
| 2743 | '((seen range) | 2743 | '((seen range) |
| 2744 | (killed range) | 2744 | (killed range) |
| 2745 | (bookmark tuple) | 2745 | (bookmark tuple) |
| 2746 | (uid tuple) | ||
| 2747 | (active tuple) | ||
| 2746 | (score tuple))) | 2748 | (score tuple))) |
| 2747 | 2749 | ||
| 2748 | ;; Propagate flags to server, with the following exceptions: | 2750 | ;; Propagate flags to server, with the following exceptions: |
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index c4cbce4abaf..948fc08135d 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el | |||
| @@ -114,6 +114,7 @@ | |||
| 114 | "Render of HTML contents. | 114 | "Render of HTML contents. |
| 115 | It is one of defined renderer types, or a rendering function. | 115 | It is one of defined renderer types, or a rendering function. |
| 116 | The defined renderer types are: | 116 | The defined renderer types are: |
| 117 | `gnus-article-html' : use Gnus renderer based on w3m; | ||
| 117 | `w3m' : use emacs-w3m; | 118 | `w3m' : use emacs-w3m; |
| 118 | `w3m-standalone': use w3m; | 119 | `w3m-standalone': use w3m; |
| 119 | `links': use links; | 120 | `links': use links; |
| @@ -122,8 +123,9 @@ The defined renderer types are: | |||
| 122 | `html2text' : use html2text; | 123 | `html2text' : use html2text; |
| 123 | nil : use external viewer (default web browser)." | 124 | nil : use external viewer (default web browser)." |
| 124 | :version "24.1" | 125 | :version "24.1" |
| 125 | :type '(choice (const w3) | 126 | :type '(choice (const gnus-article-html) |
| 126 | (const w3m :tag "emacs-w3m") | 127 | (const w3) |
| 128 | (const w3m :tag "emacs-w3m") | ||
| 127 | (const w3m-standalone :tag "standalone w3m" ) | 129 | (const w3m-standalone :tag "standalone w3m" ) |
| 128 | (const links) | 130 | (const links) |
| 129 | (const lynx) | 131 | (const lynx) |
diff --git a/lisp/gnus/mm-partial.el b/lisp/gnus/mm-partial.el index 3fec4a2a975..6509b648fe7 100644 --- a/lisp/gnus/mm-partial.el +++ b/lisp/gnus/mm-partial.el | |||
| @@ -70,8 +70,7 @@ If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." | |||
| 70 | (sort (cons handle | 70 | (sort (cons handle |
| 71 | (mm-partial-find-parts | 71 | (mm-partial-find-parts |
| 72 | id | 72 | id |
| 73 | (save-excursion | 73 | (with-current-buffer gnus-summary-buffer |
| 74 | (set-buffer gnus-summary-buffer) | ||
| 75 | (gnus-summary-article-number)))) | 74 | (gnus-summary-article-number)))) |
| 76 | #'(lambda (a b) | 75 | #'(lambda (a b) |
| 77 | (let ((anumber (string-to-number | 76 | (let ((anumber (string-to-number |
| @@ -83,8 +82,7 @@ If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." | |||
| 83 | (< anumber bnumber))))) | 82 | (< anumber bnumber))))) |
| 84 | (setq gnus-article-mime-handles | 83 | (setq gnus-article-mime-handles |
| 85 | (mm-merge-handles gnus-article-mime-handles phandles)) | 84 | (mm-merge-handles gnus-article-mime-handles phandles)) |
| 86 | (save-excursion | 85 | (with-current-buffer (generate-new-buffer " *mm*") |
| 87 | (set-buffer (generate-new-buffer " *mm*")) | ||
| 88 | (while (setq phandle (pop phandles)) | 86 | (while (setq phandle (pop phandles)) |
| 89 | (setq nn (string-to-number | 87 | (setq nn (string-to-number |
| 90 | (cdr (assq 'number | 88 | (cdr (assq 'number |
diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el index 263d721dad2..ccd4e890da7 100644 --- a/lisp/gnus/nnagent.el +++ b/lisp/gnus/nnagent.el | |||
| @@ -252,6 +252,9 @@ | |||
| 252 | (nnoo-parent-function 'nnagent 'nnml-request-regenerate | 252 | (nnoo-parent-function 'nnagent 'nnml-request-regenerate |
| 253 | (list (nnagent-server server)))) | 253 | (list (nnagent-server server)))) |
| 254 | 254 | ||
| 255 | (deffoo nnagent-retrieve-group-data-early (server infos) | ||
| 256 | nil) | ||
| 257 | |||
| 255 | ;; Use nnml functions for just about everything. | 258 | ;; Use nnml functions for just about everything. |
| 256 | (nnoo-import nnagent | 259 | (nnoo-import nnagent |
| 257 | (nnml)) | 260 | (nnml)) |
diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el index 58e848bcb5c..512de38559d 100644 --- a/lisp/gnus/nnbabyl.el +++ b/lisp/gnus/nnbabyl.el | |||
| @@ -75,8 +75,7 @@ | |||
| 75 | (nnoo-define-basics nnbabyl) | 75 | (nnoo-define-basics nnbabyl) |
| 76 | 76 | ||
| 77 | (deffoo nnbabyl-retrieve-headers (articles &optional group server fetch-old) | 77 | (deffoo nnbabyl-retrieve-headers (articles &optional group server fetch-old) |
| 78 | (save-excursion | 78 | (with-current-buffer nntp-server-buffer |
| 79 | (set-buffer nntp-server-buffer) | ||
| 80 | (erase-buffer) | 79 | (erase-buffer) |
| 81 | (let ((number (length articles)) | 80 | (let ((number (length articles)) |
| 82 | (count 0) | 81 | (count 0) |
| @@ -136,8 +135,7 @@ | |||
| 136 | ;; Restore buffer mode. | 135 | ;; Restore buffer mode. |
| 137 | (when (and (nnbabyl-server-opened) | 136 | (when (and (nnbabyl-server-opened) |
| 138 | nnbabyl-previous-buffer-mode) | 137 | nnbabyl-previous-buffer-mode) |
| 139 | (save-excursion | 138 | (with-current-buffer nnbabyl-mbox-buffer |
| 140 | (set-buffer nnbabyl-mbox-buffer) | ||
| 141 | (narrow-to-region | 139 | (narrow-to-region |
| 142 | (caar nnbabyl-previous-buffer-mode) | 140 | (caar nnbabyl-previous-buffer-mode) |
| 143 | (cdar nnbabyl-previous-buffer-mode)) | 141 | (cdar nnbabyl-previous-buffer-mode)) |
| @@ -155,8 +153,7 @@ | |||
| 155 | 153 | ||
| 156 | (deffoo nnbabyl-request-article (article &optional newsgroup server buffer) | 154 | (deffoo nnbabyl-request-article (article &optional newsgroup server buffer) |
| 157 | (nnbabyl-possibly-change-newsgroup newsgroup server) | 155 | (nnbabyl-possibly-change-newsgroup newsgroup server) |
| 158 | (save-excursion | 156 | (with-current-buffer nnbabyl-mbox-buffer |
| 159 | (set-buffer nnbabyl-mbox-buffer) | ||
| 160 | (goto-char (point-min)) | 157 | (goto-char (point-min)) |
| 161 | (when (search-forward (nnbabyl-article-string article) nil t) | 158 | (when (search-forward (nnbabyl-article-string article) nil t) |
| 162 | (let (start stop summary-line) | 159 | (let (start stop summary-line) |
| @@ -216,8 +213,7 @@ | |||
| 216 | (nnmail-get-new-mail | 213 | (nnmail-get-new-mail |
| 217 | 'nnbabyl | 214 | 'nnbabyl |
| 218 | (lambda () | 215 | (lambda () |
| 219 | (save-excursion | 216 | (with-current-buffer nnbabyl-mbox-buffer |
| 220 | (set-buffer nnbabyl-mbox-buffer) | ||
| 221 | (save-buffer))) | 217 | (save-buffer))) |
| 222 | (file-name-directory nnbabyl-mbox-file) | 218 | (file-name-directory nnbabyl-mbox-file) |
| 223 | group | 219 | group |
| @@ -264,8 +260,7 @@ | |||
| 264 | rest) | 260 | rest) |
| 265 | (nnmail-activate 'nnbabyl) | 261 | (nnmail-activate 'nnbabyl) |
| 266 | 262 | ||
| 267 | (save-excursion | 263 | (with-current-buffer nnbabyl-mbox-buffer |
| 268 | (set-buffer nnbabyl-mbox-buffer) | ||
| 269 | (set-text-properties (point-min) (point-max) nil) | 264 | (set-text-properties (point-min) (point-max) nil) |
| 270 | (while (and articles is-old) | 265 | (while (and articles is-old) |
| 271 | (goto-char (point-min)) | 266 | (goto-char (point-min)) |
| @@ -308,8 +303,7 @@ | |||
| 308 | result) | 303 | result) |
| 309 | (and | 304 | (and |
| 310 | (nnbabyl-request-article article group server) | 305 | (nnbabyl-request-article article group server) |
| 311 | (save-excursion | 306 | (with-current-buffer buf |
| 312 | (set-buffer buf) | ||
| 313 | (insert-buffer-substring nntp-server-buffer) | 307 | (insert-buffer-substring nntp-server-buffer) |
| 314 | (goto-char (point-min)) | 308 | (goto-char (point-min)) |
| 315 | (while (re-search-forward | 309 | (while (re-search-forward |
| @@ -373,8 +367,7 @@ | |||
| 373 | 367 | ||
| 374 | (deffoo nnbabyl-request-replace-article (article group buffer) | 368 | (deffoo nnbabyl-request-replace-article (article group buffer) |
| 375 | (nnbabyl-possibly-change-newsgroup group) | 369 | (nnbabyl-possibly-change-newsgroup group) |
| 376 | (save-excursion | 370 | (with-current-buffer nnbabyl-mbox-buffer |
| 377 | (set-buffer nnbabyl-mbox-buffer) | ||
| 378 | (goto-char (point-min)) | 371 | (goto-char (point-min)) |
| 379 | (if (not (search-forward (nnbabyl-article-string article) nil t)) | 372 | (if (not (search-forward (nnbabyl-article-string article) nil t)) |
| 380 | nil | 373 | nil |
| @@ -388,8 +381,7 @@ | |||
| 388 | ;; Delete all articles in GROUP. | 381 | ;; Delete all articles in GROUP. |
| 389 | (if (not force) | 382 | (if (not force) |
| 390 | () ; Don't delete the articles. | 383 | () ; Don't delete the articles. |
| 391 | (save-excursion | 384 | (with-current-buffer nnbabyl-mbox-buffer |
| 392 | (set-buffer nnbabyl-mbox-buffer) | ||
| 393 | (goto-char (point-min)) | 385 | (goto-char (point-min)) |
| 394 | ;; Delete all articles in this group. | 386 | ;; Delete all articles in this group. |
| 395 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) | 387 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) |
| @@ -409,8 +401,7 @@ | |||
| 409 | 401 | ||
| 410 | (deffoo nnbabyl-request-rename-group (group new-name &optional server) | 402 | (deffoo nnbabyl-request-rename-group (group new-name &optional server) |
| 411 | (nnbabyl-possibly-change-newsgroup group server) | 403 | (nnbabyl-possibly-change-newsgroup group server) |
| 412 | (save-excursion | 404 | (with-current-buffer nnbabyl-mbox-buffer |
| 413 | (set-buffer nnbabyl-mbox-buffer) | ||
| 414 | (goto-char (point-min)) | 405 | (goto-char (point-min)) |
| 415 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) | 406 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":")) |
| 416 | (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":")) | 407 | (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":")) |
| @@ -558,9 +549,8 @@ | |||
| 558 | (defun nnbabyl-create-mbox () | 549 | (defun nnbabyl-create-mbox () |
| 559 | (unless (file-exists-p nnbabyl-mbox-file) | 550 | (unless (file-exists-p nnbabyl-mbox-file) |
| 560 | ;; Create a new, empty RMAIL mbox file. | 551 | ;; Create a new, empty RMAIL mbox file. |
| 561 | (save-excursion | 552 | (with-current-buffer (setq nnbabyl-mbox-buffer |
| 562 | (set-buffer (setq nnbabyl-mbox-buffer | 553 | (create-file-buffer nnbabyl-mbox-file)) |
| 563 | (create-file-buffer nnbabyl-mbox-file))) | ||
| 564 | (setq buffer-file-name nnbabyl-mbox-file) | 554 | (setq buffer-file-name nnbabyl-mbox-file) |
| 565 | (insert "BABYL OPTIONS:\n\n\^_") | 555 | (insert "BABYL OPTIONS:\n\n\^_") |
| 566 | (nnmail-write-region | 556 | (nnmail-write-region |
| @@ -572,8 +562,7 @@ | |||
| 572 | 562 | ||
| 573 | (unless (and nnbabyl-mbox-buffer | 563 | (unless (and nnbabyl-mbox-buffer |
| 574 | (buffer-name nnbabyl-mbox-buffer) | 564 | (buffer-name nnbabyl-mbox-buffer) |
| 575 | (save-excursion | 565 | (with-current-buffer nnbabyl-mbox-buffer |
| 576 | (set-buffer nnbabyl-mbox-buffer) | ||
| 577 | (= (buffer-size) (nnheader-file-size nnbabyl-mbox-file)))) | 566 | (= (buffer-size) (nnheader-file-size nnbabyl-mbox-file)))) |
| 578 | ;; This buffer has changed since we read it last. Possibly. | 567 | ;; This buffer has changed since we read it last. Possibly. |
| 579 | (save-excursion | 568 | (save-excursion |
diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el index 3189d33dd5a..790e390424e 100644 --- a/lisp/gnus/nndiary.el +++ b/lisp/gnus/nndiary.el | |||
| @@ -380,8 +380,7 @@ all. This may very well take some time.") | |||
| 380 | 380 | ||
| 381 | (deffoo nndiary-retrieve-headers (sequence &optional group server fetch-old) | 381 | (deffoo nndiary-retrieve-headers (sequence &optional group server fetch-old) |
| 382 | (when (nndiary-possibly-change-directory group server) | 382 | (when (nndiary-possibly-change-directory group server) |
| 383 | (save-excursion | 383 | (with-current-buffer nntp-server-buffer |
| 384 | (set-buffer nntp-server-buffer) | ||
| 385 | (erase-buffer) | 384 | (erase-buffer) |
| 386 | (let* ((file nil) | 385 | (let* ((file nil) |
| 387 | (number (length sequence)) | 386 | (number (length sequence)) |
| @@ -615,8 +614,7 @@ all. This may very well take some time.") | |||
| 615 | (let (nndiary-current-directory | 614 | (let (nndiary-current-directory |
| 616 | nndiary-current-group | 615 | nndiary-current-group |
| 617 | nndiary-article-file-alist) | 616 | nndiary-article-file-alist) |
| 618 | (save-excursion | 617 | (with-current-buffer buf |
| 619 | (set-buffer buf) | ||
| 620 | (insert-buffer-substring nntp-server-buffer) | 618 | (insert-buffer-substring nntp-server-buffer) |
| 621 | (setq result (eval accept-form)) | 619 | (setq result (eval accept-form)) |
| 622 | (kill-buffer (current-buffer)) | 620 | (kill-buffer (current-buffer)) |
| @@ -672,8 +670,7 @@ all. This may very well take some time.") | |||
| 672 | 670 | ||
| 673 | (deffoo nndiary-request-replace-article (article group buffer) | 671 | (deffoo nndiary-request-replace-article (article group buffer) |
| 674 | (nndiary-possibly-change-directory group) | 672 | (nndiary-possibly-change-directory group) |
| 675 | (save-excursion | 673 | (with-current-buffer buffer |
| 676 | (set-buffer buffer) | ||
| 677 | (nndiary-possibly-create-directory group) | 674 | (nndiary-possibly-create-directory group) |
| 678 | (let ((chars (nnmail-insert-lines)) | 675 | (let ((chars (nnmail-insert-lines)) |
| 679 | (art (concat (int-to-string article) "\t")) | 676 | (art (concat (int-to-string article) "\t")) |
| @@ -688,8 +685,7 @@ all. This may very well take some time.") | |||
| 688 | t) | 685 | t) |
| 689 | (setq headers (nndiary-parse-head chars article)) | 686 | (setq headers (nndiary-parse-head chars article)) |
| 690 | ;; Replace the NOV line in the NOV file. | 687 | ;; Replace the NOV line in the NOV file. |
| 691 | (save-excursion | 688 | (with-current-buffer (nndiary-open-nov group) |
| 692 | (set-buffer (nndiary-open-nov group)) | ||
| 693 | (goto-char (point-min)) | 689 | (goto-char (point-min)) |
| 694 | (if (or (looking-at art) | 690 | (if (or (looking-at art) |
| 695 | (search-forward (concat "\n" art) nil t)) | 691 | (search-forward (concat "\n" art) nil t)) |
| @@ -842,8 +838,7 @@ all. This may very well take some time.") | |||
| 842 | 838 | ||
| 843 | ;; Find an article number in the current group given the Message-ID. | 839 | ;; Find an article number in the current group given the Message-ID. |
| 844 | (defun nndiary-find-group-number (id) | 840 | (defun nndiary-find-group-number (id) |
| 845 | (save-excursion | 841 | (with-current-buffer (get-buffer-create " *nndiary id*") |
| 846 | (set-buffer (get-buffer-create " *nndiary id*")) | ||
| 847 | (let ((alist nndiary-group-alist) | 842 | (let ((alist nndiary-group-alist) |
| 848 | number) | 843 | number) |
| 849 | ;; We want to look through all .overview files, but we want to | 844 | ;; We want to look through all .overview files, but we want to |
| @@ -888,8 +883,7 @@ all. This may very well take some time.") | |||
| 888 | (let ((nov (expand-file-name nndiary-nov-file-name | 883 | (let ((nov (expand-file-name nndiary-nov-file-name |
| 889 | nndiary-current-directory))) | 884 | nndiary-current-directory))) |
| 890 | (when (file-exists-p nov) | 885 | (when (file-exists-p nov) |
| 891 | (save-excursion | 886 | (with-current-buffer nntp-server-buffer |
| 892 | (set-buffer nntp-server-buffer) | ||
| 893 | (erase-buffer) | 887 | (erase-buffer) |
| 894 | (nnheader-insert-file-contents nov) | 888 | (nnheader-insert-file-contents nov) |
| 895 | (if (and fetch-old | 889 | (if (and fetch-old |
| @@ -989,8 +983,7 @@ all. This may very well take some time.") | |||
| 989 | 983 | ||
| 990 | (defun nndiary-add-nov (group article headers) | 984 | (defun nndiary-add-nov (group article headers) |
| 991 | "Add a nov line for the GROUP base." | 985 | "Add a nov line for the GROUP base." |
| 992 | (save-excursion | 986 | (with-current-buffer (nndiary-open-nov group) |
| 993 | (set-buffer (nndiary-open-nov group)) | ||
| 994 | (goto-char (point-max)) | 987 | (goto-char (point-max)) |
| 995 | (mail-header-set-number headers article) | 988 | (mail-header-set-number headers article) |
| 996 | (nnheader-insert-nov headers))) | 989 | (nnheader-insert-nov headers))) |
| @@ -1015,8 +1008,7 @@ all. This may very well take some time.") | |||
| 1015 | (or (cdr (assoc group nndiary-nov-buffer-alist)) | 1008 | (or (cdr (assoc group nndiary-nov-buffer-alist)) |
| 1016 | (let ((buffer (get-buffer-create (format " *nndiary overview %s*" | 1009 | (let ((buffer (get-buffer-create (format " *nndiary overview %s*" |
| 1017 | group)))) | 1010 | group)))) |
| 1018 | (save-excursion | 1011 | (with-current-buffer buffer |
| 1019 | (set-buffer buffer) | ||
| 1020 | (set (make-local-variable 'nndiary-nov-buffer-file-name) | 1012 | (set (make-local-variable 'nndiary-nov-buffer-file-name) |
| 1021 | (expand-file-name | 1013 | (expand-file-name |
| 1022 | nndiary-nov-file-name | 1014 | nndiary-nov-file-name |
| @@ -1103,9 +1095,8 @@ all. This may very well take some time.") | |||
| 1103 | (nov (concat dir nndiary-nov-file-name)) | 1095 | (nov (concat dir nndiary-nov-file-name)) |
| 1104 | (nov-buffer (get-buffer-create " *nov*")) | 1096 | (nov-buffer (get-buffer-create " *nov*")) |
| 1105 | chars file headers) | 1097 | chars file headers) |
| 1106 | (save-excursion | 1098 | ;; Init the nov buffer. |
| 1107 | ;; Init the nov buffer. | 1099 | (with-current-buffer nov-buffer |
| 1108 | (set-buffer nov-buffer) | ||
| 1109 | (buffer-disable-undo) | 1100 | (buffer-disable-undo) |
| 1110 | (erase-buffer) | 1101 | (erase-buffer) |
| 1111 | (set-buffer nntp-server-buffer) | 1102 | (set-buffer nntp-server-buffer) |
| @@ -1125,20 +1116,17 @@ all. This may very well take some time.") | |||
| 1125 | (unless (zerop (buffer-size)) | 1116 | (unless (zerop (buffer-size)) |
| 1126 | (goto-char (point-min)) | 1117 | (goto-char (point-min)) |
| 1127 | (setq headers (nndiary-parse-head chars (caar files))) | 1118 | (setq headers (nndiary-parse-head chars (caar files))) |
| 1128 | (save-excursion | 1119 | (with-current-buffer nov-buffer |
| 1129 | (set-buffer nov-buffer) | ||
| 1130 | (goto-char (point-max)) | 1120 | (goto-char (point-max)) |
| 1131 | (nnheader-insert-nov headers))) | 1121 | (nnheader-insert-nov headers))) |
| 1132 | (widen)) | 1122 | (widen)) |
| 1133 | (setq files (cdr files))) | 1123 | (setq files (cdr files))) |
| 1134 | (save-excursion | 1124 | (with-current-buffer nov-buffer |
| 1135 | (set-buffer nov-buffer) | ||
| 1136 | (nnmail-write-region 1 (point-max) nov nil 'nomesg) | 1125 | (nnmail-write-region 1 (point-max) nov nil 'nomesg) |
| 1137 | (kill-buffer (current-buffer)))))) | 1126 | (kill-buffer (current-buffer)))))) |
| 1138 | 1127 | ||
| 1139 | (defun nndiary-nov-delete-article (group article) | 1128 | (defun nndiary-nov-delete-article (group article) |
| 1140 | (save-excursion | 1129 | (with-current-buffer (nndiary-open-nov group) |
| 1141 | (set-buffer (nndiary-open-nov group)) | ||
| 1142 | (when (nnheader-find-nov-line article) | 1130 | (when (nnheader-find-nov-line article) |
| 1143 | (delete-region (point) (progn (forward-line 1) (point))) | 1131 | (delete-region (point) (progn (forward-line 1) (point))) |
| 1144 | (when (bobp) | 1132 | (when (bobp) |
diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el index ddeac7f9523..2e492057003 100644 --- a/lisp/gnus/nndoc.el +++ b/lisp/gnus/nndoc.el | |||
| @@ -215,8 +215,7 @@ from the document.") | |||
| 215 | 215 | ||
| 216 | (deffoo nndoc-retrieve-headers (articles &optional newsgroup server fetch-old) | 216 | (deffoo nndoc-retrieve-headers (articles &optional newsgroup server fetch-old) |
| 217 | (when (nndoc-possibly-change-buffer newsgroup server) | 217 | (when (nndoc-possibly-change-buffer newsgroup server) |
| 218 | (save-excursion | 218 | (with-current-buffer nntp-server-buffer |
| 219 | (set-buffer nntp-server-buffer) | ||
| 220 | (erase-buffer) | 219 | (erase-buffer) |
| 221 | (let (article entry) | 220 | (let (article entry) |
| 222 | (if (stringp (car articles)) | 221 | (if (stringp (car articles)) |
| @@ -333,8 +332,7 @@ from the document.") | |||
| 333 | (concat " *nndoc " group "*")))) | 332 | (concat " *nndoc " group "*")))) |
| 334 | nndoc-group-alist) | 333 | nndoc-group-alist) |
| 335 | (setq nndoc-dissection-alist nil) | 334 | (setq nndoc-dissection-alist nil) |
| 336 | (save-excursion | 335 | (with-current-buffer nndoc-current-buffer |
| 337 | (set-buffer nndoc-current-buffer) | ||
| 338 | (erase-buffer) | 336 | (erase-buffer) |
| 339 | (if (and (stringp nndoc-address) | 337 | (if (and (stringp nndoc-address) |
| 340 | (string-match nndoc-binary-file-names nndoc-address)) | 338 | (string-match nndoc-binary-file-names nndoc-address)) |
| @@ -347,8 +345,7 @@ from the document.") | |||
| 347 | ;; Initialize the nndoc structures according to this new document. | 345 | ;; Initialize the nndoc structures according to this new document. |
| 348 | (when (and nndoc-current-buffer | 346 | (when (and nndoc-current-buffer |
| 349 | (not nndoc-dissection-alist)) | 347 | (not nndoc-dissection-alist)) |
| 350 | (save-excursion | 348 | (with-current-buffer nndoc-current-buffer |
| 351 | (set-buffer nndoc-current-buffer) | ||
| 352 | (nndoc-set-delims) | 349 | (nndoc-set-delims) |
| 353 | (if (eq nndoc-article-type 'mime-parts) | 350 | (if (eq nndoc-article-type 'mime-parts) |
| 354 | (nndoc-dissect-mime-parts) | 351 | (nndoc-dissect-mime-parts) |
| @@ -588,8 +585,7 @@ from the document.") | |||
| 588 | (defun nndoc-generate-clari-briefs-head (article) | 585 | (defun nndoc-generate-clari-briefs-head (article) |
| 589 | (let ((entry (cdr (assq article nndoc-dissection-alist))) | 586 | (let ((entry (cdr (assq article nndoc-dissection-alist))) |
| 590 | subject from) | 587 | subject from) |
| 591 | (save-excursion | 588 | (with-current-buffer nndoc-current-buffer |
| 592 | (set-buffer nndoc-current-buffer) | ||
| 593 | (save-restriction | 589 | (save-restriction |
| 594 | (narrow-to-region (car entry) (nth 3 entry)) | 590 | (narrow-to-region (car entry) (nth 3 entry)) |
| 595 | (goto-char (point-min)) | 591 | (goto-char (point-min)) |
| @@ -677,8 +673,7 @@ from the document.") | |||
| 677 | (let ((entry (cdr (assq article nndoc-dissection-alist))) | 673 | (let ((entry (cdr (assq article nndoc-dissection-alist))) |
| 678 | (from "<no address given>") | 674 | (from "<no address given>") |
| 679 | subject date) | 675 | subject date) |
| 680 | (save-excursion | 676 | (with-current-buffer nndoc-current-buffer |
| 681 | (set-buffer nndoc-current-buffer) | ||
| 682 | (save-restriction | 677 | (save-restriction |
| 683 | (narrow-to-region (car entry) (nth 1 entry)) | 678 | (narrow-to-region (car entry) (nth 1 entry)) |
| 684 | (goto-char (point-min)) | 679 | (goto-char (point-min)) |
| @@ -829,8 +824,7 @@ from the document.") | |||
| 829 | (first t) | 824 | (first t) |
| 830 | art-begin head-begin head-end body-begin body-end) | 825 | art-begin head-begin head-end body-begin body-end) |
| 831 | (setq nndoc-dissection-alist nil) | 826 | (setq nndoc-dissection-alist nil) |
| 832 | (save-excursion | 827 | (with-current-buffer nndoc-current-buffer |
| 833 | (set-buffer nndoc-current-buffer) | ||
| 834 | (goto-char (point-min)) | 828 | (goto-char (point-min)) |
| 835 | ;; Remove blank lines. | 829 | ;; Remove blank lines. |
| 836 | (while (eq (following-char) ?\n) | 830 | (while (eq (following-char) ?\n) |
| @@ -902,8 +896,7 @@ When a MIME entity contains sub-entities, dissection produces one article for | |||
| 902 | the header of this entity, and one article per sub-entity." | 896 | the header of this entity, and one article per sub-entity." |
| 903 | (setq nndoc-dissection-alist nil | 897 | (setq nndoc-dissection-alist nil |
| 904 | nndoc-mime-split-ordinal 0) | 898 | nndoc-mime-split-ordinal 0) |
| 905 | (save-excursion | 899 | (with-current-buffer nndoc-current-buffer |
| 906 | (set-buffer nndoc-current-buffer) | ||
| 907 | (nndoc-dissect-mime-parts-sub (point-min) (point-max) nil nil nil))) | 900 | (nndoc-dissect-mime-parts-sub (point-min) (point-max) nil nil nil))) |
| 908 | 901 | ||
| 909 | (defun nndoc-dissect-mime-parts-sub (head-begin body-end article-insert | 902 | (defun nndoc-dissect-mime-parts-sub (head-begin body-end article-insert |
diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el index dd2b8a6b48d..e92e00efe6f 100644 --- a/lisp/gnus/nndraft.el +++ b/lisp/gnus/nndraft.el | |||
| @@ -77,8 +77,7 @@ are generated if and only if they are also in `message-draft-headers'.") | |||
| 77 | 77 | ||
| 78 | (deffoo nndraft-retrieve-headers (articles &optional group server fetch-old) | 78 | (deffoo nndraft-retrieve-headers (articles &optional group server fetch-old) |
| 79 | (nndraft-possibly-change-group group) | 79 | (nndraft-possibly-change-group group) |
| 80 | (save-excursion | 80 | (with-current-buffer nntp-server-buffer |
| 81 | (set-buffer nntp-server-buffer) | ||
| 82 | (erase-buffer) | 81 | (erase-buffer) |
| 83 | (let* (article) | 82 | (let* (article) |
| 84 | ;; We don't support fetching by Message-ID. | 83 | ;; We don't support fetching by Message-ID. |
| @@ -119,8 +118,7 @@ are generated if and only if they are also in `message-draft-headers'.") | |||
| 119 | mm-text-coding-system) | 118 | mm-text-coding-system) |
| 120 | mm-auto-save-coding-system))) | 119 | mm-auto-save-coding-system))) |
| 121 | (nnmail-find-file newest))) | 120 | (nnmail-find-file newest))) |
| 122 | (save-excursion | 121 | (with-current-buffer nntp-server-buffer |
| 123 | (set-buffer nntp-server-buffer) | ||
| 124 | (goto-char (point-min)) | 122 | (goto-char (point-min)) |
| 125 | ;; If there's a mail header separator in this file, | 123 | ;; If there's a mail header separator in this file, |
| 126 | ;; we remove it. | 124 | ;; we remove it. |
| @@ -209,8 +207,7 @@ are generated if and only if they are also in `message-draft-headers'.") | |||
| 209 | result) | 207 | result) |
| 210 | (and | 208 | (and |
| 211 | (nndraft-request-article article group server) | 209 | (nndraft-request-article article group server) |
| 212 | (save-excursion | 210 | (with-current-buffer buf |
| 213 | (set-buffer buf) | ||
| 214 | (erase-buffer) | 211 | (erase-buffer) |
| 215 | (insert-buffer-substring nntp-server-buffer) | 212 | (insert-buffer-substring nntp-server-buffer) |
| 216 | (setq result (eval accept-form)) | 213 | (setq result (eval accept-form)) |
diff --git a/lisp/gnus/nneething.el b/lisp/gnus/nneething.el index 2f05c7e7900..bd5bfba0468 100644 --- a/lisp/gnus/nneething.el +++ b/lisp/gnus/nneething.el | |||
| @@ -81,8 +81,7 @@ included.") | |||
| 81 | (deffoo nneething-retrieve-headers (articles &optional group server fetch-old) | 81 | (deffoo nneething-retrieve-headers (articles &optional group server fetch-old) |
| 82 | (nneething-possibly-change-directory group) | 82 | (nneething-possibly-change-directory group) |
| 83 | 83 | ||
| 84 | (save-excursion | 84 | (with-current-buffer nntp-server-buffer |
| 85 | (set-buffer nntp-server-buffer) | ||
| 86 | (erase-buffer) | 85 | (erase-buffer) |
| 87 | (let* ((number (length articles)) | 86 | (let* ((number (length articles)) |
| 88 | (count 0) | 87 | (count 0) |
| @@ -323,8 +322,7 @@ included.") | |||
| 323 | (if (equal '(0 0) (nth 5 atts)) "" | 322 | (if (equal '(0 0) (nth 5 atts)) "" |
| 324 | (concat "Date: " (current-time-string (nth 5 atts)) "\n")) | 323 | (concat "Date: " (current-time-string (nth 5 atts)) "\n")) |
| 325 | (or (when buffer | 324 | (or (when buffer |
| 326 | (save-excursion | 325 | (with-current-buffer buffer |
| 327 | (set-buffer buffer) | ||
| 328 | (when (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t) | 326 | (when (re-search-forward "<[a-zA-Z0-9_]@[-a-zA-Z0-9_]>" 1000 t) |
| 329 | (concat "From: " (match-string 0) "\n")))) | 327 | (concat "From: " (match-string 0) "\n")))) |
| 330 | (nneething-from-line (nth 2 atts) file)) | 328 | (nneething-from-line (nth 2 atts) file)) |
| @@ -332,8 +330,7 @@ included.") | |||
| 332 | (concat "Chars: " (int-to-string (nth 7 atts)) "\n") | 330 | (concat "Chars: " (int-to-string (nth 7 atts)) "\n") |
| 333 | "") | 331 | "") |
| 334 | (if buffer | 332 | (if buffer |
| 335 | (save-excursion | 333 | (with-current-buffer buffer |
| 336 | (set-buffer buffer) | ||
| 337 | (concat "Lines: " (int-to-string | 334 | (concat "Lines: " (int-to-string |
| 338 | (count-lines (point-min) (point-max))) | 335 | (count-lines (point-min) (point-max))) |
| 339 | "\n")) | 336 | "\n")) |
| @@ -382,8 +379,7 @@ included.") | |||
| 382 | 379 | ||
| 383 | (defun nneething-get-head (file) | 380 | (defun nneething-get-head (file) |
| 384 | "Either find the head in FILE or make a head for FILE." | 381 | "Either find the head in FILE or make a head for FILE." |
| 385 | (save-excursion | 382 | (with-current-buffer (get-buffer-create nneething-work-buffer) |
| 386 | (set-buffer (get-buffer-create nneething-work-buffer)) | ||
| 387 | (setq case-fold-search nil) | 383 | (setq case-fold-search nil) |
| 388 | (buffer-disable-undo) | 384 | (buffer-disable-undo) |
| 389 | (erase-buffer) | 385 | (erase-buffer) |
diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el index 6413e98cc1e..5cebcb0e5fc 100644 --- a/lisp/gnus/nnfolder.el +++ b/lisp/gnus/nnfolder.el | |||
| @@ -157,8 +157,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 157 | (nnoo-define-basics nnfolder) | 157 | (nnoo-define-basics nnfolder) |
| 158 | 158 | ||
| 159 | (deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old) | 159 | (deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old) |
| 160 | (save-excursion | 160 | (with-current-buffer nntp-server-buffer |
| 161 | (set-buffer nntp-server-buffer) | ||
| 162 | (erase-buffer) | 161 | (erase-buffer) |
| 163 | (let (article start stop num) | 162 | (let (article start stop num) |
| 164 | (nnfolder-possibly-change-group group server) | 163 | (nnfolder-possibly-change-group group server) |
| @@ -261,8 +260,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 261 | 260 | ||
| 262 | (deffoo nnfolder-request-article (article &optional group server buffer) | 261 | (deffoo nnfolder-request-article (article &optional group server buffer) |
| 263 | (nnfolder-possibly-change-group group server) | 262 | (nnfolder-possibly-change-group group server) |
| 264 | (save-excursion | 263 | (with-current-buffer nnfolder-current-buffer |
| 265 | (set-buffer nnfolder-current-buffer) | ||
| 266 | (goto-char (point-min)) | 264 | (goto-char (point-min)) |
| 267 | (when (nnfolder-goto-article article) | 265 | (when (nnfolder-goto-article article) |
| 268 | (let (start stop) | 266 | (let (start stop) |
| @@ -360,8 +358,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 360 | nnfolder-current-group (car inf)))) | 358 | nnfolder-current-group (car inf)))) |
| 361 | (when (and nnfolder-current-buffer | 359 | (when (and nnfolder-current-buffer |
| 362 | (buffer-name nnfolder-current-buffer)) | 360 | (buffer-name nnfolder-current-buffer)) |
| 363 | (save-excursion | 361 | (with-current-buffer nnfolder-current-buffer |
| 364 | (set-buffer nnfolder-current-buffer) | ||
| 365 | ;; If the buffer was modified, write the file out now. | 362 | ;; If the buffer was modified, write the file out now. |
| 366 | (nnfolder-save-buffer) | 363 | (nnfolder-save-buffer) |
| 367 | ;; If we're shutting the server down, we need to kill the | 364 | ;; If we're shutting the server down, we need to kill the |
| @@ -447,8 +444,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 447 | target) | 444 | target) |
| 448 | (nnmail-activate 'nnfolder) | 445 | (nnmail-activate 'nnfolder) |
| 449 | 446 | ||
| 450 | (save-excursion | 447 | (with-current-buffer nnfolder-current-buffer |
| 451 | (set-buffer nnfolder-current-buffer) | ||
| 452 | ;; Since messages are sorted in arrival order and expired in the | 448 | ;; Since messages are sorted in arrival order and expired in the |
| 453 | ;; same order, we can stop as soon as we find a message that is | 449 | ;; same order, we can stop as soon as we find a message that is |
| 454 | ;; too old. | 450 | ;; too old. |
| @@ -501,8 +497,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 501 | result) | 497 | result) |
| 502 | (and | 498 | (and |
| 503 | (nnfolder-request-article article group server) | 499 | (nnfolder-request-article article group server) |
| 504 | (save-excursion | 500 | (with-current-buffer buf |
| 505 | (set-buffer buf) | ||
| 506 | (erase-buffer) | 501 | (erase-buffer) |
| 507 | (insert-buffer-substring nntp-server-buffer) | 502 | (insert-buffer-substring nntp-server-buffer) |
| 508 | (goto-char (point-min)) | 503 | (goto-char (point-min)) |
| @@ -578,8 +573,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 578 | 573 | ||
| 579 | (deffoo nnfolder-request-replace-article (article group buffer) | 574 | (deffoo nnfolder-request-replace-article (article group buffer) |
| 580 | (nnfolder-possibly-change-group group) | 575 | (nnfolder-possibly-change-group group) |
| 581 | (save-excursion | 576 | (with-current-buffer buffer |
| 582 | (set-buffer buffer) | ||
| 583 | (goto-char (point-min)) | 577 | (goto-char (point-min)) |
| 584 | (if (not (looking-at "X-From-Line: ")) | 578 | (if (not (looking-at "X-From-Line: ")) |
| 585 | (insert "From nobody " (current-time-string) "\n") | 579 | (insert "From nobody " (current-time-string) "\n") |
| @@ -596,8 +590,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 596 | (nnfolder-delete-mail) | 590 | (nnfolder-delete-mail) |
| 597 | (insert-buffer-substring buffer) | 591 | (insert-buffer-substring buffer) |
| 598 | (unless (or gnus-nov-is-evil nnfolder-nov-is-evil) | 592 | (unless (or gnus-nov-is-evil nnfolder-nov-is-evil) |
| 599 | (save-excursion | 593 | (with-current-buffer buffer |
| 600 | (set-buffer buffer) | ||
| 601 | (let ((headers (nnfolder-parse-head article | 594 | (let ((headers (nnfolder-parse-head article |
| 602 | (point-min) (point-max)))) | 595 | (point-min) (point-max)))) |
| 603 | (with-current-buffer (nnfolder-open-nov group) | 596 | (with-current-buffer (nnfolder-open-nov group) |
| @@ -630,8 +623,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 630 | 623 | ||
| 631 | (deffoo nnfolder-request-rename-group (group new-name &optional server) | 624 | (deffoo nnfolder-request-rename-group (group new-name &optional server) |
| 632 | (nnfolder-possibly-change-group group server) | 625 | (nnfolder-possibly-change-group group server) |
| 633 | (save-excursion | 626 | (with-current-buffer nnfolder-current-buffer |
| 634 | (set-buffer nnfolder-current-buffer) | ||
| 635 | (and (file-writable-p buffer-file-name) | 627 | (and (file-writable-p buffer-file-name) |
| 636 | (ignore-errors | 628 | (ignore-errors |
| 637 | (let ((new-file (nnfolder-group-pathname new-name))) | 629 | (let ((new-file (nnfolder-group-pathname new-name))) |
| @@ -671,8 +663,7 @@ the group. Then the marks file will be regenerated properly by Gnus.") | |||
| 671 | (marker (concat "\n" nnfolder-article-marker)) | 663 | (marker (concat "\n" nnfolder-article-marker)) |
| 672 | (number "[0-9]+") | 664 | (number "[0-9]+") |
| 673 | (activemin (cdr active))) | 665 | (activemin (cdr active))) |
| 674 | (save-excursion | 666 | (with-current-buffer nnfolder-current-buffer |
| 675 | (set-buffer nnfolder-current-buffer) | ||
| 676 | (goto-char (point-min)) | 667 | (goto-char (point-min)) |
| 677 | (while (and (search-forward marker nil t) | 668 | (while (and (search-forward marker nil t) |
| 678 | (re-search-forward number nil t)) | 669 | (re-search-forward number nil t)) |
| @@ -1114,8 +1105,7 @@ This command does not work if you use short group names." | |||
| 1114 | (defun nnfolder-open-nov (group) | 1105 | (defun nnfolder-open-nov (group) |
| 1115 | (or (cdr (assoc group nnfolder-nov-buffer-alist)) | 1106 | (or (cdr (assoc group nnfolder-nov-buffer-alist)) |
| 1116 | (let ((buffer (get-buffer-create (format " *nnfolder overview %s*" group)))) | 1107 | (let ((buffer (get-buffer-create (format " *nnfolder overview %s*" group)))) |
| 1117 | (save-excursion | 1108 | (with-current-buffer buffer |
| 1118 | (set-buffer buffer) | ||
| 1119 | (set (make-local-variable 'nnfolder-nov-buffer-file-name) | 1109 | (set (make-local-variable 'nnfolder-nov-buffer-file-name) |
| 1120 | (nnfolder-group-nov-pathname group)) | 1110 | (nnfolder-group-nov-pathname group)) |
| 1121 | (erase-buffer) | 1111 | (erase-buffer) |
| @@ -1139,8 +1129,7 @@ This command does not work if you use short group names." | |||
| 1139 | (setq nnfolder-nov-buffer-alist (cdr nnfolder-nov-buffer-alist))))) | 1129 | (setq nnfolder-nov-buffer-alist (cdr nnfolder-nov-buffer-alist))))) |
| 1140 | 1130 | ||
| 1141 | (defun nnfolder-nov-delete-article (group article) | 1131 | (defun nnfolder-nov-delete-article (group article) |
| 1142 | (save-excursion | 1132 | (with-current-buffer (nnfolder-open-nov group) |
| 1143 | (set-buffer (nnfolder-open-nov group)) | ||
| 1144 | (when (nnheader-find-nov-line article) | 1133 | (when (nnheader-find-nov-line article) |
| 1145 | (delete-region (point) (progn (forward-line 1) (point)))) | 1134 | (delete-region (point) (progn (forward-line 1) (point)))) |
| 1146 | t)) | 1135 | t)) |
| @@ -1150,8 +1139,7 @@ This command does not work if you use short group names." | |||
| 1150 | nil | 1139 | nil |
| 1151 | (let ((nov (nnfolder-group-nov-pathname nnfolder-current-group))) | 1140 | (let ((nov (nnfolder-group-nov-pathname nnfolder-current-group))) |
| 1152 | (when (file-exists-p nov) | 1141 | (when (file-exists-p nov) |
| 1153 | (save-excursion | 1142 | (with-current-buffer nntp-server-buffer |
| 1154 | (set-buffer nntp-server-buffer) | ||
| 1155 | (erase-buffer) | 1143 | (erase-buffer) |
| 1156 | (nnheader-insert-file-contents nov) | 1144 | (nnheader-insert-file-contents nov) |
| 1157 | (if (and fetch-old | 1145 | (if (and fetch-old |
| @@ -1187,8 +1175,7 @@ This command does not work if you use short group names." | |||
| 1187 | 1175 | ||
| 1188 | (defun nnfolder-add-nov (group article headers) | 1176 | (defun nnfolder-add-nov (group article headers) |
| 1189 | "Add a nov line for the GROUP base." | 1177 | "Add a nov line for the GROUP base." |
| 1190 | (save-excursion | 1178 | (with-current-buffer (nnfolder-open-nov group) |
| 1191 | (set-buffer (nnfolder-open-nov group)) | ||
| 1192 | (goto-char (point-max)) | 1179 | (goto-char (point-max)) |
| 1193 | (mail-header-set-number headers article) | 1180 | (mail-header-set-number headers article) |
| 1194 | (nnheader-insert-nov headers))) | 1181 | (nnheader-insert-nov headers))) |
diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el index 9a90a76f7af..1bfdbeab9c4 100644 --- a/lisp/gnus/nnheader.el +++ b/lisp/gnus/nnheader.el | |||
| @@ -835,8 +835,7 @@ The first string in ARGS can be a format string." | |||
| 835 | "Clear the communication buffer and insert FORMAT and ARGS into the buffer. | 835 | "Clear the communication buffer and insert FORMAT and ARGS into the buffer. |
| 836 | If FORMAT isn't a format string, it and all ARGS will be inserted | 836 | If FORMAT isn't a format string, it and all ARGS will be inserted |
| 837 | without formatting." | 837 | without formatting." |
| 838 | (save-excursion | 838 | (with-current-buffer nntp-server-buffer |
| 839 | (set-buffer nntp-server-buffer) | ||
| 840 | (erase-buffer) | 839 | (erase-buffer) |
| 841 | (if (string-match "%" format) | 840 | (if (string-match "%" format) |
| 842 | (insert (apply 'format format args)) | 841 | (insert (apply 'format format args)) |
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index d412af46d0c..e7bf0f376a8 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | ;;; nnimap.el --- imap backend for Gnus | 1 | ;;; nnimap.el --- IMAP interface for Gnus |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, | 3 | ;; Copyright (C) 2010 Free Software Foundation, Inc. |
| 4 | ;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc. | ||
| 5 | 4 | ||
| 6 | ;; Author: Simon Josefsson <simon@josefsson.org> | 5 | ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> |
| 7 | ;; Jim Radford <radford@robby.caltech.edu> | 6 | ;; Simon Josefsson <simon@josefsson.org> |
| 8 | ;; Keywords: mail | ||
| 9 | 7 | ||
| 10 | ;; This file is part of GNU Emacs. | 8 | ;; This file is part of GNU Emacs. |
| 11 | 9 | ||
| @@ -24,1791 +22,942 @@ | |||
| 24 | 22 | ||
| 25 | ;;; Commentary: | 23 | ;;; Commentary: |
| 26 | 24 | ||
| 27 | ;; Todo, major things: | 25 | ;; nnimap interfaces Gnus with IMAP servers. |
| 28 | ;; | ||
| 29 | ;; o Fix Gnus to view correct number of unread/total articles in group buffer | ||
| 30 | ;; o Fix Gnus to handle leading '.' in group names (fixed?) | ||
| 31 | ;; o Finish disconnected mode (moving articles between mailboxes unplugged) | ||
| 32 | ;; o Sieve | ||
| 33 | ;; o MIME (partial article fetches) | ||
| 34 | ;; o Split to other backends, different split rules for different | ||
| 35 | ;; servers/inboxes | ||
| 36 | ;; | ||
| 37 | ;; Todo, minor things: | ||
| 38 | ;; | ||
| 39 | ;; o Don't require half of Gnus -- backends should be standalone | ||
| 40 | ;; o Verify that we don't use IMAP4rev1 specific things (RFC2060 App B) | ||
| 41 | ;; o Dont uid fetch 1,* in nnimap-retrive-groups (slow) | ||
| 42 | ;; o Split up big fetches (1,* header especially) in smaller chunks | ||
| 43 | ;; o What do I do with gnus-newsgroup-*? | ||
| 44 | ;; o Tell Gnus about new groups (how can we tell?) | ||
| 45 | ;; o Respooling (fix Gnus?) (unnecessary?) | ||
| 46 | ;; o Add support for the following: (if applicable) | ||
| 47 | ;; request-list-newsgroups, request-regenerate | ||
| 48 | ;; list-active-group, | ||
| 49 | ;; request-associate-buffer, request-restore-buffer, | ||
| 50 | ;; o Do The Right Thing when UIDVALIDITY changes (what's the right thing?) | ||
| 51 | ;; o Support RFC2221 (Login referrals) | ||
| 52 | ;; o IMAP2BIS compatibility? (RFC2061) | ||
| 53 | ;; o ACAP stuff (perhaps a different project, would be nice to ACAPify | ||
| 54 | ;; .newsrc.eld) | ||
| 55 | ;; o What about Gnus's article editing, can we support it? NO! | ||
| 56 | ;; o Use \Draft to support the draft group?? | ||
| 57 | ;; o Duplicate suppression | ||
| 58 | ;; o Rewrite UID SEARCH UID X as UID FETCH X (UID) for those with slow servers | ||
| 59 | 26 | ||
| 60 | ;;; Code: | 27 | ;;; Code: |
| 61 | 28 | ||
| 62 | ;; For Emacs < 22.2. | ||
| 63 | (eval-and-compile | 29 | (eval-and-compile |
| 64 | (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))) | 30 | (require 'nnheader)) |
| 65 | 31 | ||
| 66 | (require 'imap) | 32 | (eval-when-compile |
| 67 | (require 'nnoo) | 33 | (require 'cl)) |
| 68 | (require 'nnmail) | ||
| 69 | (require 'nnheader) | ||
| 70 | (require 'mm-util) | ||
| 71 | (require 'gnus) | ||
| 72 | (require 'gnus-range) | ||
| 73 | (require 'gnus-start) | ||
| 74 | (require 'gnus-int) | ||
| 75 | 34 | ||
| 76 | (eval-when-compile (require 'cl)) | 35 | (require 'netrc) |
| 77 | |||
| 78 | (autoload 'auth-source-user-or-password "auth-source") | ||
| 79 | 36 | ||
| 80 | (nnoo-declare nnimap) | 37 | (nnoo-declare nnimap) |
| 81 | 38 | ||
| 82 | (defconst nnimap-version "nnimap 1.0") | ||
| 83 | |||
| 84 | (defgroup nnimap nil | ||
| 85 | "Reading IMAP mail with Gnus." | ||
| 86 | :group 'gnus) | ||
| 87 | |||
| 88 | (defvoo nnimap-address nil | 39 | (defvoo nnimap-address nil |
| 89 | "Address of physical IMAP server. If nil, use the virtual server's name.") | 40 | "The address of the IMAP server.") |
| 90 | 41 | ||
| 91 | (defvoo nnimap-server-port nil | 42 | (defvoo nnimap-server-port nil |
| 92 | "Port number on physical IMAP server. | 43 | "The IMAP port used. |
| 93 | If nil, defaults to 993 for TLS/SSL connections and 143 otherwise.") | 44 | If nnimap-stream is `ssl', this will default to `imaps'. If not, |
| 94 | 45 | it will default to `imap'.") | |
| 95 | ;; Splitting variables | 46 | |
| 96 | 47 | (defvoo nnimap-stream 'ssl | |
| 97 | (defcustom nnimap-split-crosspost t | 48 | "How nnimap will talk to the IMAP server. |
| 98 | "If non-nil, do crossposting if several split methods match the mail. | 49 | Values are `ssl' and `network'.") |
| 99 | If nil, the first match found will be used." | 50 | |
| 100 | :group 'nnimap | 51 | (defvoo nnimap-shell-program (if (boundp 'imap-shell-program) |
| 101 | :type 'boolean) | 52 | (if (listp imap-shell-program) |
| 102 | 53 | (car imap-shell-program) | |
| 103 | (defcustom nnimap-split-inbox nil | 54 | imap-shell-program) |
| 104 | "Name of mailbox to split mail from. | 55 | "ssh %s imapd")) |
| 105 | 56 | ||
| 106 | Mail is read from this mailbox and split according to rules in | 57 | (defvoo nnimap-inbox nil |
| 107 | `nnimap-split-rule'. | 58 | "The mail box where incoming mail arrives and should be split out of.") |
| 108 | 59 | ||
| 109 | This can be a string or a list of strings." | 60 | (defvoo nnimap-expunge-inbox nil |
| 110 | :group 'nnimap | 61 | "If non-nil, expunge the inbox after fetching mail. |
| 111 | :type '(choice (string) | 62 | This is always done if the server supports UID EXPUNGE, but it's |
| 112 | (repeat string))) | 63 | not done by default on servers that doesn't support that command.") |
| 113 | 64 | ||
| 114 | (define-widget 'nnimap-strict-function 'function | 65 | (defvoo nnimap-connection-alist nil) |
| 115 | "This widget only matches values that are functionp. | 66 | (defvar nnimap-process nil) |
| 116 | 67 | ||
| 117 | Warning: This means that a value that is the symbol of a not yet | 68 | (defvar nnimap-status-string "") |
| 118 | loaded function will not match. Use with care." | ||
| 119 | :match 'nnimap-strict-function-match) | ||
| 120 | |||
| 121 | (defun nnimap-strict-function-match (widget value) | ||
| 122 | "Ignoring WIDGET, match if VALUE is a function." | ||
| 123 | (functionp value)) | ||
| 124 | |||
| 125 | (defcustom nnimap-split-rule nil | ||
| 126 | "Mail will be split according to these rules. | ||
| 127 | |||
| 128 | Mail is read from mailbox(es) specified in `nnimap-split-inbox'. | ||
| 129 | |||
| 130 | If you'd like, for instance, one mail group for mail from the | ||
| 131 | \"gnus-imap\" mailing list, one group for junk mail and leave | ||
| 132 | everything else in the incoming mailbox, you could do something like | ||
| 133 | this: | ||
| 134 | |||
| 135 | \(setq nnimap-split-rule '((\"INBOX.gnus-imap\" \"From:.*gnus-imap\") | ||
| 136 | (\"INBOX.junk\" \"Subject:.*buy\"))) | ||
| 137 | |||
| 138 | As you can see, `nnimap-split-rule' is a list of lists, where the | ||
| 139 | first element in each \"rule\" is the name of the IMAP mailbox (or the | ||
| 140 | symbol `junk' if you want to remove the mail), and the second is a | ||
| 141 | regexp that nnimap will try to match on the header to find a fit. | ||
| 142 | |||
| 143 | The second element can also be a function. In that case, it will be | ||
| 144 | called narrowed to the headers with the first element of the rule as | ||
| 145 | the argument. It should return a non-nil value if it thinks that the | ||
| 146 | mail belongs in that group. | ||
| 147 | |||
| 148 | This variable can also have a function as its value, the function will | ||
| 149 | be called with the headers narrowed and should return a group where it | ||
| 150 | thinks the article should be splitted to. See `nnimap-split-fancy'. | ||
| 151 | |||
| 152 | To allow for different split rules on different virtual servers, and | ||
| 153 | even different split rules in different inboxes on the same server, | ||
| 154 | the syntax of this variable have been extended along the lines of: | ||
| 155 | |||
| 156 | \(setq nnimap-split-rule | ||
| 157 | '((\"my1server\" (\".*\" ((\"ding\" \"ding@gnus.org\") | ||
| 158 | (\"junk\" \"From:.*Simon\"))) | ||
| 159 | (\"my2server\" (\"INBOX\" nnimap-split-fancy)) | ||
| 160 | (\"my[34]server\" (\".*\" ((\"private\" \"To:.*Simon\") | ||
| 161 | (\"junk\" my-junk-func))))) | ||
| 162 | |||
| 163 | The virtual server name is in fact a regexp, so that the same rules | ||
| 164 | may apply to several servers. In the example, the servers | ||
| 165 | \"my3server\" and \"my4server\" both use the same rules. Similarly, | ||
| 166 | the inbox string is also a regexp. The actual splitting rules are as | ||
| 167 | before, either a function, or a list with group/regexp or | ||
| 168 | group/function elements." | ||
| 169 | :group 'nnimap | ||
| 170 | ;; FIXME: Doesn't allow `("my2server" ("INBOX" nnimap-split-fancy))' | ||
| 171 | ;; per example above. -- fx | ||
| 172 | :type '(choice :tag "Rule type" | ||
| 173 | (repeat :menu-tag "Single-server" | ||
| 174 | :tag "Single-server list" | ||
| 175 | (list (string :tag "Mailbox") | ||
| 176 | (choice :tag "Predicate" | ||
| 177 | (regexp :tag "A regexp") | ||
| 178 | (nnimap-strict-function :tag "A function")))) | ||
| 179 | (choice :menu-tag "A function" | ||
| 180 | :tag "A function" | ||
| 181 | (function-item nnimap-split-fancy) | ||
| 182 | (function-item nnmail-split-fancy) | ||
| 183 | (nnimap-strict-function :tag "User-defined function")) | ||
| 184 | (repeat :menu-tag "Multi-server (extended)" | ||
| 185 | :tag "Multi-server list" | ||
| 186 | (list (regexp :tag "Server regexp") | ||
| 187 | (list (regexp :tag "Incoming Mailbox regexp") | ||
| 188 | (repeat :tag "Rules for matching server(s) and mailbox(es)" | ||
| 189 | (list (string :tag "Destination mailbox") | ||
| 190 | (choice :tag "Predicate" | ||
| 191 | (regexp :tag "A Regexp") | ||
| 192 | (nnimap-strict-function :tag "A Function"))))))))) | ||
| 193 | |||
| 194 | (defcustom nnimap-split-predicate "UNSEEN UNDELETED" | ||
| 195 | "The predicate used to find articles to split. | ||
| 196 | If you use another IMAP client to peek on articles but always would | ||
| 197 | like nnimap to split them once it's started, you could change this to | ||
| 198 | \"UNDELETED\". Other available predicates are available in | ||
| 199 | RFC2060 section 6.4.4." | ||
| 200 | :group 'nnimap | ||
| 201 | :type 'string) | ||
| 202 | |||
| 203 | (defcustom nnimap-split-fancy nil | ||
| 204 | "Like the variable `nnmail-split-fancy'." | ||
| 205 | :group 'nnimap | ||
| 206 | :type 'sexp) | ||
| 207 | 69 | ||
| 208 | (defvar nnimap-split-download-body-default nil | 70 | (defvar nnimap-split-download-body-default nil |
| 209 | "Internal variable with default value for `nnimap-split-download-body'.") | 71 | "Internal variable with default value for `nnimap-split-download-body'.") |
| 210 | 72 | ||
| 211 | (defcustom nnimap-split-download-body 'default | 73 | (defstruct nnimap |
| 212 | "Whether to download entire articles during splitting. | 74 | group process commands capabilities) |
| 213 | This is generally not required, and will slow things down considerably. | ||
| 214 | You may need it if you want to use an advanced splitting function that | ||
| 215 | analyzes the body before splitting the article. | ||
| 216 | If this variable is nil, bodies will not be downloaded; if this | ||
| 217 | variable is the symbol `default' the default behavior is | ||
| 218 | used (which currently is nil, unless you use a statistical | ||
| 219 | spam.el test); if this variable is another non-nil value bodies | ||
| 220 | will be downloaded." | ||
| 221 | :version "22.1" | ||
| 222 | :group 'nnimap | ||
| 223 | :type '(choice (const :tag "Let system decide" deault) | ||
| 224 | boolean)) | ||
| 225 | |||
| 226 | ;; Performance / bug workaround variables | ||
| 227 | |||
| 228 | (defcustom nnimap-close-asynchronous t | ||
| 229 | "Close mailboxes asynchronously in `nnimap-close-group'. | ||
| 230 | This means that errors caught by nnimap when closing the mailbox will | ||
| 231 | not prevent Gnus from updating the group status, which may be harmful. | ||
| 232 | However, it increases speed." | ||
| 233 | :version "22.1" | ||
| 234 | :type 'boolean | ||
| 235 | :group 'nnimap) | ||
| 236 | |||
| 237 | (defcustom nnimap-dont-close t | ||
| 238 | "Never close mailboxes. | ||
| 239 | This increases the speed of closing mailboxes (quiting group) but may | ||
| 240 | decrease the speed of selecting another mailbox later. Re-selecting | ||
| 241 | the same mailbox will be faster though." | ||
| 242 | :version "22.1" | ||
| 243 | :type 'boolean | ||
| 244 | :group 'nnimap) | ||
| 245 | |||
| 246 | (defcustom nnimap-retrieve-groups-asynchronous t | ||
| 247 | "Send asynchronous STATUS commands for each mailbox before checking mail. | ||
| 248 | If you have mailboxes that rarely receives mail, this speeds up new | ||
| 249 | mail checking. It works by first sending STATUS commands for each | ||
| 250 | mailbox, and then only checking groups which has a modified UIDNEXT | ||
| 251 | more carefully for new mail. | ||
| 252 | |||
| 253 | In summary, the default is O((1-p)*k+p*n) and changing it to nil makes | ||
| 254 | it O(n). If p is small, then the default is probably faster." | ||
| 255 | :version "22.1" | ||
| 256 | :type 'boolean | ||
| 257 | :group 'nnimap) | ||
| 258 | |||
| 259 | (defvoo nnimap-need-unselect-to-notice-new-mail t | ||
| 260 | "Unselect mailboxes before looking for new mail in them. | ||
| 261 | Some servers seem to need this under some circumstances.") | ||
| 262 | |||
| 263 | (defvoo nnimap-logout-timeout nil | ||
| 264 | "Close server immediately if it can't logout in this number of seconds. | ||
| 265 | If it is nil, never close server until logout completes. This variable | ||
| 266 | overrides `imap-logout-timeout' on a per-server basis.") | ||
| 267 | |||
| 268 | ;; Authorization / Privacy variables | ||
| 269 | |||
| 270 | (defvoo nnimap-auth-method nil | ||
| 271 | "Obsolete.") | ||
| 272 | |||
| 273 | (defvoo nnimap-stream nil | ||
| 274 | "How nnimap will connect to the server. | ||
| 275 | |||
| 276 | The default, nil, will try to use the \"best\" method the server can | ||
| 277 | handle. | ||
| 278 | |||
| 279 | Change this if | ||
| 280 | |||
| 281 | 1) you want to connect with TLS/SSL. The TLS/SSL integration | ||
| 282 | with IMAP is suboptimal so you'll have to tell it | ||
| 283 | specifically. | ||
| 284 | |||
| 285 | 2) your server is more capable than your environment -- i.e. your | ||
| 286 | server accept Kerberos login's but you haven't installed the | ||
| 287 | `imtest' program or your machine isn't configured for Kerberos. | ||
| 288 | |||
| 289 | Possible choices: gssapi, kerberos4, starttls, tls, ssl, network, shell. | ||
| 290 | See also `imap-streams' and `imap-stream-alist'.") | ||
| 291 | |||
| 292 | (defvoo nnimap-authenticator nil | ||
| 293 | "How nnimap authenticate itself to the server. | ||
| 294 | |||
| 295 | The default, nil, will try to use the \"best\" method the server can | ||
| 296 | handle. | ||
| 297 | |||
| 298 | There is only one reason for fiddling with this variable, and that is | ||
| 299 | if your server is more capable than your environment -- i.e. you | ||
| 300 | connect to a server that accept Kerberos login's but you haven't | ||
| 301 | installed the `imtest' program or your machine isn't configured for | ||
| 302 | Kerberos. | ||
| 303 | |||
| 304 | Possible choices: gssapi, kerberos4, digest-md5, cram-md5, login, anonymous. | ||
| 305 | See also `imap-authenticators' and `imap-authenticator-alist'") | ||
| 306 | |||
| 307 | (defvoo nnimap-directory (nnheader-concat gnus-directory "overview/") | ||
| 308 | "Directory to keep NOV cache files for nnimap groups. | ||
| 309 | See also `nnimap-nov-file-name'.") | ||
| 310 | |||
| 311 | (defvoo nnimap-nov-file-name "nnimap." | ||
| 312 | "NOV cache base filename. | ||
| 313 | The group name and `nnimap-nov-file-name-suffix' will be appended. A | ||
| 314 | typical complete file name would be | ||
| 315 | ~/News/overview/nnimap.pdc.INBOX.ding.nov, or | ||
| 316 | ~/News/overview/nnimap/pdc/INBOX/ding/nov if | ||
| 317 | `nnmail-use-long-file-names' is nil") | ||
| 318 | |||
| 319 | (defvoo nnimap-nov-file-name-suffix ".novcache" | ||
| 320 | "Suffix for NOV cache base filename.") | ||
| 321 | |||
| 322 | (defvoo nnimap-nov-is-evil gnus-agent | ||
| 323 | "If non-nil, never generate or use a local nov database for this backend. | ||
| 324 | Using nov databases should speed up header fetching considerably. | ||
| 325 | However, it will invoke a UID SEARCH UID command on the server, and | ||
| 326 | some servers implement this command inefficiently by opening each and | ||
| 327 | every message in the group, thus making it quite slow. | ||
| 328 | Unlike other backends, you do not need to take special care if you | ||
| 329 | flip this variable.") | ||
| 330 | |||
| 331 | (defvoo nnimap-search-uids-not-since-is-evil nil | ||
| 332 | "If non-nil, avoid \"UID SEARCH UID ... NOT SINCE\" queries when expiring. | ||
| 333 | Instead, use \"UID SEARCH SINCE\" to prune the list of expirable | ||
| 334 | articles within Gnus. This seems to be faster on Courier in some cases.") | ||
| 335 | |||
| 336 | (defvoo nnimap-expunge-on-close 'always ; 'ask, 'never | ||
| 337 | "Whether to expunge a group when it is closed. | ||
| 338 | When a IMAP group with articles marked for deletion is closed, this | ||
| 339 | variable determine if nnimap should actually remove the articles or | ||
| 340 | not. | ||
| 341 | |||
| 342 | If always, nnimap always perform a expunge when closing the group. | ||
| 343 | If never, nnimap never expunges articles marked for deletion. | ||
| 344 | If ask, nnimap will ask you if you wish to expunge marked articles. | ||
| 345 | |||
| 346 | When setting this variable to `never', you can only expunge articles | ||
| 347 | by using `G x' (gnus-group-nnimap-expunge) from the Group buffer.") | ||
| 348 | |||
| 349 | (defvoo nnimap-list-pattern "*" | ||
| 350 | "A string LIMIT or list of strings with mailbox wildcards used to limit available groups. | ||
| 351 | See below for available wildcards. | ||
| 352 | |||
| 353 | The LIMIT string can be a cons cell (REFERENCE . LIMIT), where | ||
| 354 | REFERENCE will be passed as the first parameter to LIST/LSUB. The | ||
| 355 | semantics of this are server specific, on the University of Washington | ||
| 356 | server you can specify a directory. | ||
| 357 | |||
| 358 | Example: | ||
| 359 | '(\"INBOX\" \"mail/*\" (\"~friend/mail/\" . \"list/*\")) | ||
| 360 | |||
| 361 | There are two wildcards * and %. * matches everything, % matches | ||
| 362 | everything in the current hierarchy.") | ||
| 363 | |||
| 364 | (defvoo nnimap-news-groups nil | ||
| 365 | "IMAP support a news-like mode, also known as bulletin board mode, | ||
| 366 | where replies is sent via IMAP instead of SMTP. | ||
| 367 | |||
| 368 | This variable should contain a regexp matching groups where you wish | ||
| 369 | replies to be stored to the mailbox directly. | ||
| 370 | |||
| 371 | Example: | ||
| 372 | '(\"^[^I][^N][^B][^O][^X].*$\") | ||
| 373 | |||
| 374 | This will match all groups not beginning with \"INBOX\". | ||
| 375 | |||
| 376 | Note that there is nothing technically different between mail-like and | ||
| 377 | news-like mailboxes. If you wish to have a group with todo items or | ||
| 378 | similar which you wouldn't want to set up a mailing list for, you can | ||
| 379 | use this to make replies go directly to the group.") | ||
| 380 | |||
| 381 | (defvoo nnimap-expunge-search-string "UID %s NOT SINCE %s" | ||
| 382 | "IMAP search command to use for articles that are to be expired. | ||
| 383 | The first %s is replaced by a UID set of articles to search on, | ||
| 384 | and the second %s is replaced by a date criterium. | ||
| 385 | |||
| 386 | One useful (and perhaps the only useful) value to change this to would | ||
| 387 | be `UID %s NOT SENTSINCE %s' to make nnimap use the Date: header | ||
| 388 | instead of the internal date of messages. See section 6.4.4 of RFC | ||
| 389 | 2060 for more information on valid strings. | ||
| 390 | |||
| 391 | However, if `nnimap-search-uids-not-since-is-evil' is true, this | ||
| 392 | variable has no effect since the search logic is reversed.") | ||
| 393 | |||
| 394 | (defvoo nnimap-importantize-dormant t | ||
| 395 | "If non-nil, mark \"dormant\" articles as \"ticked\" for other IMAP clients. | ||
| 396 | Note that within Gnus, dormant articles will still (only) be | ||
| 397 | marked as ticked. This is to make \"dormant\" articles stand out, | ||
| 398 | just like \"ticked\" articles, in other IMAP clients.") | ||
| 399 | |||
| 400 | (defvoo nnimap-server-address nil | ||
| 401 | "Obsolete. Use `nnimap-address'.") | ||
| 402 | |||
| 403 | (defcustom nnimap-authinfo-file "~/.authinfo" | ||
| 404 | "Authorization information for IMAP servers. In .netrc format." | ||
| 405 | :type | ||
| 406 | '(choice file | ||
| 407 | (repeat :tag "Entries" | ||
| 408 | :menu-tag "Inline" | ||
| 409 | (list :format "%v" | ||
| 410 | :value ("" ("login" . "") ("password" . "")) | ||
| 411 | (string :tag "Host") | ||
| 412 | (checklist :inline t | ||
| 413 | (cons :format "%v" | ||
| 414 | (const :format "" "login") | ||
| 415 | (string :format "Login: %v")) | ||
| 416 | (cons :format "%v" | ||
| 417 | (const :format "" "password") | ||
| 418 | (string :format "Password: %v")))))) | ||
| 419 | :group 'nnimap) | ||
| 420 | |||
| 421 | (defcustom nnimap-prune-cache t | ||
| 422 | "If non-nil, nnimap check whether articles still exist on server before using data stored in NOV cache." | ||
| 423 | :type 'boolean | ||
| 424 | :group 'nnimap) | ||
| 425 | |||
| 426 | (defvar nnimap-request-list-method 'imap-mailbox-list | ||
| 427 | "Method to use to request a list of all folders from the server. | ||
| 428 | If this is 'imap-mailbox-lsub, then use a server-side subscription list to | ||
| 429 | restrict visible folders.") | ||
| 430 | |||
| 431 | (defcustom nnimap-id nil | ||
| 432 | "Plist with client identity to send to server upon login. | ||
| 433 | A nil value means no information is sent, symbol `no' to disable ID query | ||
| 434 | altogether, or plist with identifier-value pairs to send to | ||
| 435 | server. RFC 2971 describes the list as follows: | ||
| 436 | |||
| 437 | Any string may be sent as a field, but the following are defined to | ||
| 438 | describe certain values that might be sent. Implementations are free | ||
| 439 | to send none, any, or all of these. Strings are not case-sensitive. | ||
| 440 | Field strings MUST NOT be longer than 30 octets. Value strings MUST | ||
| 441 | NOT be longer than 1024 octets. Implementations MUST NOT send more | ||
| 442 | than 30 field-value pairs. | ||
| 443 | |||
| 444 | name Name of the program | ||
| 445 | version Version number of the program | ||
| 446 | os Name of the operating system | ||
| 447 | os-version Version of the operating system | ||
| 448 | vendor Vendor of the client/server | ||
| 449 | support-url URL to contact for support | ||
| 450 | address Postal address of contact/vendor | ||
| 451 | date Date program was released, specified as a date-time | ||
| 452 | in IMAP4rev1 | ||
| 453 | command Command used to start the program | ||
| 454 | arguments Arguments supplied on the command line, if any | ||
| 455 | if any | ||
| 456 | environment Description of environment, i.e., UNIX environment | ||
| 457 | variables or Windows registry settings | ||
| 458 | |||
| 459 | Implementations MUST NOT send the same field name more than once. | ||
| 460 | |||
| 461 | An example plist would be '(\"name\" \"Gnus\" \"version\" gnus-version-number | ||
| 462 | \"os\" system-configuration \"vendor\" \"GNU\")." | ||
| 463 | :group 'nnimap | ||
| 464 | :type '(choice (const :tag "No information" nil) | ||
| 465 | (const :tag "Disable ID query" no) | ||
| 466 | (plist :key-type string :value-type string))) | ||
| 467 | |||
| 468 | (defcustom nnimap-debug nil | ||
| 469 | "If non-nil, trace nnimap- functions into `nnimap-debug-buffer'. | ||
| 470 | Uses `trace-function-background', so you can turn it off with, | ||
| 471 | say, `untrace-all'. | ||
| 472 | |||
| 473 | Note that username, passwords and other privacy sensitive | ||
| 474 | information (such as e-mail) may be stored in the buffer. | ||
| 475 | It is not written to disk, however. Do not enable this | ||
| 476 | variable unless you are comfortable with that. | ||
| 477 | |||
| 478 | This variable only takes effect when loading the `nnimap' library. | ||
| 479 | See also `nnimap-log'." | ||
| 480 | :group 'nnimap | ||
| 481 | :type 'boolean) | ||
| 482 | |||
| 483 | ;; Internal variables: | ||
| 484 | |||
| 485 | (defvar nnimap-debug-buffer "*nnimap-debug*") | ||
| 486 | (defvar nnimap-mailbox-info (gnus-make-hashtable 997)) | ||
| 487 | (defvar nnimap-current-move-server nil) | ||
| 488 | (defvar nnimap-current-move-group nil) | ||
| 489 | (defvar nnimap-current-move-article nil) | ||
| 490 | (defvar nnimap-length) | ||
| 491 | (defvar nnimap-progress-chars '(?| ?/ ?- ?\\)) | ||
| 492 | (defvar nnimap-progress-how-often 20) | ||
| 493 | (defvar nnimap-counter) | ||
| 494 | (defvar nnimap-server-buffer-alist nil) ;; Map server name to buffers. | ||
| 495 | (defvar nnimap-current-server nil) ;; Current server | ||
| 496 | (defvar nnimap-server-buffer nil) ;; Current servers' buffer | ||
| 497 | |||
| 498 | |||
| 499 | |||
| 500 | (nnoo-define-basics nnimap) | ||
| 501 | |||
| 502 | ;; Utility functions: | ||
| 503 | |||
| 504 | (defsubst nnimap-decode-group-name (group) | ||
| 505 | (and group | ||
| 506 | (gnus-group-decoded-name group))) | ||
| 507 | |||
| 508 | (defsubst nnimap-encode-group-name (group) | ||
| 509 | (and group | ||
| 510 | (mm-encode-coding-string group (gnus-group-name-charset nil group)))) | ||
| 511 | |||
| 512 | (defun nnimap-group-prefixed-name (group &optional server) | ||
| 513 | (gnus-group-prefixed-name group | ||
| 514 | (gnus-server-to-method | ||
| 515 | (format "nnimap:%s" | ||
| 516 | (or server nnimap-current-server))))) | ||
| 517 | |||
| 518 | (defsubst nnimap-get-server-buffer (server) | ||
| 519 | "Return buffer for SERVER, if nil use current server." | ||
| 520 | (cadr (assoc (or server nnimap-current-server) nnimap-server-buffer-alist))) | ||
| 521 | |||
| 522 | (defun nnimap-remove-server-from-buffer-alist (server list) | ||
| 523 | "Remove SERVER from LIST." | ||
| 524 | (let (l) | ||
| 525 | (dolist (e list) | ||
| 526 | (unless (equal server (car-safe e)) | ||
| 527 | (push e l))) | ||
| 528 | l)) | ||
| 529 | |||
| 530 | (defun nnimap-possibly-change-server (server) | ||
| 531 | "Return buffer for SERVER, changing the current server as a side-effect. | ||
| 532 | If SERVER is nil, uses the current server." | ||
| 533 | (setq nnimap-current-server (or server nnimap-current-server) | ||
| 534 | nnimap-server-buffer (nnimap-get-server-buffer nnimap-current-server))) | ||
| 535 | |||
| 536 | (defun nnimap-verify-uidvalidity (group server) | ||
| 537 | "Verify stored uidvalidity match current one in GROUP on SERVER." | ||
| 538 | (let* ((gnusgroup (nnimap-group-prefixed-name group server)) | ||
| 539 | (new-uidvalidity (imap-mailbox-get 'uidvalidity)) | ||
| 540 | (old-uidvalidity (gnus-group-get-parameter gnusgroup 'uidvalidity)) | ||
| 541 | (dir (file-name-as-directory (expand-file-name nnimap-directory))) | ||
| 542 | (nameuid (nnheader-translate-file-chars | ||
| 543 | (concat nnimap-nov-file-name | ||
| 544 | (if (equal server "") | ||
| 545 | "unnamed" | ||
| 546 | server) "." group "." old-uidvalidity | ||
| 547 | nnimap-nov-file-name-suffix) t)) | ||
| 548 | (file (if (or nnmail-use-long-file-names | ||
| 549 | (file-exists-p (expand-file-name nameuid dir))) | ||
| 550 | (expand-file-name nameuid dir) | ||
| 551 | (expand-file-name | ||
| 552 | (mm-encode-coding-string | ||
| 553 | (nnheader-replace-chars-in-string nameuid ?. ?/) | ||
| 554 | nnmail-pathname-coding-system) | ||
| 555 | dir)))) | ||
| 556 | (if old-uidvalidity | ||
| 557 | (if (not (equal old-uidvalidity new-uidvalidity)) | ||
| 558 | ;; uidvalidity clash | ||
| 559 | (progn | ||
| 560 | (gnus-group-set-parameter gnusgroup 'uidvalidity new-uidvalidity) | ||
| 561 | (gnus-group-remove-parameter gnusgroup 'imap-status) | ||
| 562 | (gnus-sethash (gnus-group-prefixed-name group server) | ||
| 563 | nil nnimap-mailbox-info) | ||
| 564 | (gnus-delete-file file)) | ||
| 565 | t) | ||
| 566 | (gnus-group-add-parameter gnusgroup (cons 'uidvalidity new-uidvalidity)) | ||
| 567 | (gnus-group-remove-parameter gnusgroup 'imap-status) | ||
| 568 | (gnus-sethash ; Maybe not necessary here. | ||
| 569 | (gnus-group-prefixed-name group server) | ||
| 570 | nil nnimap-mailbox-info) | ||
| 571 | t))) | ||
| 572 | 75 | ||
| 573 | (defun nnimap-before-find-minmax-bugworkaround () | 76 | (defvar nnimap-object nil) |
| 574 | "Function called before iterating through mailboxes with | 77 | |
| 575 | `nnimap-find-minmax-uid'." | 78 | (defvar nnimap-mark-alist |
| 576 | (when nnimap-need-unselect-to-notice-new-mail | 79 | '((read "\\Seen") |
| 577 | ;; XXX this is for UoW imapd problem, it doesn't notice new mail in | 80 | (tick "\\Flagged") |
| 578 | ;; currently selected mailbox without a re-select/examine. | 81 | (reply "\\Answered") |
| 579 | (or (null (imap-current-mailbox nnimap-server-buffer)) | 82 | (expire "gnus-expire") |
| 580 | (imap-mailbox-unselect nnimap-server-buffer)))) | 83 | (dormant "gnus-dormant") |
| 581 | 84 | (score "gnus-score") | |
| 582 | (defun nnimap-find-minmax-uid (group &optional examine) | 85 | (save "gnus-save") |
| 583 | "Find lowest and highest active article number in GROUP. | 86 | (download "gnus-download") |
| 584 | If EXAMINE is non-nil the group is selected read-only." | 87 | (forward "gnus-forward"))) |
| 585 | (with-current-buffer nnimap-server-buffer | 88 | |
| 586 | (let ((decoded-group (nnimap-decode-group-name group))) | 89 | (defvar nnimap-split-methods nil) |
| 587 | (when (or (string= decoded-group (imap-current-mailbox)) | 90 | |
| 588 | (imap-mailbox-select decoded-group examine)) | 91 | (defun nnimap-buffer () |
| 589 | (let (minuid maxuid) | 92 | (nnimap-find-process-buffer nntp-server-buffer)) |
| 590 | (when (> (imap-mailbox-get 'exists) 0) | 93 | |
| 591 | (imap-fetch "1:*" "UID" nil 'nouidfetch) | 94 | (defun nnimap-retrieve-headers (articles &optional group server fetch-old) |
| 592 | (imap-message-map | ||
| 593 | (lambda (uid Uid) | ||
| 594 | (setq minuid (if minuid (min minuid uid) uid) | ||
| 595 | maxuid (if maxuid (max maxuid uid) uid))) | ||
| 596 | 'UID)) | ||
| 597 | (list (imap-mailbox-get 'exists) minuid maxuid)))))) | ||
| 598 | |||
| 599 | (defun nnimap-possibly-change-group (group &optional server) | ||
| 600 | "Make GROUP the current group, and SERVER the current server." | ||
| 601 | (when (nnimap-possibly-change-server server) | ||
| 602 | (let ((decoded-group (nnimap-decode-group-name group))) | ||
| 603 | (with-current-buffer nnimap-server-buffer | ||
| 604 | (if (or (null group) (imap-current-mailbox-p decoded-group)) | ||
| 605 | imap-current-mailbox ; Note: utf-7 encoded. | ||
| 606 | (if (imap-mailbox-select decoded-group) | ||
| 607 | (if (or (nnimap-verify-uidvalidity | ||
| 608 | group (or server nnimap-current-server)) | ||
| 609 | (zerop (imap-mailbox-get 'exists decoded-group)) | ||
| 610 | t ;; for OGnus to see if ignoring uidvalidity | ||
| 611 | ;; changes has any bad effects. | ||
| 612 | (yes-or-no-p | ||
| 613 | (format | ||
| 614 | "nnimap: Group %s is not uidvalid. Continue? " | ||
| 615 | decoded-group))) | ||
| 616 | imap-current-mailbox ; Note: utf-7 encoded. | ||
| 617 | (imap-mailbox-unselect) | ||
| 618 | (error "nnimap: Group %s is not uid-valid" decoded-group)) | ||
| 619 | (nnheader-report 'nnimap (imap-error-text)))))))) | ||
| 620 | |||
| 621 | (defun nnimap-replace-whitespace (string) | ||
| 622 | "Return STRING with all whitespace replaced with space." | ||
| 623 | (when string | ||
| 624 | (while (string-match "[\r\n\t]+" string) | ||
| 625 | (setq string (replace-match " " t t string))) | ||
| 626 | string)) | ||
| 627 | |||
| 628 | ;; Required backend functions | ||
| 629 | |||
| 630 | (defun nnimap-retrieve-headers-progress () | ||
| 631 | "Hook to insert NOV line for current article into `nntp-server-buffer'." | ||
| 632 | (and (numberp nnmail-large-newsgroup) | ||
| 633 | (zerop (% (incf nnimap-counter) nnimap-progress-how-often)) | ||
| 634 | (> nnimap-length nnmail-large-newsgroup) | ||
| 635 | (nnheader-message 6 "nnimap: Retrieving headers... %c" | ||
| 636 | (nth (/ (% nnimap-counter | ||
| 637 | (* (length nnimap-progress-chars) | ||
| 638 | nnimap-progress-how-often)) | ||
| 639 | nnimap-progress-how-often) | ||
| 640 | nnimap-progress-chars))) | ||
| 641 | (with-current-buffer nntp-server-buffer | ||
| 642 | (let (headers lines chars uid mbx) | ||
| 643 | (with-current-buffer nnimap-server-buffer | ||
| 644 | (setq uid imap-current-message | ||
| 645 | mbx (nnimap-encode-group-name (imap-current-mailbox)) | ||
| 646 | headers (if (imap-capability 'IMAP4rev1) | ||
| 647 | ;; xxx don't just use car? alist doesn't contain | ||
| 648 | ;; anything else now, but it might... | ||
| 649 | (nth 2 (car (imap-message-get uid 'BODYDETAIL))) | ||
| 650 | (imap-message-get uid 'RFC822.HEADER)) | ||
| 651 | lines (imap-body-lines (imap-message-body imap-current-message)) | ||
| 652 | chars (imap-message-get imap-current-message 'RFC822.SIZE))) | ||
| 653 | (nnheader-insert-nov | ||
| 654 | ;; At this stage, we only have bytes, so let's use unibyte buffers | ||
| 655 | ;; to make it more clear. | ||
| 656 | (mm-with-unibyte-buffer | ||
| 657 | (buffer-disable-undo) | ||
| 658 | ;; headers can be nil if article is write-only | ||
| 659 | (when headers (insert headers)) | ||
| 660 | (let ((head (nnheader-parse-naked-head uid))) | ||
| 661 | (mail-header-set-number head uid) | ||
| 662 | (mail-header-set-chars head chars) | ||
| 663 | (mail-header-set-lines head lines) | ||
| 664 | (mail-header-set-xref | ||
| 665 | head (format "%s %s:%d" (system-name) mbx uid)) | ||
| 666 | head)))))) | ||
| 667 | |||
| 668 | (defun nnimap-retrieve-which-headers (articles fetch-old) | ||
| 669 | "Get a range of articles to fetch based on ARTICLES and FETCH-OLD." | ||
| 670 | (with-current-buffer nnimap-server-buffer | ||
| 671 | (if (numberp (car-safe articles)) | ||
| 672 | (imap-search | ||
| 673 | (concat "UID " | ||
| 674 | (imap-range-to-message-set | ||
| 675 | (gnus-compress-sequence | ||
| 676 | (append (gnus-uncompress-sequence | ||
| 677 | (and fetch-old | ||
| 678 | (cons (if (numberp fetch-old) | ||
| 679 | (max 1 (- (car articles) fetch-old)) | ||
| 680 | 1) | ||
| 681 | (1- (car articles))))) | ||
| 682 | articles))))) | ||
| 683 | (mapcar (lambda (msgid) | ||
| 684 | (imap-search | ||
| 685 | (format "HEADER Message-Id \"%s\"" msgid))) | ||
| 686 | articles)))) | ||
| 687 | |||
| 688 | (defun nnimap-group-overview-filename (group server) | ||
| 689 | "Make file name for GROUP on SERVER." | ||
| 690 | (let* ((dir (file-name-as-directory (expand-file-name nnimap-directory))) | ||
| 691 | (uidvalidity (gnus-group-get-parameter | ||
| 692 | (nnimap-group-prefixed-name group server) | ||
| 693 | 'uidvalidity)) | ||
| 694 | (name (nnheader-translate-file-chars | ||
| 695 | (concat nnimap-nov-file-name | ||
| 696 | (if (equal server "") | ||
| 697 | "unnamed" | ||
| 698 | server) "." group nnimap-nov-file-name-suffix) t)) | ||
| 699 | (nameuid (nnheader-translate-file-chars | ||
| 700 | (concat nnimap-nov-file-name | ||
| 701 | (if (equal server "") | ||
| 702 | "unnamed" | ||
| 703 | server) "." group "." uidvalidity | ||
| 704 | nnimap-nov-file-name-suffix) t)) | ||
| 705 | (oldfile (if (or nnmail-use-long-file-names | ||
| 706 | (file-exists-p (expand-file-name name dir))) | ||
| 707 | (expand-file-name name dir) | ||
| 708 | (expand-file-name | ||
| 709 | (mm-encode-coding-string | ||
| 710 | (nnheader-replace-chars-in-string name ?. ?/) | ||
| 711 | nnmail-pathname-coding-system) | ||
| 712 | dir))) | ||
| 713 | (newfile (if (or nnmail-use-long-file-names | ||
| 714 | (file-exists-p (expand-file-name nameuid dir))) | ||
| 715 | (expand-file-name nameuid dir) | ||
| 716 | (expand-file-name | ||
| 717 | (mm-encode-coding-string | ||
| 718 | (nnheader-replace-chars-in-string nameuid ?. ?/) | ||
| 719 | nnmail-pathname-coding-system) | ||
| 720 | dir)))) | ||
| 721 | (when (and (file-exists-p oldfile) (not (file-exists-p newfile))) | ||
| 722 | (message "nnimap: Upgrading novcache filename...") | ||
| 723 | (sit-for 1) | ||
| 724 | (gnus-make-directory (file-name-directory newfile)) | ||
| 725 | (unless (ignore-errors (rename-file oldfile newfile) t) | ||
| 726 | (if (ignore-errors (copy-file oldfile newfile) t) | ||
| 727 | (delete-file oldfile) | ||
| 728 | (error "Can't rename `%s' to `%s'" oldfile newfile)))) | ||
| 729 | newfile)) | ||
| 730 | |||
| 731 | (defun nnimap-retrieve-headers-from-file (group server) | ||
| 732 | (with-current-buffer nntp-server-buffer | 95 | (with-current-buffer nntp-server-buffer |
| 733 | (let ((nov (nnimap-group-overview-filename group server))) | 96 | (erase-buffer) |
| 734 | (when (file-exists-p nov) | 97 | (when (nnimap-possibly-change-group group server) |
| 735 | (mm-insert-file-contents nov) | 98 | (with-current-buffer (nnimap-buffer) |
| 736 | (set-buffer-modified-p nil) | 99 | (nnimap-send-command "SELECT %S" (utf7-encode group t)) |
| 737 | (let ((min (ignore-errors (goto-char (point-min)) | 100 | (erase-buffer) |
| 738 | (read (current-buffer)))) | 101 | (nnimap-wait-for-response |
| 739 | (max (ignore-errors (goto-char (point-max)) | 102 | (nnimap-send-command |
| 740 | (forward-line -1) | 103 | "UID FETCH %s %s" |
| 741 | (read (current-buffer))))) | 104 | (nnimap-article-ranges (gnus-compress-sequence articles)) |
| 742 | (if (and (numberp min) (numberp max)) | 105 | (format "(UID RFC822.SIZE BODYSTRUCTURE %s)" |
| 743 | (cons min max) | 106 | (format |
| 744 | ;; junk, remove it, it's saved later | 107 | (if (member "IMAP4REV1" |
| 745 | (erase-buffer) | 108 | (nnimap-capabilities nnimap-object)) |
| 746 | nil)))))) | 109 | "BODY.PEEK[HEADER.FIELDS %s]" |
| 747 | 110 | "RFC822.HEADER.LINES %s") | |
| 748 | (defun nnimap-retrieve-headers-from-server (articles group server) | 111 | (append '(Subject From Date Message-Id |
| 749 | (with-current-buffer nnimap-server-buffer | 112 | References In-Reply-To Xref) |
| 750 | (let ((imap-fetch-data-hook '(nnimap-retrieve-headers-progress)) | 113 | nnmail-extra-headers)))) |
| 751 | (nnimap-length (gnus-range-length articles)) | 114 | t) |
| 752 | (nnimap-counter 0)) | 115 | (nnimap-transform-headers)) |
| 753 | (imap-fetch (imap-range-to-message-set articles) | 116 | (insert-buffer-substring |
| 754 | (concat "(UID RFC822.SIZE BODY " | 117 | (nnimap-find-process-buffer (current-buffer)))) |
| 755 | (let ((headers | 118 | t)) |
| 756 | (append '(Subject From Date Message-Id | 119 | |
| 757 | References In-Reply-To Xref) | 120 | (defun nnimap-transform-headers () |
| 758 | (copy-sequence | 121 | (goto-char (point-min)) |
| 759 | nnmail-extra-headers)))) | 122 | (let (article bytes lines) |
| 760 | (if (imap-capability 'IMAP4rev1) | 123 | (block nil |
| 761 | (format "BODY.PEEK[HEADER.FIELDS %s])" headers) | 124 | (while (not (eobp)) |
| 762 | (format "RFC822.HEADER.LINES %s)" headers))))) | 125 | (while (not (looking-at "^\\* [0-9]+ FETCH.*UID \\([0-9]+\\)")) |
| 763 | (with-current-buffer nntp-server-buffer | 126 | (delete-region (point) (progn (forward-line 1) (point))) |
| 764 | (sort-numeric-fields 1 (point-min) (point-max))) | 127 | (when (eobp) |
| 765 | (and (numberp nnmail-large-newsgroup) | 128 | (return))) |
| 766 | (> nnimap-length nnmail-large-newsgroup) | 129 | (setq article (match-string 1) |
| 767 | (nnheader-message 6 "nnimap: Retrieving headers...done"))))) | 130 | bytes (nnimap-get-length) |
| 768 | 131 | lines nil) | |
| 769 | (defun nnimap-dont-use-nov-p (group server) | 132 | (beginning-of-line) |
| 770 | (or gnus-nov-is-evil nnimap-nov-is-evil | 133 | (when (search-forward "BODYSTRUCTURE" (line-end-position) t) |
| 771 | (unless (and (gnus-make-directory | 134 | (let ((structure (ignore-errors (read (current-buffer))))) |
| 772 | (file-name-directory | 135 | (while (and (consp structure) |
| 773 | (nnimap-group-overview-filename group server))) | 136 | (not (stringp (car structure)))) |
| 774 | (file-writable-p | 137 | (setq structure (car structure))) |
| 775 | (nnimap-group-overview-filename group server))) | 138 | (setq lines (nth 7 structure)))) |
| 776 | (message "nnimap: Nov cache not writable, %s" | 139 | (delete-region (line-beginning-position) (line-end-position)) |
| 777 | (nnimap-group-overview-filename group server))))) | 140 | (insert (format "211 %s Article retrieved." article)) |
| 778 | 141 | (forward-line 1) | |
| 779 | (deffoo nnimap-retrieve-headers (articles &optional group server fetch-old) | 142 | (insert (format "Bytes: %d\n" bytes)) |
| 780 | (when (nnimap-possibly-change-group group server) | 143 | (when lines |
| 781 | (with-current-buffer nntp-server-buffer | 144 | (insert (format "Lines: %s\n" lines))) |
| 782 | (erase-buffer) | 145 | (re-search-forward "^\r$") |
| 783 | (if (nnimap-dont-use-nov-p group server) | 146 | (delete-region (line-beginning-position) (line-end-position)) |
| 784 | (nnimap-retrieve-headers-from-server | 147 | (insert ".") |
| 785 | (gnus-compress-sequence articles) group server) | 148 | (forward-line 1))))) |
| 786 | (let (uids cached low high) | 149 | |
| 787 | (when (setq uids (nnimap-retrieve-which-headers articles fetch-old) | 150 | (defun nnimap-get-length () |
| 788 | low (car uids) | 151 | (and (re-search-forward "{\\([0-9]+\\)}" (line-end-position) t) |
| 789 | high (car (last uids))) | 152 | (string-to-number (match-string 1)))) |
| 790 | (if (setq cached (nnimap-retrieve-headers-from-file group server)) | 153 | |
| 791 | (progn | 154 | (defun nnimap-article-ranges (ranges) |
| 792 | ;; fetch articles with uids before cache block | 155 | (let (result) |
| 793 | (when (< low (car cached)) | 156 | (cond |
| 794 | (goto-char (point-min)) | 157 | ((numberp ranges) |
| 795 | (nnimap-retrieve-headers-from-server | 158 | (number-to-string ranges)) |
| 796 | (cons low (1- (car cached))) group server)) | 159 | ((numberp (cdr ranges)) |
| 797 | ;; fetch articles with uids after cache block | 160 | (format "%d:%d" (car ranges) (cdr ranges))) |
| 798 | (when (> high (cdr cached)) | 161 | (t |
| 799 | (goto-char (point-max)) | 162 | (dolist (elem ranges) |
| 800 | (nnimap-retrieve-headers-from-server | 163 | (push |
| 801 | (cons (1+ (cdr cached)) high) group server)) | 164 | (if (consp elem) |
| 802 | (when nnimap-prune-cache | 165 | (format "%d:%d" (car elem) (cdr elem)) |
| 803 | ;; remove nov's for articles which has expired on server | 166 | (number-to-string elem)) |
| 804 | (goto-char (point-min)) | 167 | result)) |
| 805 | (dolist (uid (gnus-set-difference articles uids)) | 168 | (mapconcat #'identity (nreverse result) ","))))) |
| 806 | (when (re-search-forward (format "^%d\t" uid) nil t) | 169 | |
| 807 | (gnus-delete-line))))) | 170 | (defun nnimap-open-server (server &optional defs) |
| 808 | ;; nothing cached, fetch whole range from server | ||
| 809 | (nnimap-retrieve-headers-from-server | ||
| 810 | (cons low high) group server)) | ||
| 811 | (when (buffer-modified-p) | ||
| 812 | (nnmail-write-region | ||
| 813 | (point-min) (point-max) | ||
| 814 | (nnimap-group-overview-filename group server) nil 'nomesg)) | ||
| 815 | (nnheader-nov-delete-outside-range low high)))) | ||
| 816 | 'nov))) | ||
| 817 | |||
| 818 | (declare-function netrc-parse "netrc" (file)) | ||
| 819 | (declare-function netrc-machine-user-or-password "netrc" | ||
| 820 | (mode authinfo-file-or-list machines ports defaults)) | ||
| 821 | |||
| 822 | (defun nnimap-open-connection (server) | ||
| 823 | ;; Note: `nnimap-open-server' that calls this function binds | ||
| 824 | ;; `imap-logout-timeout' to `nnimap-logout-timeout'. | ||
| 825 | (if (not (imap-open nnimap-address nnimap-server-port nnimap-stream | ||
| 826 | nnimap-authenticator nnimap-server-buffer)) | ||
| 827 | (nnheader-report 'nnimap "Can't open connection to server %s" server) | ||
| 828 | (require 'netrc) | ||
| 829 | (unless (or (imap-capability 'IMAP4 nnimap-server-buffer) | ||
| 830 | (imap-capability 'IMAP4rev1 nnimap-server-buffer)) | ||
| 831 | (imap-close nnimap-server-buffer) | ||
| 832 | (nnheader-report 'nnimap "Server %s is not IMAP4 compliant" server)) | ||
| 833 | (let* ((list (progn (gnus-message 7 "Parsing authinfo file `%s'." | ||
| 834 | nnimap-authinfo-file) | ||
| 835 | (netrc-parse nnimap-authinfo-file))) | ||
| 836 | (port (if nnimap-server-port | ||
| 837 | (int-to-string nnimap-server-port) | ||
| 838 | "imap")) | ||
| 839 | (auth-info | ||
| 840 | (auth-source-user-or-password '("login" "password") server port)) | ||
| 841 | (auth-user (nth 0 auth-info)) | ||
| 842 | (auth-passwd (nth 1 auth-info)) | ||
| 843 | (user (or | ||
| 844 | auth-user ; this is preferred to netrc-* | ||
| 845 | (netrc-machine-user-or-password | ||
| 846 | "login" | ||
| 847 | list | ||
| 848 | (list server | ||
| 849 | (or nnimap-server-address | ||
| 850 | nnimap-address)) | ||
| 851 | (list port) | ||
| 852 | (list "imap" "imaps" "143" "993")))) | ||
| 853 | (passwd (or | ||
| 854 | auth-passwd ; this is preferred to netrc-* | ||
| 855 | (netrc-machine-user-or-password | ||
| 856 | "password" | ||
| 857 | list | ||
| 858 | (list server | ||
| 859 | (or nnimap-server-address | ||
| 860 | nnimap-address)) | ||
| 861 | (list port) | ||
| 862 | (list "imap" "imaps" "143" "993"))))) | ||
| 863 | (if (imap-authenticate user passwd nnimap-server-buffer) | ||
| 864 | (prog2 | ||
| 865 | (setq nnimap-server-buffer-alist | ||
| 866 | (nnimap-remove-server-from-buffer-alist | ||
| 867 | server | ||
| 868 | nnimap-server-buffer-alist)) | ||
| 869 | (push (list server nnimap-server-buffer) | ||
| 870 | nnimap-server-buffer-alist) | ||
| 871 | (imap-id nnimap-id nnimap-server-buffer) | ||
| 872 | (nnimap-possibly-change-server server)) | ||
| 873 | (imap-close nnimap-server-buffer) | ||
| 874 | (kill-buffer nnimap-server-buffer) | ||
| 875 | (nnheader-report 'nnimap "Could not authenticate to %s" server))))) | ||
| 876 | |||
| 877 | (deffoo nnimap-open-server (server &optional defs) | ||
| 878 | (nnheader-init-server-buffer) | ||
| 879 | (if (nnimap-server-opened server) | 171 | (if (nnimap-server-opened server) |
| 880 | t | 172 | t |
| 881 | (unless (assq 'nnimap-server-buffer defs) | ||
| 882 | (push (list 'nnimap-server-buffer (concat " *nnimap* " server)) defs)) | ||
| 883 | ;; translate `nnimap-server-address' to `nnimap-address' in defs | ||
| 884 | ;; for people that configured nnimap with a very old version | ||
| 885 | (unless (assq 'nnimap-address defs) | 173 | (unless (assq 'nnimap-address defs) |
| 886 | (if (assq 'nnimap-server-address defs) | 174 | (setq defs (append defs (list (list 'nnimap-address server))))) |
| 887 | (push (list 'nnimap-address | ||
| 888 | (cadr (assq 'nnimap-server-address defs))) defs) | ||
| 889 | (push (list 'nnimap-address server) defs))) | ||
| 890 | (nnoo-change-server 'nnimap server defs) | 175 | (nnoo-change-server 'nnimap server defs) |
| 891 | (or nnimap-server-buffer | 176 | (or (nnimap-find-connection nntp-server-buffer) |
| 892 | (setq nnimap-server-buffer (cadr (assq 'nnimap-server-buffer defs)))) | 177 | (nnimap-open-connection nntp-server-buffer)))) |
| 893 | (with-current-buffer (get-buffer-create nnimap-server-buffer) | 178 | |
| 894 | (nnoo-change-server 'nnimap server defs)) | 179 | (defun nnimap-make-process-buffer (buffer) |
| 895 | (let ((imap-logout-timeout nnimap-logout-timeout)) | 180 | (with-current-buffer |
| 896 | (or (and nnimap-server-buffer | 181 | (generate-new-buffer (format "*nnimap %s %s %s*" |
| 897 | (imap-opened nnimap-server-buffer) | 182 | nnimap-address nnimap-server-port |
| 898 | (if (with-current-buffer nnimap-server-buffer | 183 | (gnus-buffer-exists-p buffer))) |
| 899 | (memq imap-state '(auth selected examine))) | 184 | (mm-disable-multibyte) |
| 900 | t | 185 | (buffer-disable-undo) |
| 901 | (imap-close nnimap-server-buffer) | 186 | (gnus-add-buffer) |
| 902 | (nnimap-open-connection server))) | 187 | (set (make-local-variable 'after-change-functions) nil) |
| 903 | (nnimap-open-connection server))))) | 188 | (set (make-local-variable 'nnimap-object) (make-nnimap)) |
| 904 | 189 | (push (list buffer (current-buffer)) nnimap-connection-alist) | |
| 905 | (deffoo nnimap-server-opened (&optional server) | 190 | (current-buffer))) |
| 906 | "Whether SERVER is opened. | 191 | |
| 907 | If SERVER is the current virtual server, and the connection to the | 192 | (defun nnimap-open-shell-stream (name buffer host port) |
| 908 | physical server is alive, this function return a non-nil value. If | 193 | (let ((process (start-process name buffer shell-file-name |
| 909 | SERVER is nil, it is treated as the current server." | 194 | shell-command-switch |
| 910 | ;; clean up autologouts?? | 195 | (format-spec |
| 911 | (and (or server nnimap-current-server) | 196 | nnimap-shell-program |
| 912 | (nnoo-server-opened 'nnimap (or server nnimap-current-server)) | 197 | (format-spec-make |
| 913 | (imap-opened (nnimap-get-server-buffer server)))) | 198 | ?s host |
| 914 | 199 | ?p port))))) | |
| 915 | (deffoo nnimap-close-server (&optional server) | 200 | process)) |
| 916 | "Close connection to server and free all resources connected to it. | 201 | |
| 917 | Return nil if the server couldn't be closed for some reason." | 202 | (defun nnimap-open-connection (buffer) |
| 918 | (let ((server (or server nnimap-current-server)) | 203 | (with-current-buffer (nnimap-make-process-buffer buffer) |
| 919 | (imap-logout-timeout nnimap-logout-timeout)) | 204 | (let* ((coding-system-for-read 'binary) |
| 920 | (when (or (nnimap-server-opened server) | 205 | (coding-system-for-write 'binary) |
| 921 | (imap-opened (nnimap-get-server-buffer server))) | 206 | (credentials |
| 922 | (imap-close (nnimap-get-server-buffer server)) | 207 | (cond |
| 923 | (kill-buffer (nnimap-get-server-buffer server)) | 208 | ((eq nnimap-stream 'network) |
| 924 | (setq nnimap-server-buffer nil | 209 | (open-network-stream "*nnimap*" (current-buffer) nnimap-address |
| 925 | nnimap-current-server nil | 210 | (or nnimap-server-port |
| 926 | nnimap-server-buffer-alist | 211 | (if (netrc-find-service-number "imap") |
| 927 | (nnimap-remove-server-from-buffer-alist | 212 | "imap" |
| 928 | server | 213 | "143"))) |
| 929 | nnimap-server-buffer-alist))) | 214 | (auth-source-user-or-password |
| 930 | (nnoo-close-server 'nnimap server))) | 215 | '("login" "password") nnimap-address "imap" nil t)) |
| 931 | 216 | ((eq nnimap-stream 'stream) | |
| 932 | (deffoo nnimap-request-close () | 217 | (nnimap-open-shell-stream |
| 933 | "Close connection to all servers and free all resources that the backend have reserved. | 218 | "*nnimap*" (current-buffer) nnimap-address |
| 934 | All buffers that have been created by that | 219 | (or nnimap-server-port "imap")) |
| 935 | backend should be killed. (Not the nntp-server-buffer, though.) This | 220 | (auth-source-user-or-password |
| 936 | function is generally only called when Gnus is shutting down." | 221 | '("login" "password") nnimap-address "imap" nil t)) |
| 937 | (mapc (lambda (server) (nnimap-close-server (car server))) | 222 | ((eq nnimap-stream 'ssl) |
| 938 | nnimap-server-buffer-alist) | 223 | (open-tls-stream "*nnimap*" (current-buffer) nnimap-address |
| 939 | (setq nnimap-server-buffer-alist nil)) | 224 | (or nnimap-server-port |
| 940 | 225 | (if (netrc-find-service-number "imaps") | |
| 941 | (deffoo nnimap-status-message (&optional server) | 226 | "imaps" |
| 942 | "This function returns the last error message from server." | 227 | "993"))) |
| 943 | (when (nnimap-possibly-change-server server) | 228 | (or |
| 944 | (nnoo-status-message 'nnimap server))) | 229 | (auth-source-user-or-password |
| 945 | 230 | '("login" "password") nnimap-address "imap") | |
| 946 | ;; We used to use a string-as-multibyte here, but it is really incorrect. | 231 | (auth-source-user-or-password |
| 947 | ;; This function is used when we're about to insert a unibyte string | 232 | '("login" "password") nnimap-address "imaps" nil t)))))) |
| 948 | ;; into a potentially multibyte buffer. The string is either an article | 233 | (setf (nnimap-process nnimap-object) |
| 949 | ;; header or body (or both?), undecoded. When Emacs is asked to convert | 234 | (get-buffer-process (current-buffer))) |
| 950 | ;; a unibyte string to multibyte, it may either use the equivalent of | 235 | (unless credentials |
| 951 | ;; nothing (e.g. non-Mule XEmacs), string-make-unibyte (i.e. decode using | 236 | (delete-process (nnimap-process nnimap-object))) |
| 952 | ;; locale), string-as-multibyte (decode using emacs-internal coding system) | 237 | (when (and (nnimap-process nnimap-object) |
| 953 | ;; or string-to-multibyte (keep the data undecoded as a sequence of bytes). | 238 | (memq (process-status (nnimap-process nnimap-object)) |
| 954 | ;; Only the last one preserves the data such that we can reliably later on | 239 | '(open run))) |
| 955 | ;; decode the text using the mime info. | 240 | (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil) |
| 956 | (defalias 'nnimap-demule 'mm-string-to-multibyte) | 241 | (let ((result (nnimap-command "LOGIN %S %S" |
| 957 | 242 | (car credentials) (cadr credentials)))) | |
| 958 | (defun nnimap-make-callback (article gnus-callback buffer) | 243 | (if (not (car result)) |
| 959 | "Return a callback function." | 244 | (progn |
| 960 | `(lambda () | 245 | (delete-process (nnimap-process nnimap-object)) |
| 961 | (nnimap-callback ,article ,gnus-callback ,buffer))) | 246 | nil) |
| 962 | 247 | (setf (nnimap-capabilities nnimap-object) | |
| 963 | (defun nnimap-callback (article gnus-callback buffer) | 248 | (mapcar |
| 964 | (when (eq article (imap-current-message)) | 249 | #'upcase |
| 965 | (remove-hook 'imap-fetch-data-hook | 250 | (or (nnimap-find-parameter "CAPABILITY" (cdr result)) |
| 966 | (nnimap-make-callback article gnus-callback buffer)) | 251 | (nnimap-find-parameter |
| 967 | (with-current-buffer buffer | 252 | "CAPABILITY" (cdr (nnimap-command "CAPABILITY")))))) |
| 968 | (insert | 253 | (when (member "QRESYNC" (nnimap-capabilities nnimap-object)) |
| 969 | (with-current-buffer nnimap-server-buffer | 254 | (nnimap-command "ENABLE QRESYNC")) |
| 970 | (nnimap-demule | 255 | t)))))) |
| 971 | (if (imap-capability 'IMAP4rev1) | 256 | |
| 972 | ;; xxx don't just use car? alist doesn't contain | 257 | (defun nnimap-find-parameter (parameter elems) |
| 973 | ;; anything else now, but it might... | 258 | (let (result) |
| 974 | (nth 2 (car (imap-message-get article 'BODYDETAIL))) | 259 | (dolist (elem elems) |
| 975 | (imap-message-get article 'RFC822))))) | 260 | (cond |
| 976 | (nnheader-ms-strip-cr) | 261 | ((equal (car elem) parameter) |
| 977 | (funcall gnus-callback t)))) | 262 | (setq result (cdr elem))) |
| 978 | 263 | ((and (equal (car elem) "OK") | |
| 979 | (defun nnimap-request-article-part (article part prop &optional | 264 | (consp (cadr elem)) |
| 980 | group server to-buffer detail) | 265 | (equal (caadr elem) parameter)) |
| 981 | (when (nnimap-possibly-change-group group server) | 266 | (setq result (cdr (cadr elem)))))) |
| 982 | (let ((article (if (stringp article) | 267 | result)) |
| 983 | (car-safe (imap-search | 268 | |
| 984 | (format "HEADER Message-Id \"%s\"" article) | 269 | (defun nnimap-close-server (&optional server) |
| 985 | nnimap-server-buffer)) | ||
| 986 | article))) | ||
| 987 | (when article | ||
| 988 | (gnus-message 10 "nnimap: Fetching (part of) article %d from %s..." | ||
| 989 | article (or (nnimap-decode-group-name group) | ||
| 990 | (imap-current-mailbox) | ||
| 991 | (nnimap-decode-group-name | ||
| 992 | gnus-newsgroup-name))) | ||
| 993 | (if (not nnheader-callback-function) | ||
| 994 | (with-current-buffer (or to-buffer nntp-server-buffer) | ||
| 995 | (erase-buffer) | ||
| 996 | (let ((data (imap-fetch article part prop nil | ||
| 997 | nnimap-server-buffer))) | ||
| 998 | ;; data can be nil if article is write-only | ||
| 999 | (when data | ||
| 1000 | (insert (nnimap-demule (if detail | ||
| 1001 | (nth 2 (car data)) | ||
| 1002 | data))))) | ||
| 1003 | (nnheader-ms-strip-cr) | ||
| 1004 | (gnus-message | ||
| 1005 | 10 "nnimap: Fetching (part of) article %d from %s...done" | ||
| 1006 | article (or (nnimap-decode-group-name group) | ||
| 1007 | (imap-current-mailbox) | ||
| 1008 | (nnimap-decode-group-name gnus-newsgroup-name))) | ||
| 1009 | (if (bobp) | ||
| 1010 | (nnheader-report 'nnimap "No such article %d in %s: %s" | ||
| 1011 | article (or (nnimap-decode-group-name group) | ||
| 1012 | (imap-current-mailbox) | ||
| 1013 | (nnimap-decode-group-name | ||
| 1014 | gnus-newsgroup-name)) | ||
| 1015 | (imap-error-text nnimap-server-buffer)) | ||
| 1016 | (cons group article))) | ||
| 1017 | (add-hook 'imap-fetch-data-hook | ||
| 1018 | (nnimap-make-callback article | ||
| 1019 | nnheader-callback-function | ||
| 1020 | nntp-server-buffer)) | ||
| 1021 | (imap-fetch-asynch article part nil nnimap-server-buffer) | ||
| 1022 | (cons group article)))))) | ||
| 1023 | |||
| 1024 | (deffoo nnimap-asynchronous-p () | ||
| 1025 | t) | 270 | t) |
| 1026 | 271 | ||
| 1027 | (deffoo nnimap-request-article (article &optional group server to-buffer) | 272 | (defun nnimap-request-close () |
| 1028 | (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) | 273 | t) |
| 1029 | (nnimap-request-article-part | ||
| 1030 | article "BODY.PEEK[]" 'BODYDETAIL group server to-buffer 'detail) | ||
| 1031 | (nnimap-request-article-part | ||
| 1032 | article "RFC822.PEEK" 'RFC822 group server to-buffer))) | ||
| 1033 | |||
| 1034 | (deffoo nnimap-request-head (article &optional group server to-buffer) | ||
| 1035 | (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) | ||
| 1036 | (nnimap-request-article-part | ||
| 1037 | article "BODY.PEEK[HEADER]" 'BODYDETAIL group server to-buffer 'detail) | ||
| 1038 | (nnimap-request-article-part | ||
| 1039 | article "RFC822.HEADER" 'RFC822.HEADER group server to-buffer))) | ||
| 1040 | |||
| 1041 | (deffoo nnimap-request-body (article &optional group server to-buffer) | ||
| 1042 | (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) | ||
| 1043 | (nnimap-request-article-part | ||
| 1044 | article "BODY.PEEK[TEXT]" 'BODYDETAIL group server to-buffer 'detail) | ||
| 1045 | (nnimap-request-article-part | ||
| 1046 | article "RFC822.TEXT.PEEK" 'RFC822.TEXT group server to-buffer))) | ||
| 1047 | |||
| 1048 | (deffoo nnimap-request-group (group &optional server fast) | ||
| 1049 | (nnimap-request-update-info-internal | ||
| 1050 | group | ||
| 1051 | (gnus-get-info (nnimap-group-prefixed-name group server)) | ||
| 1052 | server) | ||
| 1053 | (when (nnimap-possibly-change-group group server) | ||
| 1054 | (nnimap-before-find-minmax-bugworkaround) | ||
| 1055 | (let (info) | ||
| 1056 | (cond (fast group) | ||
| 1057 | ((null (setq info (nnimap-find-minmax-uid group t))) | ||
| 1058 | (nnheader-report 'nnimap "Could not get active info for %s" | ||
| 1059 | group)) | ||
| 1060 | (t | ||
| 1061 | (nnheader-insert "211 %d %d %d %s\n" (or (nth 0 info) 0) | ||
| 1062 | (max 1 (or (nth 1 info) 1)) | ||
| 1063 | (or (nth 2 info) 0) group) | ||
| 1064 | (nnheader-report 'nnimap "Group %s selected" group) | ||
| 1065 | t))))) | ||
| 1066 | |||
| 1067 | (defun nnimap-update-unseen (group &optional server) | ||
| 1068 | "Update the unseen count in `nnimap-mailbox-info'." | ||
| 1069 | (gnus-sethash | ||
| 1070 | (gnus-group-prefixed-name group server) | ||
| 1071 | (let ((old (gnus-gethash-safe (gnus-group-prefixed-name group server) | ||
| 1072 | nnimap-mailbox-info))) | ||
| 1073 | (list (nth 0 old) (nth 1 old) | ||
| 1074 | (imap-mailbox-status (nnimap-decode-group-name group) | ||
| 1075 | 'unseen nnimap-server-buffer))) | ||
| 1076 | nnimap-mailbox-info)) | ||
| 1077 | 274 | ||
| 1078 | (defun nnimap-close-group (group &optional server) | 275 | (defun nnimap-server-opened (&optional server) |
| 1079 | (with-current-buffer nnimap-server-buffer | 276 | (and (nnoo-current-server-p 'nnimap server) |
| 1080 | (when (and (imap-opened) | 277 | nntp-server-buffer |
| 1081 | (nnimap-possibly-change-group group server)) | 278 | (gnus-buffer-live-p nntp-server-buffer) |
| 1082 | (nnimap-update-unseen group server) | 279 | (nnimap-find-connection nntp-server-buffer))) |
| 1083 | (case nnimap-expunge-on-close | ||
| 1084 | (always (progn | ||
| 1085 | (imap-mailbox-expunge nnimap-close-asynchronous) | ||
| 1086 | (unless nnimap-dont-close | ||
| 1087 | (imap-mailbox-close nnimap-close-asynchronous)))) | ||
| 1088 | (ask (if (and (imap-search "DELETED") | ||
| 1089 | (gnus-y-or-n-p (format "Expunge articles in group `%s'? " | ||
| 1090 | (imap-current-mailbox)))) | ||
| 1091 | (progn | ||
| 1092 | (imap-mailbox-expunge nnimap-close-asynchronous) | ||
| 1093 | (unless nnimap-dont-close | ||
| 1094 | (imap-mailbox-close nnimap-close-asynchronous))) | ||
| 1095 | (imap-mailbox-unselect))) | ||
| 1096 | (t (imap-mailbox-unselect))) | ||
| 1097 | (not imap-current-mailbox)))) | ||
| 1098 | |||
| 1099 | (defun nnimap-pattern-to-list-arguments (pattern) | ||
| 1100 | (mapcar (lambda (p) | ||
| 1101 | (cons (car-safe p) (or (cdr-safe p) p))) | ||
| 1102 | (if (and (listp pattern) | ||
| 1103 | (listp (cdr pattern))) | ||
| 1104 | pattern | ||
| 1105 | (list pattern)))) | ||
| 1106 | |||
| 1107 | (deffoo nnimap-request-list (&optional server) | ||
| 1108 | (when (nnimap-possibly-change-server server) | ||
| 1109 | (with-current-buffer nntp-server-buffer | ||
| 1110 | (erase-buffer)) | ||
| 1111 | (gnus-message 5 "nnimap: Generating active list%s..." | ||
| 1112 | (if (> (length server) 0) (concat " for " server) "")) | ||
| 1113 | (nnimap-before-find-minmax-bugworkaround) | ||
| 1114 | (with-current-buffer nnimap-server-buffer | ||
| 1115 | (dolist (pattern (nnimap-pattern-to-list-arguments nnimap-list-pattern)) | ||
| 1116 | (dolist (mbx (funcall nnimap-request-list-method | ||
| 1117 | (cdr pattern) (car pattern))) | ||
| 1118 | (unless (member "\\noselect" | ||
| 1119 | (mapcar #'downcase | ||
| 1120 | (imap-mailbox-get 'list-flags mbx))) | ||
| 1121 | (let* ((encoded-mbx (nnimap-encode-group-name mbx)) | ||
| 1122 | (info (nnimap-find-minmax-uid encoded-mbx 'examine))) | ||
| 1123 | (when info | ||
| 1124 | (with-current-buffer nntp-server-buffer | ||
| 1125 | (insert (format "\"%s\" %d %d y\n" | ||
| 1126 | encoded-mbx (or (nth 2 info) 0) | ||
| 1127 | (max 1 (or (nth 1 info) 1))))))))))) | ||
| 1128 | (gnus-message 5 "nnimap: Generating active list%s...done" | ||
| 1129 | (if (> (length server) 0) (concat " for " server) "")) | ||
| 1130 | t)) | ||
| 1131 | 280 | ||
| 1132 | (deffoo nnimap-request-post (&optional server) | 281 | (defun nnimap-status-message (&optional server) |
| 1133 | (let ((success t)) | 282 | nnimap-status-string) |
| 1134 | (dolist (mbx (message-unquote-tokens | ||
| 1135 | (message-tokenize-header | ||
| 1136 | (message-fetch-field "Newsgroups") ", ")) success) | ||
| 1137 | (let ((to-newsgroup (gnus-group-prefixed-name mbx gnus-command-method))) | ||
| 1138 | (or (gnus-active to-newsgroup) | ||
| 1139 | (gnus-activate-group to-newsgroup) | ||
| 1140 | (if (gnus-y-or-n-p (format "No such group: %s. Create it? " | ||
| 1141 | to-newsgroup)) | ||
| 1142 | (or (and (gnus-request-create-group | ||
| 1143 | to-newsgroup gnus-command-method) | ||
| 1144 | (gnus-activate-group to-newsgroup nil nil | ||
| 1145 | gnus-command-method)) | ||
| 1146 | (error "Couldn't create group %s" to-newsgroup))) | ||
| 1147 | (error "No such group: %s" to-newsgroup)) | ||
| 1148 | (unless (nnimap-request-accept-article mbx (nth 1 gnus-command-method)) | ||
| 1149 | (setq success nil)))))) | ||
| 1150 | |||
| 1151 | ;; Optional backend functions | ||
| 1152 | |||
| 1153 | (defun nnimap-string-lessp-numerical (s1 s2) | ||
| 1154 | "Return t if first arg string is less than second in numerical order." | ||
| 1155 | (cond ((string= s1 s2) | ||
| 1156 | nil) | ||
| 1157 | ((> (length s1) (length s2)) | ||
| 1158 | nil) | ||
| 1159 | ((< (length s1) (length s2)) | ||
| 1160 | t) | ||
| 1161 | ((< (string-to-number (substring s1 0 1)) | ||
| 1162 | (string-to-number (substring s2 0 1))) | ||
| 1163 | t) | ||
| 1164 | ((> (string-to-number (substring s1 0 1)) | ||
| 1165 | (string-to-number (substring s2 0 1))) | ||
| 1166 | nil) | ||
| 1167 | (t | ||
| 1168 | (nnimap-string-lessp-numerical (substring s1 1) (substring s2 1))))) | ||
| 1169 | |||
| 1170 | (deffoo nnimap-retrieve-groups (groups &optional server) | ||
| 1171 | (when (nnimap-possibly-change-server server) | ||
| 1172 | (gnus-message 5 "nnimap: Checking mailboxes...") | ||
| 1173 | (with-current-buffer nntp-server-buffer | ||
| 1174 | (erase-buffer) | ||
| 1175 | (nnimap-before-find-minmax-bugworkaround) | ||
| 1176 | (let (asyncgroups slowgroups decoded-group) | ||
| 1177 | (if (null nnimap-retrieve-groups-asynchronous) | ||
| 1178 | (setq slowgroups groups) | ||
| 1179 | (dolist (group groups) | ||
| 1180 | (setq decoded-group (nnimap-decode-group-name group)) | ||
| 1181 | (gnus-message 9 "nnimap: Quickly checking mailbox %s" | ||
| 1182 | decoded-group) | ||
| 1183 | (add-to-list (if (gnus-group-get-parameter | ||
| 1184 | (nnimap-group-prefixed-name group) | ||
| 1185 | 'imap-status) | ||
| 1186 | 'asyncgroups | ||
| 1187 | 'slowgroups) | ||
| 1188 | (list group (imap-mailbox-status-asynch | ||
| 1189 | decoded-group | ||
| 1190 | '(uidvalidity uidnext unseen) | ||
| 1191 | nnimap-server-buffer)))) | ||
| 1192 | (dolist (asyncgroup asyncgroups) | ||
| 1193 | (let* ((group (nth 0 asyncgroup)) | ||
| 1194 | (tag (nth 1 asyncgroup)) | ||
| 1195 | (gnusgroup (nnimap-group-prefixed-name group)) | ||
| 1196 | (saved-uidvalidity (gnus-group-get-parameter gnusgroup | ||
| 1197 | 'uidvalidity)) | ||
| 1198 | (saved-imap-status (gnus-group-get-parameter gnusgroup | ||
| 1199 | 'imap-status)) | ||
| 1200 | (saved-info (and saved-imap-status | ||
| 1201 | (split-string saved-imap-status " ")))) | ||
| 1202 | (setq decoded-group (nnimap-decode-group-name group)) | ||
| 1203 | (when (imap-ok-p (imap-wait-for-tag tag nnimap-server-buffer)) | ||
| 1204 | (if (or (not (equal | ||
| 1205 | saved-uidvalidity | ||
| 1206 | (imap-mailbox-get 'uidvalidity decoded-group | ||
| 1207 | nnimap-server-buffer))) | ||
| 1208 | (not (equal | ||
| 1209 | (nth 0 saved-info) | ||
| 1210 | (imap-mailbox-get 'uidnext decoded-group | ||
| 1211 | nnimap-server-buffer)))) | ||
| 1212 | (push (list group) slowgroups) | ||
| 1213 | (gnus-sethash | ||
| 1214 | (gnus-group-prefixed-name group server) | ||
| 1215 | (list (imap-mailbox-get 'uidvalidity | ||
| 1216 | decoded-group nnimap-server-buffer) | ||
| 1217 | (imap-mailbox-get 'uidnext | ||
| 1218 | decoded-group nnimap-server-buffer) | ||
| 1219 | (imap-mailbox-get 'unseen | ||
| 1220 | decoded-group nnimap-server-buffer)) | ||
| 1221 | nnimap-mailbox-info) | ||
| 1222 | (insert (format "\"%s\" %s %s y\n" group | ||
| 1223 | (nth 2 saved-info) | ||
| 1224 | (nth 1 saved-info)))))))) | ||
| 1225 | (dolist (group slowgroups) | ||
| 1226 | (if nnimap-retrieve-groups-asynchronous | ||
| 1227 | (setq group (car group))) | ||
| 1228 | (setq decoded-group (nnimap-decode-group-name group)) | ||
| 1229 | (gnus-message 7 "nnimap: Mailbox %s modified" decoded-group) | ||
| 1230 | (or (member "\\NoSelect" (imap-mailbox-get 'list-flags decoded-group | ||
| 1231 | nnimap-server-buffer)) | ||
| 1232 | (let* ((gnusgroup (nnimap-group-prefixed-name group)) | ||
| 1233 | (status (imap-mailbox-status | ||
| 1234 | decoded-group '(uidvalidity uidnext unseen) | ||
| 1235 | nnimap-server-buffer)) | ||
| 1236 | (info (nnimap-find-minmax-uid group 'examine)) | ||
| 1237 | (min-uid (max 1 (or (nth 1 info) 1))) | ||
| 1238 | (max-uid (or (nth 2 info) 0))) | ||
| 1239 | (when (> (or (imap-mailbox-get 'recent decoded-group | ||
| 1240 | nnimap-server-buffer) 0) | ||
| 1241 | 0) | ||
| 1242 | (push (list (cons decoded-group 0)) nnmail-split-history)) | ||
| 1243 | (insert (format "\"%s\" %d %d y\n" group max-uid min-uid)) | ||
| 1244 | (gnus-sethash | ||
| 1245 | (gnus-group-prefixed-name group server) | ||
| 1246 | status | ||
| 1247 | nnimap-mailbox-info) | ||
| 1248 | (if (not (equal (nth 0 status) | ||
| 1249 | (gnus-group-get-parameter gnusgroup | ||
| 1250 | 'uidvalidity))) | ||
| 1251 | (nnimap-verify-uidvalidity group nnimap-current-server)) | ||
| 1252 | ;; The imap-status parameter is a string on the form | ||
| 1253 | ;; "<uidnext> <min-uid> <max-uid>". | ||
| 1254 | (gnus-group-add-parameter | ||
| 1255 | gnusgroup | ||
| 1256 | (cons 'imap-status | ||
| 1257 | (format "%s %s %s" (nth 1 status) min-uid max-uid)))))))) | ||
| 1258 | (gnus-message 5 "nnimap: Checking mailboxes...done") | ||
| 1259 | 'active)) | ||
| 1260 | |||
| 1261 | (deffoo nnimap-request-update-info-internal (group info &optional server) | ||
| 1262 | (when (nnimap-possibly-change-group group server) | ||
| 1263 | (when info ;; xxx what does this mean? should we create a info? | ||
| 1264 | (with-current-buffer nnimap-server-buffer | ||
| 1265 | (gnus-message 5 "nnimap: Updating info for %s..." | ||
| 1266 | (nnimap-decode-group-name (gnus-info-group info))) | ||
| 1267 | |||
| 1268 | (when (nnimap-mark-permanent-p 'read) | ||
| 1269 | (let (seen unseen) | ||
| 1270 | ;; read info could contain articles marked unread by other | ||
| 1271 | ;; imap clients! we correct this | ||
| 1272 | (setq unseen (gnus-compress-sequence | ||
| 1273 | (imap-search "UNSEEN UNDELETED")) | ||
| 1274 | seen (gnus-range-difference (gnus-info-read info) unseen) | ||
| 1275 | seen (gnus-range-add seen | ||
| 1276 | (gnus-compress-sequence | ||
| 1277 | (imap-search "SEEN"))) | ||
| 1278 | seen (if (and (integerp (car seen)) | ||
| 1279 | (null (cdr seen))) | ||
| 1280 | (list (cons (car seen) (car seen))) | ||
| 1281 | seen)) | ||
| 1282 | (gnus-info-set-read info seen))) | ||
| 1283 | |||
| 1284 | (dolist (pred gnus-article-mark-lists) | ||
| 1285 | (when (or (eq (cdr pred) 'recent) | ||
| 1286 | (and (nnimap-mark-permanent-p (cdr pred)) | ||
| 1287 | (member (nnimap-mark-to-flag (cdr pred)) | ||
| 1288 | (imap-mailbox-get 'flags)))) | ||
| 1289 | (gnus-info-set-marks | ||
| 1290 | info | ||
| 1291 | (gnus-update-alist-soft | ||
| 1292 | (cdr pred) | ||
| 1293 | (gnus-compress-sequence | ||
| 1294 | (imap-search (nnimap-mark-to-predicate (cdr pred)))) | ||
| 1295 | (gnus-info-marks info)) | ||
| 1296 | t))) | ||
| 1297 | |||
| 1298 | (when nnimap-importantize-dormant | ||
| 1299 | ;; nnimap mark dormant article as ticked too (for other clients) | ||
| 1300 | ;; so we remove that mark for gnus since we support dormant | ||
| 1301 | (gnus-info-set-marks | ||
| 1302 | info | ||
| 1303 | (gnus-update-alist-soft | ||
| 1304 | 'tick | ||
| 1305 | (gnus-remove-from-range | ||
| 1306 | (cdr-safe (assoc 'tick (gnus-info-marks info))) | ||
| 1307 | (cdr-safe (assoc 'dormant (gnus-info-marks info)))) | ||
| 1308 | (gnus-info-marks info)) | ||
| 1309 | t)) | ||
| 1310 | |||
| 1311 | (gnus-message 5 "nnimap: Updating info for %s...done" | ||
| 1312 | (nnimap-decode-group-name (gnus-info-group info))) | ||
| 1313 | |||
| 1314 | info)))) | ||
| 1315 | |||
| 1316 | (deffoo nnimap-request-type (group &optional article) | ||
| 1317 | (if (and nnimap-news-groups (string-match nnimap-news-groups group)) | ||
| 1318 | 'news | ||
| 1319 | 'mail)) | ||
| 1320 | |||
| 1321 | (deffoo nnimap-request-set-mark (group actions &optional server) | ||
| 1322 | (when (nnimap-possibly-change-group group server) | ||
| 1323 | (with-current-buffer nnimap-server-buffer | ||
| 1324 | (let (action) | ||
| 1325 | (gnus-message 7 "nnimap: Setting marks in %s..." | ||
| 1326 | (nnimap-decode-group-name group)) | ||
| 1327 | (while (setq action (pop actions)) | ||
| 1328 | (let ((range (nth 0 action)) | ||
| 1329 | (what (nth 1 action)) | ||
| 1330 | (cmdmarks (nth 2 action)) | ||
| 1331 | marks) | ||
| 1332 | ;; bookmark can't be stored (not list/range | ||
| 1333 | (setq cmdmarks (delq 'bookmark cmdmarks)) | ||
| 1334 | ;; killed can't be stored (not list/range | ||
| 1335 | (setq cmdmarks (delq 'killed cmdmarks)) | ||
| 1336 | ;; unsent are for nndraft groups only | ||
| 1337 | (setq cmdmarks (delq 'unsent cmdmarks)) | ||
| 1338 | ;; cache flags are pointless on the server | ||
| 1339 | (setq cmdmarks (delq 'cache cmdmarks)) | ||
| 1340 | ;; seen flags are local to each gnus | ||
| 1341 | (setq cmdmarks (delq 'seen cmdmarks)) | ||
| 1342 | ;; recent marks can't be set | ||
| 1343 | (setq cmdmarks (delq 'recent cmdmarks)) | ||
| 1344 | (when nnimap-importantize-dormant | ||
| 1345 | ;; flag dormant articles as ticked | ||
| 1346 | (if (memq 'dormant cmdmarks) | ||
| 1347 | (setq cmdmarks (cons 'tick cmdmarks)))) | ||
| 1348 | ;; remove stuff we are forbidden to store | ||
| 1349 | (mapc (lambda (mark) | ||
| 1350 | (if (imap-message-flag-permanent-p | ||
| 1351 | (nnimap-mark-to-flag mark)) | ||
| 1352 | (setq marks (cons mark marks)))) | ||
| 1353 | cmdmarks) | ||
| 1354 | (when (and range marks) | ||
| 1355 | (cond ((eq what 'del) | ||
| 1356 | (imap-message-flags-del | ||
| 1357 | (imap-range-to-message-set range) | ||
| 1358 | (nnimap-mark-to-flag marks nil t))) | ||
| 1359 | ((eq what 'add) | ||
| 1360 | (imap-message-flags-add | ||
| 1361 | (imap-range-to-message-set range) | ||
| 1362 | (nnimap-mark-to-flag marks nil t))) | ||
| 1363 | ((eq what 'set) | ||
| 1364 | (imap-message-flags-set | ||
| 1365 | (imap-range-to-message-set range) | ||
| 1366 | (nnimap-mark-to-flag marks nil t))))))) | ||
| 1367 | (gnus-message 7 "nnimap: Setting marks in %s...done" | ||
| 1368 | (nnimap-decode-group-name group))))) | ||
| 1369 | nil) | ||
| 1370 | 283 | ||
| 1371 | (defun nnimap-split-fancy () | 284 | (defun nnimap-request-article (article &optional group server to-buffer) |
| 1372 | "Like the function `nnmail-split-fancy', but uses `nnimap-split-fancy'." | ||
| 1373 | (let ((nnmail-split-fancy nnimap-split-fancy)) | ||
| 1374 | (nnmail-split-fancy))) | ||
| 1375 | |||
| 1376 | (defun nnimap-split-to-groups (rules) | ||
| 1377 | ;; tries to match all rules in nnimap-split-rule against content of | ||
| 1378 | ;; nntp-server-buffer, returns a list of groups that matched. | ||
| 1379 | ;; Note: This function takes and returns decoded group names. | ||
| 1380 | (with-current-buffer nntp-server-buffer | 285 | (with-current-buffer nntp-server-buffer |
| 1381 | ;; Fold continuation lines. | 286 | (let ((result (nnimap-possibly-change-group group server))) |
| 1382 | (goto-char (point-min)) | 287 | (when (stringp article) |
| 1383 | (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t) | 288 | (setq article (nnimap-find-article-by-message-id group article))) |
| 1384 | (replace-match " " t t)) | 289 | (when (and result |
| 1385 | (if (functionp rules) | 290 | article) |
| 1386 | (funcall rules) | 291 | (erase-buffer) |
| 1387 | (let (to-groups regrepp) | 292 | (with-current-buffer (nnimap-buffer) |
| 1388 | (catch 'split-done | 293 | (erase-buffer) |
| 1389 | (dolist (rule rules to-groups) | 294 | (setq result |
| 1390 | (let ((group (car rule)) | 295 | (nnimap-command |
| 1391 | (regexp (cadr rule))) | 296 | (if (member "IMAP4REV1" (nnimap-capabilities nnimap-object)) |
| 297 | "UID FETCH %d BODY.PEEK[]" | ||
| 298 | "UID FETCH %d RFC822.PEEK") | ||
| 299 | article))) | ||
| 300 | (let ((buffer (nnimap-find-process-buffer (current-buffer)))) | ||
| 301 | (when (car result) | ||
| 302 | (with-current-buffer to-buffer | ||
| 303 | (insert-buffer-substring buffer) | ||
| 1392 | (goto-char (point-min)) | 304 | (goto-char (point-min)) |
| 1393 | (when (and (if (stringp regexp) | 305 | (let ((bytes (nnimap-get-length))) |
| 1394 | (progn | 306 | (delete-region (line-beginning-position) |
| 1395 | (if (not (stringp group)) | 307 | (progn (forward-line 1) (point))) |
| 1396 | (setq group (eval group)) | 308 | (goto-char (+ (point) bytes)) |
| 1397 | (setq regrepp | 309 | (delete-region (point) (point-max)) |
| 1398 | (string-match "\\\\[0-9&]" group))) | 310 | (nnheader-ms-strip-cr)) |
| 1399 | (re-search-forward regexp nil t)) | 311 | t))))))) |
| 1400 | (funcall regexp group)) | 312 | |
| 1401 | ;; Don't enter the article into the same group twice. | 313 | (defun nnimap-request-group (group &optional server dont-check) |
| 1402 | (not (assoc group to-groups))) | 314 | (with-current-buffer nntp-server-buffer |
| 1403 | (push (if regrepp | 315 | (let ((result (nnimap-possibly-change-group group server)) |
| 1404 | (nnmail-expand-newtext group) | 316 | articles) |
| 1405 | group) | 317 | (when result |
| 1406 | to-groups) | 318 | (setq articles (nnimap-get-flags "1:*")) |
| 1407 | (or nnimap-split-crosspost | 319 | (erase-buffer) |
| 1408 | (throw 'split-done to-groups)))))))))) | 320 | (insert |
| 1409 | 321 | (format | |
| 1410 | (defun nnimap-assoc-match (key alist) | 322 | "211 %d %d %d %S\n" |
| 1411 | (let (element) | 323 | (length articles) |
| 1412 | (while (and alist (not element)) | 324 | (or (caar articles) 0) |
| 1413 | (if (string-match (car (car alist)) key) | 325 | (or (caar (last articles)) 0) |
| 1414 | (setq element (car alist))) | 326 | group)) |
| 1415 | (setq alist (cdr alist))) | ||
| 1416 | element)) | ||
| 1417 | |||
| 1418 | (defun nnimap-split-find-rule (server inbox) | ||
| 1419 | (if (and (listp nnimap-split-rule) (listp (car nnimap-split-rule)) | ||
| 1420 | (list (cdar nnimap-split-rule)) (listp (cadar nnimap-split-rule))) | ||
| 1421 | ;; extended format | ||
| 1422 | (cadr (nnimap-assoc-match inbox (cdr (nnimap-assoc-match | ||
| 1423 | server nnimap-split-rule)))) | ||
| 1424 | nnimap-split-rule)) | ||
| 1425 | |||
| 1426 | (defun nnimap-split-find-inbox (server) | ||
| 1427 | (if (listp nnimap-split-inbox) | ||
| 1428 | nnimap-split-inbox | ||
| 1429 | (list nnimap-split-inbox))) | ||
| 1430 | |||
| 1431 | (defun nnimap-split-articles (&optional group server) | ||
| 1432 | ;; Note: Assumes decoded group names in nnimap-split-inbox, | ||
| 1433 | ;; nnimap-split-rule, nnimap-split-fancy, and nnmail-split-history. | ||
| 1434 | (when (nnimap-possibly-change-server server) | ||
| 1435 | (with-current-buffer nnimap-server-buffer | ||
| 1436 | (let (rule inbox removeorig | ||
| 1437 | (inboxes (nnimap-split-find-inbox server))) | ||
| 1438 | ;; iterate over inboxes | ||
| 1439 | (while (and (setq inbox (pop inboxes)) | ||
| 1440 | (nnimap-possibly-change-group | ||
| 1441 | (nnimap-encode-group-name inbox))) ;; SELECT | ||
| 1442 | ;; find split rule for this server / inbox | ||
| 1443 | (when (setq rule (nnimap-split-find-rule server inbox)) | ||
| 1444 | ;; iterate over articles | ||
| 1445 | (dolist (article (imap-search nnimap-split-predicate)) | ||
| 1446 | (when (if (if (eq nnimap-split-download-body 'default) | ||
| 1447 | nnimap-split-download-body-default | ||
| 1448 | nnimap-split-download-body) | ||
| 1449 | (and (nnimap-request-article article) | ||
| 1450 | (with-current-buffer nntp-server-buffer (mail-narrow-to-head))) | ||
| 1451 | (nnimap-request-head article)) | ||
| 1452 | ;; copy article to right group(s) | ||
| 1453 | (setq removeorig nil) | ||
| 1454 | (dolist (to-group (nnimap-split-to-groups rule)) | ||
| 1455 | (cond ((eq to-group 'junk) | ||
| 1456 | (message "IMAP split removed %s:%s:%d" server inbox | ||
| 1457 | article) | ||
| 1458 | (setq removeorig t)) | ||
| 1459 | ((imap-message-copy (number-to-string article) | ||
| 1460 | to-group nil 'nocopyuid) | ||
| 1461 | (message "IMAP split moved %s:%s:%d to %s" server | ||
| 1462 | inbox article to-group) | ||
| 1463 | (setq removeorig t) | ||
| 1464 | (when nnmail-cache-accepted-message-ids | ||
| 1465 | (with-current-buffer nntp-server-buffer | ||
| 1466 | (let (msgid) | ||
| 1467 | (and (setq msgid | ||
| 1468 | (nnmail-fetch-field "message-id")) | ||
| 1469 | (nnmail-cache-insert msgid | ||
| 1470 | (nnimap-encode-group-name to-group) | ||
| 1471 | (nnmail-fetch-field "subject")))))) | ||
| 1472 | ;; Add the group-art list to the history list. | ||
| 1473 | (push (list (cons to-group 0)) nnmail-split-history)) | ||
| 1474 | (t | ||
| 1475 | (message "IMAP split failed to move %s:%s:%d to %s" | ||
| 1476 | server inbox article to-group)))) | ||
| 1477 | (if (if (eq nnimap-split-download-body 'default) | ||
| 1478 | nnimap-split-download-body-default | ||
| 1479 | nnimap-split-download-body) | ||
| 1480 | (widen)) | ||
| 1481 | ;; remove article if it was successfully copied somewhere | ||
| 1482 | (and removeorig | ||
| 1483 | (imap-message-flags-add (format "%d" article) | ||
| 1484 | "\\Seen \\Deleted"))))) | ||
| 1485 | (when (imap-mailbox-select inbox) ;; just in case | ||
| 1486 | ;; todo: UID EXPUNGE (if available) to remove splitted articles | ||
| 1487 | (imap-mailbox-expunge) | ||
| 1488 | (imap-mailbox-close))) | ||
| 1489 | (when nnmail-cache-accepted-message-ids | ||
| 1490 | (nnmail-cache-close)) | ||
| 1491 | t)))) | 327 | t)))) |
| 1492 | 328 | ||
| 1493 | (deffoo nnimap-request-scan (&optional group server) | 329 | (defun nnimap-get-flags (spec) |
| 1494 | (nnimap-split-articles group server)) | 330 | (let ((articles nil) |
| 1495 | 331 | elems) | |
| 1496 | (deffoo nnimap-request-newgroups (date &optional server) | 332 | (with-current-buffer (nnimap-buffer) |
| 1497 | (when (nnimap-possibly-change-server server) | ||
| 1498 | (with-current-buffer nntp-server-buffer | ||
| 1499 | (gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s..." | ||
| 1500 | (if (> (length server) 0) " on " "") server) | ||
| 1501 | (erase-buffer) | 333 | (erase-buffer) |
| 1502 | (nnimap-before-find-minmax-bugworkaround) | 334 | (nnimap-wait-for-response (nnimap-send-command |
| 1503 | (dolist (pattern (nnimap-pattern-to-list-arguments | 335 | "UID FETCH %s FLAGS" spec)) |
| 1504 | nnimap-list-pattern)) | 336 | (goto-char (point-min)) |
| 1505 | (dolist (mbx (funcall nnimap-request-list-method (cdr pattern) (car pattern) nil | 337 | (while (re-search-forward "^\\* [0-9]+ FETCH (\\(.*\\))" nil t) |
| 1506 | nnimap-server-buffer)) | 338 | (setq elems (nnimap-parse-line (match-string 1))) |
| 1507 | (or (catch 'found | 339 | (push (cons (string-to-number (cadr (member "UID" elems))) |
| 1508 | (dolist (mailbox (imap-mailbox-get 'list-flags mbx | 340 | (cadr (member "FLAGS" elems))) |
| 1509 | nnimap-server-buffer)) | 341 | articles))) |
| 1510 | (if (string= (downcase mailbox) "\\noselect") | 342 | (nreverse articles))) |
| 1511 | (throw 'found t))) | ||
| 1512 | nil) | ||
| 1513 | (let* ((encoded-mbx (nnimap-encode-group-name mbx)) | ||
| 1514 | (info (nnimap-find-minmax-uid encoded-mbx 'examine))) | ||
| 1515 | (when info | ||
| 1516 | (insert (format "\"%s\" %d %d y\n" | ||
| 1517 | encoded-mbx (or (nth 2 info) 0) | ||
| 1518 | (max 1 (or (nth 1 info) 1))))))))) | ||
| 1519 | (gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s...done" | ||
| 1520 | (if (> (length server) 0) " on " "") server)) | ||
| 1521 | t)) | ||
| 1522 | 343 | ||
| 1523 | (deffoo nnimap-request-create-group (group &optional server args) | 344 | (defun nnimap-close-group (group &optional server) |
| 1524 | (when (nnimap-possibly-change-server server) | 345 | t) |
| 1525 | (let ((decoded-group (nnimap-decode-group-name group))) | ||
| 1526 | (or (imap-mailbox-status decoded-group 'uidvalidity nnimap-server-buffer) | ||
| 1527 | (imap-mailbox-create decoded-group nnimap-server-buffer) | ||
| 1528 | (nnheader-report 'nnimap "%S" | ||
| 1529 | (imap-error-text nnimap-server-buffer)))))) | ||
| 1530 | |||
| 1531 | (defun nnimap-time-substract (time1 time2) | ||
| 1532 | "Return TIME for TIME1 - TIME2." | ||
| 1533 | (let* ((ms (- (car time1) (car time2))) | ||
| 1534 | (ls (- (nth 1 time1) (nth 1 time2)))) | ||
| 1535 | (if (< ls 0) | ||
| 1536 | (list (- ms 1) (+ (expt 2 16) ls)) | ||
| 1537 | (list ms ls)))) | ||
| 1538 | |||
| 1539 | (eval-when-compile (require 'parse-time)) | ||
| 1540 | (defun nnimap-date-days-ago (daysago) | ||
| 1541 | "Return date, in format \"3-Aug-1998\", for DAYSAGO days ago." | ||
| 1542 | (require 'parse-time) | ||
| 1543 | (let* ((time (nnimap-time-substract (current-time) (days-to-time daysago))) | ||
| 1544 | (date (format-time-string | ||
| 1545 | (format "%%d-%s-%%Y" | ||
| 1546 | (capitalize (car (rassoc (nth 4 (decode-time time)) | ||
| 1547 | parse-time-months)))) | ||
| 1548 | time))) | ||
| 1549 | (if (eq ?0 (string-to-char date)) | ||
| 1550 | (substring date 1) | ||
| 1551 | date))) | ||
| 1552 | |||
| 1553 | (defun nnimap-request-expire-articles-progress () | ||
| 1554 | (gnus-message 5 "nnimap: Marking article %d for deletion..." | ||
| 1555 | imap-current-message)) | ||
| 1556 | |||
| 1557 | (defun nnimap-expiry-target (arts group server) | ||
| 1558 | (unless (eq nnmail-expiry-target 'delete) | ||
| 1559 | (with-temp-buffer | ||
| 1560 | (dolist (art arts) | ||
| 1561 | (nnimap-request-article art group server (current-buffer)) | ||
| 1562 | ;; hints for optimization in `nnimap-request-accept-article' | ||
| 1563 | (let ((nnimap-current-move-article art) | ||
| 1564 | (nnimap-current-move-group group) | ||
| 1565 | (nnimap-current-move-server server)) | ||
| 1566 | (nnmail-expiry-target-group nnmail-expiry-target group)))) | ||
| 1567 | ;; It is not clear if `nnmail-expiry-target' somehow cause the | ||
| 1568 | ;; current group to be changed or not, so we make sure here. | ||
| 1569 | (nnimap-possibly-change-group group server))) | ||
| 1570 | |||
| 1571 | ;; Notice that we don't actually delete anything, we just mark them deleted. | ||
| 1572 | (deffoo nnimap-request-expire-articles (articles group &optional server force) | ||
| 1573 | (let ((artseq (gnus-compress-sequence articles))) | ||
| 1574 | (when (and artseq (nnimap-possibly-change-group group server)) | ||
| 1575 | (with-current-buffer nnimap-server-buffer | ||
| 1576 | (let ((days (or (and nnmail-expiry-wait-function | ||
| 1577 | (funcall nnmail-expiry-wait-function group)) | ||
| 1578 | nnmail-expiry-wait))) | ||
| 1579 | (cond ((or force (eq days 'immediate)) | ||
| 1580 | (let ((oldarts (imap-search | ||
| 1581 | (concat "UID " | ||
| 1582 | (imap-range-to-message-set artseq))))) | ||
| 1583 | (when oldarts | ||
| 1584 | (nnimap-expiry-target oldarts group server) | ||
| 1585 | (when (imap-message-flags-add | ||
| 1586 | (imap-range-to-message-set | ||
| 1587 | (gnus-compress-sequence oldarts)) "\\Deleted") | ||
| 1588 | (setq articles (gnus-set-difference | ||
| 1589 | articles oldarts)))))) | ||
| 1590 | ((and nnimap-search-uids-not-since-is-evil (numberp days)) | ||
| 1591 | (let* ((all-new-articles | ||
| 1592 | (gnus-compress-sequence | ||
| 1593 | (imap-search (format "SINCE %s" | ||
| 1594 | (nnimap-date-days-ago days))))) | ||
| 1595 | (oldartseq | ||
| 1596 | (gnus-range-difference artseq all-new-articles)) | ||
| 1597 | (oldarts (gnus-uncompress-range oldartseq))) | ||
| 1598 | (when oldarts | ||
| 1599 | (nnimap-expiry-target oldarts group server) | ||
| 1600 | (when (imap-message-flags-add | ||
| 1601 | (imap-range-to-message-set oldartseq) | ||
| 1602 | "\\Deleted") | ||
| 1603 | (setq articles (gnus-set-difference | ||
| 1604 | articles oldarts)))))) | ||
| 1605 | ((numberp days) | ||
| 1606 | (let ((oldarts (imap-search | ||
| 1607 | (format nnimap-expunge-search-string | ||
| 1608 | (imap-range-to-message-set artseq) | ||
| 1609 | (nnimap-date-days-ago days)))) | ||
| 1610 | (imap-fetch-data-hook | ||
| 1611 | '(nnimap-request-expire-articles-progress))) | ||
| 1612 | (when oldarts | ||
| 1613 | (nnimap-expiry-target oldarts group server) | ||
| 1614 | (when (imap-message-flags-add | ||
| 1615 | (imap-range-to-message-set | ||
| 1616 | (gnus-compress-sequence oldarts)) "\\Deleted") | ||
| 1617 | (setq articles (gnus-set-difference | ||
| 1618 | articles oldarts))))))))))) | ||
| 1619 | ;; return articles not deleted | ||
| 1620 | articles) | ||
| 1621 | 346 | ||
| 1622 | (deffoo nnimap-request-move-article (article group server accept-form | 347 | (deffoo nnimap-request-move-article (article group server accept-form |
| 1623 | &optional last move-is-internal) | 348 | &optional last internal-move-group) |
| 1624 | (when (nnimap-possibly-change-server server) | 349 | (when (nnimap-possibly-change-group group server) |
| 1625 | (save-excursion | 350 | ;; If the move is internal (on the same server), just do it the easy |
| 1626 | (let ((buf (get-buffer-create " *nnimap move*")) | 351 | ;; way. |
| 1627 | (nnimap-current-move-article article) | 352 | (let ((message-id (message-field-value "message-id"))) |
| 1628 | (nnimap-current-move-group group) | 353 | (if internal-move-group |
| 1629 | (nnimap-current-move-server nnimap-current-server) | 354 | (let ((result |
| 1630 | result) | 355 | (with-current-buffer (nnimap-buffer) |
| 1631 | (gnus-message 10 "nnimap-request-move-article: this is an %s move" | 356 | (nnimap-command "UID COPY %d %S" |
| 1632 | (if move-is-internal | 357 | article |
| 1633 | "internal" | 358 | (utf7-encode internal-move-group t))))) |
| 1634 | "external")) | 359 | (when (car result) |
| 1635 | ;; request the article only when the move is NOT internal | 360 | (nnimap-delete-article article) |
| 1636 | (and (or move-is-internal | 361 | (cons internal-move-group |
| 1637 | (nnimap-request-article article group server)) | 362 | (nnimap-find-article-by-message-id |
| 1638 | (with-current-buffer buf | 363 | internal-move-group message-id)))) |
| 1639 | (buffer-disable-undo (current-buffer)) | 364 | (with-temp-buffer |
| 1640 | (insert-buffer-substring nntp-server-buffer) | 365 | (let ((result (eval accept-form))) |
| 1641 | (setq result (eval accept-form)) | 366 | (when result |
| 1642 | (kill-buffer buf) | 367 | (nnimap-delete-article article) |
| 1643 | result) | 368 | result))))))) |
| 1644 | (nnimap-possibly-change-group group server) | 369 | |
| 1645 | (imap-message-flags-add | 370 | (deffoo nnimap-request-expire-articles (articles group &optional server force) |
| 1646 | (imap-range-to-message-set (list article)) | 371 | (cond |
| 1647 | "\\Deleted" 'silent nnimap-server-buffer)) | 372 | ((not (nnimap-possibly-change-group group server)) |
| 1648 | result)))) | 373 | articles) |
| 374 | (force | ||
| 375 | (unless (nnimap-delete-article articles) | ||
| 376 | (message "Article marked for deletion, but not expunged.")) | ||
| 377 | nil) | ||
| 378 | (t | ||
| 379 | articles))) | ||
| 380 | |||
| 381 | (defun nnimap-find-article-by-message-id (group message-id) | ||
| 382 | (when (nnimap-possibly-change-group group nil) | ||
| 383 | (with-current-buffer (nnimap-buffer) | ||
| 384 | (let ((result | ||
| 385 | (nnimap-command "UID SEARCH HEADER Message-Id %S" message-id)) | ||
| 386 | article) | ||
| 387 | (when (car result) | ||
| 388 | ;; Select the last instance of the message in the group. | ||
| 389 | (and (setq article | ||
| 390 | (car (last (assoc "SEARCH" (cdr result))))) | ||
| 391 | (string-to-number article))))))) | ||
| 392 | |||
| 393 | (defun nnimap-delete-article (articles) | ||
| 394 | (with-current-buffer (nnimap-buffer) | ||
| 395 | (nnimap-command "UID STORE %s +FLAGS.SILENT (\\Deleted)" | ||
| 396 | (nnimap-article-ranges articles)) | ||
| 397 | (when (member "UIDPLUS" (nnimap-capabilities nnimap-object)) | ||
| 398 | (nnimap-send-command "UID EXPUNGE %s" | ||
| 399 | (nnimap-article-ranges articles)) | ||
| 400 | t))) | ||
| 401 | |||
| 402 | (deffoo nnimap-request-scan (&optional group server) | ||
| 403 | (when (and (nnimap-possibly-change-group nil server) | ||
| 404 | (equal group nnimap-inbox) | ||
| 405 | nnimap-inbox | ||
| 406 | nnimap-split-methods) | ||
| 407 | (nnimap-split-incoming-mail))) | ||
| 408 | |||
| 409 | (defun nnimap-marks-to-flags (marks) | ||
| 410 | (let (flags flag) | ||
| 411 | (dolist (mark marks) | ||
| 412 | (when (setq flag (cadr (assq mark nnimap-mark-alist))) | ||
| 413 | (push flag flags))) | ||
| 414 | flags)) | ||
| 415 | |||
| 416 | (defun nnimap-request-set-mark (group actions &optional server) | ||
| 417 | (when (nnimap-possibly-change-group group server) | ||
| 418 | (let (sequence) | ||
| 419 | (with-current-buffer (nnimap-buffer) | ||
| 420 | ;; Just send all the STORE commands without waiting for | ||
| 421 | ;; response. If they're successful, they're successful. | ||
| 422 | (dolist (action actions) | ||
| 423 | (destructuring-bind (range action marks) action | ||
| 424 | (let ((flags (nnimap-marks-to-flags marks))) | ||
| 425 | (when flags | ||
| 426 | (setq sequence (nnimap-send-command | ||
| 427 | "UID STORE %s %sFLAGS.SILENT (%s)" | ||
| 428 | (nnimap-article-ranges range) | ||
| 429 | (if (eq action 'del) | ||
| 430 | "-" | ||
| 431 | "+") | ||
| 432 | (mapconcat #'identity flags " "))))))) | ||
| 433 | ;; Wait for the last command to complete to avoid later | ||
| 434 | ;; syncronisation problems with the stream. | ||
| 435 | (nnimap-wait-for-response sequence))))) | ||
| 1649 | 436 | ||
| 1650 | (deffoo nnimap-request-accept-article (group &optional server last) | 437 | (deffoo nnimap-request-accept-article (group &optional server last) |
| 1651 | (when (nnimap-possibly-change-server server) | 438 | (when (nnimap-possibly-change-group nil server) |
| 1652 | (let (uid) | 439 | (nnmail-check-syntax) |
| 1653 | (if (setq uid | 440 | (let ((message (buffer-string)) |
| 1654 | (if (string= nnimap-current-server nnimap-current-move-server) | 441 | (message-id (message-field-value "message-id")) |
| 1655 | ;; moving article within same server, speed it up... | 442 | sequence) |
| 1656 | (and (nnimap-possibly-change-group | 443 | (with-current-buffer (nnimap-buffer) |
| 1657 | nnimap-current-move-group) | 444 | (setq sequence (nnimap-send-command |
| 1658 | (imap-message-copy (number-to-string | 445 | "APPEND %S {%d}" (utf7-encode group t) |
| 1659 | nnimap-current-move-article) | 446 | (length message))) |
| 1660 | (nnimap-decode-group-name group) | 447 | (process-send-string (get-buffer-process (current-buffer)) message) |
| 1661 | 'dontcreate nil | 448 | (process-send-string (get-buffer-process (current-buffer)) "\r\n") |
| 1662 | nnimap-server-buffer)) | 449 | (let ((result (nnimap-get-response sequence))) |
| 1663 | (with-current-buffer (current-buffer) | 450 | (when result |
| 1664 | (goto-char (point-min)) | 451 | (cons group |
| 1665 | ;; remove any 'From blabla' lines, some IMAP servers | 452 | (nnimap-find-article-by-message-id group message-id)))))))) |
| 1666 | ;; reject the entire message otherwise. | 453 | |
| 1667 | (when (looking-at "^From[^:]") | 454 | (defun nnimap-add-cr () |
| 1668 | (delete-region (point) (progn (forward-line) (point)))) | 455 | (goto-char (point-min)) |
| 1669 | ;; turn into rfc822 format (\r\n eol's) | 456 | (while (re-search-forward "\r?\n" nil t) |
| 1670 | (while (search-forward "\n" nil t) | 457 | (replace-match "\r\n" t t))) |
| 1671 | (replace-match "\r\n")) | 458 | |
| 1672 | (when nnmail-cache-accepted-message-ids | 459 | (defun nnimap-get-groups () |
| 1673 | (nnmail-cache-insert (nnmail-fetch-field "message-id") | 460 | (let ((result (nnimap-command "LIST \"\" \"*\"")) |
| 1674 | group | 461 | groups) |
| 1675 | (nnmail-fetch-field "subject")))) | 462 | (when (car result) |
| 1676 | (when (and last nnmail-cache-accepted-message-ids) | 463 | (dolist (line (cdr result)) |
| 1677 | (nnmail-cache-close)) | 464 | (when (and (equal (car line) "LIST") |
| 1678 | ;; this 'or' is for Cyrus server bug | 465 | (not (and (caadr line) |
| 1679 | (or (null (imap-current-mailbox nnimap-server-buffer)) | 466 | (string-match "noselect" (caadr line))))) |
| 1680 | (imap-mailbox-unselect nnimap-server-buffer)) | 467 | (push (car (last line)) groups))) |
| 1681 | (imap-message-append (nnimap-decode-group-name group) | 468 | (nreverse groups)))) |
| 1682 | (current-buffer) nil nil | 469 | |
| 1683 | nnimap-server-buffer))) | 470 | (defun nnimap-request-list (&optional server) |
| 1684 | (cons group (nth 1 uid)) | 471 | (nnimap-possibly-change-group nil server) |
| 1685 | (nnheader-report 'nnimap (imap-error-text nnimap-server-buffer)))))) | 472 | (with-current-buffer nntp-server-buffer |
| 1686 | 473 | (erase-buffer) | |
| 1687 | (deffoo nnimap-request-delete-group (group force &optional server) | 474 | (let ((groups |
| 1688 | (when (nnimap-possibly-change-server server) | 475 | (with-current-buffer (nnimap-buffer) |
| 1689 | (setq group (nnimap-decode-group-name group)) | 476 | (nnimap-get-groups))) |
| 1690 | (when (string= group (imap-current-mailbox nnimap-server-buffer)) | 477 | sequences responses) |
| 1691 | (imap-mailbox-unselect nnimap-server-buffer)) | 478 | (when groups |
| 1692 | (with-current-buffer nnimap-server-buffer | 479 | (with-current-buffer (nnimap-buffer) |
| 1693 | (if force | 480 | (dolist (group groups) |
| 1694 | (or (null (imap-mailbox-status group 'uidvalidity)) | 481 | (push (list (nnimap-send-command "EXAMINE %S" (utf7-encode group t)) |
| 1695 | (imap-mailbox-delete group)) | 482 | group) |
| 1696 | ;; UNSUBSCRIBE? | 483 | sequences)) |
| 484 | (nnimap-wait-for-response (caar sequences)) | ||
| 485 | (setq responses | ||
| 486 | (nnimap-get-responses (mapcar #'car sequences)))) | ||
| 487 | (dolist (response responses) | ||
| 488 | (let* ((sequence (car response)) | ||
| 489 | (response (cadr response)) | ||
| 490 | (group (cadr (assoc sequence sequences)))) | ||
| 491 | (when (and group | ||
| 492 | (equal (caar response) "OK")) | ||
| 493 | (let ((uidnext (nnimap-find-parameter "UIDNEXT" response)) | ||
| 494 | highest exists) | ||
| 495 | (dolist (elem response) | ||
| 496 | (when (equal (cadr elem) "EXISTS") | ||
| 497 | (setq exists (string-to-number (car elem))))) | ||
| 498 | (when uidnext | ||
| 499 | (setq highest (1- (string-to-number (car uidnext))))) | ||
| 500 | (cond | ||
| 501 | ((null highest) | ||
| 502 | (insert (format "%S 0 1 y\n" (utf7-decode group t)))) | ||
| 503 | ((zerop exists) | ||
| 504 | ;; Empty group. | ||
| 505 | (insert (format "%S %d %d y\n" | ||
| 506 | (utf7-decode group t) highest (1+ highest)))) | ||
| 507 | (t | ||
| 508 | ;; Return the widest possible range. | ||
| 509 | (insert (format "%S %d 1 y\n" (utf7-decode group t) | ||
| 510 | (or highest exists))))))))) | ||
| 1697 | t)))) | 511 | t)))) |
| 1698 | 512 | ||
| 1699 | (deffoo nnimap-request-rename-group (group new-name &optional server) | 513 | (defun nnimap-retrieve-group-data-early (server infos) |
| 1700 | (when (nnimap-possibly-change-server server) | 514 | (when (nnimap-possibly-change-group nil server) |
| 1701 | (imap-mailbox-rename (nnimap-decode-group-name group) | 515 | (with-current-buffer (nnimap-buffer) |
| 1702 | (nnimap-decode-group-name new-name) | 516 | ;; QRESYNC handling isn't implemented. |
| 1703 | nnimap-server-buffer))) | 517 | (let ((qresyncp (member "notQRESYNC" (nnimap-capabilities nnimap-object))) |
| 1704 | 518 | marks groups sequences) | |
| 1705 | (defun nnimap-expunge (mailbox server) | 519 | ;; Go through the infos and gather the data needed to know |
| 1706 | (when (nnimap-possibly-change-group mailbox server) | 520 | ;; what and how to request the data. |
| 1707 | (imap-mailbox-expunge nil nnimap-server-buffer))) | 521 | (dolist (info infos) |
| 1708 | 522 | (setq marks (gnus-info-marks info)) | |
| 1709 | (defun nnimap-acl-get (mailbox server) | 523 | (push (list (gnus-group-real-name (gnus-info-group info)) |
| 1710 | (when (nnimap-possibly-change-server server) | 524 | (cdr (assq 'active marks)) |
| 1711 | (and (imap-capability 'ACL nnimap-server-buffer) | 525 | (cdr (assq 'uid marks))) |
| 1712 | (imap-mailbox-acl-get (nnimap-decode-group-name mailbox) | 526 | groups)) |
| 1713 | nnimap-server-buffer)))) | 527 | ;; Then request the data. |
| 1714 | 528 | (erase-buffer) | |
| 1715 | (defun nnimap-acl-edit (mailbox method old-acls new-acls) | 529 | (dolist (elem groups) |
| 1716 | (when (nnimap-possibly-change-server (cadr method)) | 530 | (if (and qresyncp |
| 1717 | (unless (imap-capability 'ACL nnimap-server-buffer) | 531 | (nth 2 elem)) |
| 1718 | (error "Your server does not support ACL editing")) | 532 | (push |
| 1719 | (with-current-buffer nnimap-server-buffer | 533 | (list 'qresync |
| 1720 | ;; delete all removed identifiers | 534 | (nnimap-send-command "EXAMINE %S (QRESYNC (%s %s))" |
| 1721 | (mapc (lambda (old-acl) | 535 | (car elem) |
| 1722 | (unless (assoc (car old-acl) new-acls) | 536 | (car (nth 2 elem)) |
| 1723 | (or (imap-mailbox-acl-delete (car old-acl) | 537 | (cdr (nth 2 elem))) |
| 1724 | (nnimap-decode-group-name mailbox)) | 538 | nil |
| 1725 | (error "Can't delete ACL for %s" (car old-acl))))) | 539 | (car elem)) |
| 1726 | old-acls) | 540 | sequences) |
| 1727 | ;; set all changed acl's | 541 | (let ((start |
| 1728 | (mapc (lambda (new-acl) | 542 | (if (nth 1 elem) |
| 1729 | (let ((new-rights (cdr new-acl)) | 543 | ;; Fetch the last 100 flags. |
| 1730 | (old-rights (cdr (assoc (car new-acl) old-acls)))) | 544 | (max 1 (- (cdr (nth 1 elem)) 100)) |
| 1731 | (unless (and old-rights new-rights | 545 | 1))) |
| 1732 | (string= old-rights new-rights)) | 546 | (push (list (nnimap-send-command "EXAMINE %S" (car elem)) |
| 1733 | (or (imap-mailbox-acl-set (car new-acl) new-rights | 547 | (nnimap-send-command "UID FETCH %d:* FLAGS" start) |
| 1734 | (nnimap-decode-group-name mailbox)) | 548 | start |
| 1735 | (error "Can't set ACL for %s to %s" (car new-acl) | 549 | (car elem)) |
| 1736 | new-rights))))) | 550 | sequences)))) |
| 1737 | new-acls) | 551 | sequences)))) |
| 1738 | t))) | 552 | |
| 553 | (defun nnimap-finish-retrieve-group-infos (server infos sequences) | ||
| 554 | (when (and sequences | ||
| 555 | (nnimap-possibly-change-group nil server)) | ||
| 556 | (with-current-buffer (nnimap-buffer) | ||
| 557 | ;; Wait for the final data to trickle in. | ||
| 558 | (nnimap-wait-for-response (cadar sequences)) | ||
| 559 | ;; Now we should have all the data we need, no matter whether | ||
| 560 | ;; we're QRESYNCING, fetching all the flags from scratch, or | ||
| 561 | ;; just fetching the last 100 flags per group. | ||
| 562 | (nnimap-update-infos (nnimap-flags-to-marks | ||
| 563 | (nnimap-parse-flags | ||
| 564 | (nreverse sequences))) | ||
| 565 | infos)))) | ||
| 566 | |||
| 567 | (defun nnimap-update-infos (flags infos) | ||
| 568 | (dolist (info infos) | ||
| 569 | (let ((group (gnus-group-real-name (gnus-info-group info)))) | ||
| 570 | (nnimap-update-info info (cdr (assoc group flags)))))) | ||
| 571 | |||
| 572 | (defun nnimap-update-info (info marks) | ||
| 573 | (when marks | ||
| 574 | (destructuring-bind (existing flags high low uidnext start-article) marks | ||
| 575 | (let ((group (gnus-info-group info)) | ||
| 576 | (completep (and start-article | ||
| 577 | (= start-article 1)))) | ||
| 578 | ;; First set the active ranges based on high/low. | ||
| 579 | (if (or completep | ||
| 580 | (not (gnus-active group))) | ||
| 581 | (gnus-set-active group | ||
| 582 | (if high | ||
| 583 | (cons low high) | ||
| 584 | ;; No articles in this group. | ||
| 585 | (cons (1- uidnext) uidnext))) | ||
| 586 | (setcdr (gnus-active group) high)) | ||
| 587 | ;; Then update the list of read articles. | ||
| 588 | (let* ((unread | ||
| 589 | (gnus-compress-sequence | ||
| 590 | (gnus-set-difference | ||
| 591 | (gnus-set-difference | ||
| 592 | existing | ||
| 593 | (cdr (assoc "\\Seen" flags))) | ||
| 594 | (cdr (assoc "\\Flagged" flags))))) | ||
| 595 | (read (gnus-range-difference | ||
| 596 | (cons start-article high) unread))) | ||
| 597 | (when (> start-article 1) | ||
| 598 | (setq read | ||
| 599 | (gnus-range-nconcat | ||
| 600 | (gnus-sorted-range-intersection | ||
| 601 | (cons 1 start-article) | ||
| 602 | (gnus-info-read info)) | ||
| 603 | read))) | ||
| 604 | (gnus-info-set-read info read) | ||
| 605 | ;; Update the marks. | ||
| 606 | (setq marks (gnus-info-marks info)) | ||
| 607 | ;; Note the active level for the next run-through. | ||
| 608 | (let ((active (assq 'active marks))) | ||
| 609 | (if active | ||
| 610 | (setcdr active (gnus-active group)) | ||
| 611 | (push (cons 'active (gnus-active group)) marks))) | ||
| 612 | (dolist (type (cdr nnimap-mark-alist)) | ||
| 613 | (let ((old-marks (assoc (car type) marks)) | ||
| 614 | (new-marks (gnus-compress-sequence | ||
| 615 | (cdr (assoc (cadr type) flags))))) | ||
| 616 | (setq marks (delq old-marks marks)) | ||
| 617 | (pop old-marks) | ||
| 618 | (when (and old-marks | ||
| 619 | (> start-article 1)) | ||
| 620 | (setq old-marks (gnus-range-difference | ||
| 621 | (cons start-article high) | ||
| 622 | old-marks)) | ||
| 623 | (setq new-marks (gnus-range-nconcat old-marks new-marks))) | ||
| 624 | (when new-marks | ||
| 625 | (push (cons (car type) new-marks) marks))) | ||
| 626 | (gnus-info-set-marks info marks))))))) | ||
| 627 | |||
| 628 | (defun nnimap-flags-to-marks (groups) | ||
| 629 | (let (data group totalp uidnext articles start-article mark) | ||
| 630 | (dolist (elem groups) | ||
| 631 | (setq group (car elem) | ||
| 632 | uidnext (cadr elem) | ||
| 633 | start-article (caddr elem) | ||
| 634 | articles (cdddr elem)) | ||
| 635 | (let ((high (caar articles)) | ||
| 636 | marks low existing) | ||
| 637 | (dolist (article articles) | ||
| 638 | (setq low (car article)) | ||
| 639 | (push (car article) existing) | ||
| 640 | (dolist (flag (cdr article)) | ||
| 641 | (setq mark (assoc flag marks)) | ||
| 642 | (if (not mark) | ||
| 643 | (push (list flag (car article)) marks) | ||
| 644 | (setcdr mark (cons (car article) (cdr mark))))) | ||
| 645 | (push (list group existing marks high low uidnext start-article) | ||
| 646 | data)))) | ||
| 647 | data)) | ||
| 648 | |||
| 649 | (defun nnimap-parse-flags (sequences) | ||
| 650 | (goto-char (point-min)) | ||
| 651 | (let (start end articles groups uidnext elems) | ||
| 652 | (dolist (elem sequences) | ||
| 653 | (destructuring-bind (group-sequence flag-sequence totalp group) elem | ||
| 654 | ;; The EXAMINE was successful. | ||
| 655 | (when (and (search-forward (format "\n%d OK " group-sequence) nil t) | ||
| 656 | (progn | ||
| 657 | (forward-line 1) | ||
| 658 | (setq start (point)) | ||
| 659 | (if (re-search-backward "UIDNEXT \\([0-9]+\\)" | ||
| 660 | (or end (point-min)) t) | ||
| 661 | (setq uidnext (string-to-number (match-string 1))) | ||
| 662 | (setq uidnext nil)) | ||
| 663 | (goto-char start)) | ||
| 664 | ;; The UID FETCH FLAGS was successful. | ||
| 665 | (search-forward (format "\n%d OK " flag-sequence) nil t)) | ||
| 666 | (setq end (point)) | ||
| 667 | (goto-char start) | ||
| 668 | (while (re-search-forward "^\\* [0-9]+ FETCH (\\(.*\\))" end t) | ||
| 669 | (setq elems (nnimap-parse-line (match-string 1))) | ||
| 670 | (push (cons (string-to-number (cadr (member "UID" elems))) | ||
| 671 | (cadr (member "FLAGS" elems))) | ||
| 672 | articles)) | ||
| 673 | (push (nconc (list group uidnext totalp) articles) groups) | ||
| 674 | (setq articles nil)))) | ||
| 675 | groups)) | ||
| 676 | |||
| 677 | (defun nnimap-find-process-buffer (buffer) | ||
| 678 | (cadr (assoc buffer nnimap-connection-alist))) | ||
| 679 | |||
| 680 | (defun nnimap-request-post (&optional server) | ||
| 681 | (setq nnimap-status-string "Read-only server") | ||
| 682 | nil) | ||
| 1739 | 683 | ||
| 1740 | 684 | (defun nnimap-possibly-change-group (group server) | |
| 1741 | ;;; Internal functions | 685 | (let ((open-result t)) |
| 1742 | 686 | (when (and server | |
| 1743 | ;; | 687 | (not (nnimap-server-opened server))) |
| 1744 | ;; This is confusing. | 688 | (setq open-result (nnimap-open-server server))) |
| 1745 | ;; | 689 | (cond |
| 1746 | ;; mark => read, tick, draft, reply etc | 690 | ((not open-result) |
| 1747 | ;; flag => "\\Seen", "\\Flagged", "\\Draft", "gnus-expire" etc | 691 | nil) |
| 1748 | ;; predicate => "SEEN", "FLAGGED", "DRAFT", "KEYWORD gnus-expire" etc | 692 | ((not group) |
| 1749 | ;; | 693 | t) |
| 1750 | ;; Mark should not really contain 'read since it's not a "mark" in the Gnus | 694 | (t |
| 1751 | ;; world, but we cheat. Mark == gnus-article-mark-lists + '(read . read). | 695 | (with-current-buffer (nnimap-buffer) |
| 1752 | ;; | 696 | (if (equal group (nnimap-group nnimap-object)) |
| 1753 | 697 | t | |
| 1754 | (defconst nnimap-mark-to-predicate-alist | 698 | (let ((result (nnimap-command "SELECT %S" (utf7-encode group t)))) |
| 1755 | (mapcar | 699 | (when (car result) |
| 1756 | (lambda (pair) ; cdr is the mark | 700 | (setf (nnimap-group nnimap-object) group) |
| 1757 | (or (assoc (cdr pair) | 701 | result)))))))) |
| 1758 | '((read . "SEEN") | 702 | |
| 1759 | (tick . "FLAGGED") | 703 | (defun nnimap-find-connection (buffer) |
| 1760 | (draft . "DRAFT") | 704 | "Find the connection delivering to BUFFER." |
| 1761 | (recent . "RECENT") | 705 | (let ((entry (assoc buffer nnimap-connection-alist))) |
| 1762 | (reply . "ANSWERED"))) | 706 | (when entry |
| 1763 | (cons (cdr pair) | 707 | (if (and (buffer-name (cadr entry)) |
| 1764 | (format "KEYWORD gnus-%s" (symbol-name (cdr pair)))))) | 708 | (get-buffer-process (cadr entry)) |
| 1765 | (cons '(read . read) gnus-article-mark-lists))) | 709 | (memq (process-status (get-buffer-process (cadr entry))) |
| 1766 | 710 | '(open run))) | |
| 1767 | (defun nnimap-mark-to-predicate (pred) | 711 | (get-buffer-process (cadr entry)) |
| 1768 | "Convert a Gnus mark (a symbol such as read, tick, expire) to a IMAP predicate. | 712 | (setq nnimap-connection-alist (delq entry nnimap-connection-alist)) |
| 1769 | This is a string such as \"SEEN\", \"FLAGGED\", \"KEYWORD gnus-expire\", | 713 | nil)))) |
| 1770 | to be used within a IMAP SEARCH query." | 714 | |
| 1771 | (cdr (assq pred nnimap-mark-to-predicate-alist))) | 715 | (defvar nnimap-sequence 0) |
| 1772 | 716 | ||
| 1773 | (defconst nnimap-mark-to-flag-alist | 717 | (defun nnimap-send-command (&rest args) |
| 1774 | (mapcar | 718 | (process-send-string |
| 1775 | (lambda (pair) | 719 | (get-buffer-process (current-buffer)) |
| 1776 | (or (assoc (cdr pair) | 720 | (nnimap-log-command |
| 1777 | '((read . "\\Seen") | 721 | (format "%d %s\r\n" |
| 1778 | (tick . "\\Flagged") | 722 | (incf nnimap-sequence) |
| 1779 | (draft . "\\Draft") | 723 | (apply #'format args)))) |
| 1780 | (recent . "\\Recent") | 724 | nnimap-sequence) |
| 1781 | (reply . "\\Answered"))) | 725 | |
| 1782 | (cons (cdr pair) | 726 | (defun nnimap-log-command (command) |
| 1783 | (format "gnus-%s" (symbol-name (cdr pair)))))) | 727 | (with-current-buffer (get-buffer-create "*imap log*") |
| 1784 | (cons '(read . read) gnus-article-mark-lists))) | 728 | (goto-char (point-max)) |
| 1785 | 729 | (insert (format-time-string "%H:%M:%S") " " command)) | |
| 1786 | (defun nnimap-mark-to-flag-1 (preds) | 730 | command) |
| 1787 | (if (and (not (null preds)) (listp preds)) | 731 | |
| 1788 | (cons (nnimap-mark-to-flag (car preds)) | 732 | (defun nnimap-command (&rest args) |
| 1789 | (nnimap-mark-to-flag (cdr preds))) | 733 | (erase-buffer) |
| 1790 | (cdr (assoc preds nnimap-mark-to-flag-alist)))) | 734 | (let* ((sequence (apply #'nnimap-send-command args)) |
| 1791 | 735 | (response (nnimap-get-response sequence))) | |
| 1792 | (defun nnimap-mark-to-flag (preds &optional always-list make-string) | 736 | (if (equal (caar response) "OK") |
| 1793 | "Convert a Gnus mark (a symbol such as read, tick, expire) to a IMAP flag. | 737 | (cons t response) |
| 1794 | This is a string such as \"\\Seen\", \"\\Flagged\", \"gnus-expire\", to | 738 | (nnheader-report 'nnimap "%s" |
| 1795 | be used in a STORE FLAGS command." | 739 | (mapconcat #'identity (car response) " ")) |
| 1796 | (let ((result (nnimap-mark-to-flag-1 preds))) | 740 | nil))) |
| 1797 | (setq result (if (and (or make-string always-list) | 741 | |
| 1798 | (not (listp result))) | 742 | (defun nnimap-get-response (sequence) |
| 1799 | (list result) | 743 | (nnimap-wait-for-response sequence) |
| 1800 | result)) | 744 | (nnimap-parse-response)) |
| 1801 | (if make-string | 745 | |
| 1802 | (mapconcat (lambda (flag) | 746 | (defun nnimap-wait-for-response (sequence &optional messagep) |
| 1803 | (if (listp flag) | 747 | (goto-char (point-max)) |
| 1804 | (mapconcat 'identity flag " ") | 748 | (while (or (bobp) |
| 1805 | flag)) | 749 | (progn |
| 1806 | result " ") | 750 | (forward-line -1) |
| 1807 | result))) | 751 | (not (looking-at (format "^%d .*\n" sequence))))) |
| 1808 | 752 | (when messagep | |
| 1809 | (defun nnimap-mark-permanent-p (mark &optional group) | 753 | (message "Read %dKB" (/ (buffer-size) 1000))) |
| 1810 | "Return t if MARK can be permanently (between IMAP sessions) saved on articles, in GROUP." | 754 | (nnheader-accept-process-output (get-buffer-process (current-buffer))) |
| 1811 | (imap-message-flag-permanent-p (nnimap-mark-to-flag mark))) | 755 | (goto-char (point-max)))) |
| 756 | |||
| 757 | (defun nnimap-parse-response () | ||
| 758 | (let ((lines (split-string (nnimap-last-response-string) "\r\n" t)) | ||
| 759 | result) | ||
| 760 | (dolist (line lines) | ||
| 761 | (push (cdr (nnimap-parse-line line)) result)) | ||
| 762 | ;; Return the OK/error code first, and then all the "continuation | ||
| 763 | ;; lines" afterwards. | ||
| 764 | (cons (pop result) | ||
| 765 | (nreverse result)))) | ||
| 766 | |||
| 767 | ;; Parse an IMAP response line lightly. They look like | ||
| 768 | ;; "* OK [UIDVALIDITY 1164213559] UIDs valid", typically, so parse | ||
| 769 | ;; the lines into a list of strings and lists of string. | ||
| 770 | (defun nnimap-parse-line (line) | ||
| 771 | (let (char result) | ||
| 772 | (with-temp-buffer | ||
| 773 | (insert line) | ||
| 774 | (goto-char (point-min)) | ||
| 775 | (while (not (eobp)) | ||
| 776 | (if (eql (setq char (following-char)) ? ) | ||
| 777 | (forward-char 1) | ||
| 778 | (push | ||
| 779 | (cond | ||
| 780 | ((eql char ?\[) | ||
| 781 | (split-string (buffer-substring | ||
| 782 | (1+ (point)) (1- (search-forward "]"))))) | ||
| 783 | ((eql char ?\() | ||
| 784 | (split-string (buffer-substring | ||
| 785 | (1+ (point)) (1- (search-forward ")"))))) | ||
| 786 | ((eql char ?\") | ||
| 787 | (forward-char 1) | ||
| 788 | (buffer-substring (point) (1- (search-forward "\"")))) | ||
| 789 | (t | ||
| 790 | (buffer-substring (point) (if (search-forward " " nil t) | ||
| 791 | (1- (point)) | ||
| 792 | (goto-char (point-max)))))) | ||
| 793 | result))) | ||
| 794 | (nreverse result)))) | ||
| 795 | |||
| 796 | (defun nnimap-last-response-string () | ||
| 797 | (save-excursion | ||
| 798 | (forward-line 1) | ||
| 799 | (let ((end (point))) | ||
| 800 | (forward-line -1) | ||
| 801 | (when (not (bobp)) | ||
| 802 | (forward-line -1) | ||
| 803 | (while (and (not (bobp)) | ||
| 804 | (eql (following-char) ?*)) | ||
| 805 | (forward-line -1)) | ||
| 806 | (unless (eql (following-char) ?*) | ||
| 807 | (forward-line 1))) | ||
| 808 | (buffer-substring (point) end)))) | ||
| 809 | |||
| 810 | (defun nnimap-get-responses (sequences) | ||
| 811 | (let (responses) | ||
| 812 | (dolist (sequence sequences) | ||
| 813 | (goto-char (point-min)) | ||
| 814 | (when (re-search-forward (format "^%d " sequence) nil t) | ||
| 815 | (push (list sequence (nnimap-parse-response)) | ||
| 816 | responses))) | ||
| 817 | responses)) | ||
| 818 | |||
| 819 | (defvar nnimap-incoming-split-list nil) | ||
| 820 | |||
| 821 | (defun nnimap-fetch-inbox (articles) | ||
| 822 | (erase-buffer) | ||
| 823 | (nnimap-wait-for-response | ||
| 824 | (nnimap-send-command | ||
| 825 | "UID FETCH %s %s" | ||
| 826 | (nnimap-article-ranges articles) | ||
| 827 | (format "(UID %s%s)" | ||
| 828 | (format | ||
| 829 | (if (member "IMAP4REV1" | ||
| 830 | (nnimap-capabilities nnimap-object)) | ||
| 831 | "BODY.PEEK[HEADER] BODY.PEEK" | ||
| 832 | "RFC822.PEEK")) | ||
| 833 | (if nnimap-split-download-body-default | ||
| 834 | "" | ||
| 835 | "[1]"))) | ||
| 836 | t)) | ||
| 837 | |||
| 838 | (defun nnimap-split-incoming-mail () | ||
| 839 | (with-current-buffer (nnimap-buffer) | ||
| 840 | (let ((nnimap-incoming-split-list nil) | ||
| 841 | (nnmail-split-methods nnimap-split-methods) | ||
| 842 | (nnmail-inhibit-default-split-group t) | ||
| 843 | (groups (nnimap-get-groups)) | ||
| 844 | new-articles) | ||
| 845 | (erase-buffer) | ||
| 846 | (nnimap-command "SELECT %S" nnimap-inbox) | ||
| 847 | (setq new-articles (nnimap-new-articles (nnimap-get-flags "1:*"))) | ||
| 848 | (when new-articles | ||
| 849 | (nnimap-fetch-inbox new-articles) | ||
| 850 | (nnimap-transform-split-mail) | ||
| 851 | (nnheader-ms-strip-cr) | ||
| 852 | (nnmail-cache-open) | ||
| 853 | (nnmail-split-incoming (current-buffer) | ||
| 854 | #'nnimap-save-mail-spec | ||
| 855 | nil nil | ||
| 856 | #'nnimap-dummy-active-number) | ||
| 857 | (when nnimap-incoming-split-list | ||
| 858 | (let ((specs (nnimap-make-split-specs nnimap-incoming-split-list)) | ||
| 859 | sequences) | ||
| 860 | ;; Create any groups that doesn't already exist on the | ||
| 861 | ;; server first. | ||
| 862 | (dolist (spec specs) | ||
| 863 | (unless (member (car spec) groups) | ||
| 864 | (nnimap-command "CREATE %S" (utf7-encode (car spec) t)))) | ||
| 865 | ;; Then copy over all the messages. | ||
| 866 | (erase-buffer) | ||
| 867 | (dolist (spec specs) | ||
| 868 | (let ((group (car spec)) | ||
| 869 | (ranges (cdr spec))) | ||
| 870 | (push (list (nnimap-send-command "UID COPY %s %S" | ||
| 871 | (nnimap-article-ranges ranges) | ||
| 872 | (utf7-encode group t)) | ||
| 873 | ranges) | ||
| 874 | sequences))) | ||
| 875 | ;; Wait for the last COPY response... | ||
| 876 | (when sequences | ||
| 877 | (nnimap-wait-for-response (caar sequences)) | ||
| 878 | ;; And then mark the successful copy actions as deleted, | ||
| 879 | ;; and possibly expunge them. | ||
| 880 | (nnimap-mark-and-expunge-incoming | ||
| 881 | (nnimap-parse-copied-articles sequences))))))))) | ||
| 882 | |||
| 883 | (defun nnimap-mark-and-expunge-incoming (range) | ||
| 884 | (when range | ||
| 885 | (setq range (nnimap-article-ranges range)) | ||
| 886 | (nnimap-send-command | ||
| 887 | "UID STORE %s +FLAGS.SILENT (\\Deleted)" range) | ||
| 888 | (cond | ||
| 889 | ;; If the server supports it, we now delete the message we have | ||
| 890 | ;; just copied over. | ||
| 891 | ((member "UIDPLUS" (nnimap-capabilities nnimap-object)) | ||
| 892 | (nnimap-send-command "UID EXPUNGE %s" range)) | ||
| 893 | ;; If it doesn't support UID EXPUNGE, then we only expunge if the | ||
| 894 | ;; user has configured it. | ||
| 895 | (nnimap-expunge-inbox | ||
| 896 | (nnimap-send-command "EXPUNGE"))))) | ||
| 897 | |||
| 898 | (defun nnimap-parse-copied-articles (sequences) | ||
| 899 | (let (sequence copied range) | ||
| 900 | (goto-char (point-min)) | ||
| 901 | (while (re-search-forward "^\\([0-9]+\\) OK " nil t) | ||
| 902 | (setq sequence (string-to-number (match-string 1))) | ||
| 903 | (when (setq range (cadr (assq sequence sequences))) | ||
| 904 | (push (gnus-uncompress-range range) copied))) | ||
| 905 | (gnus-compress-sequence (sort (apply #'nconc copied) #'<)))) | ||
| 906 | |||
| 907 | (defun nnimap-new-articles (flags) | ||
| 908 | (let (new) | ||
| 909 | (dolist (elem flags) | ||
| 910 | (when (or (null (cdr elem)) | ||
| 911 | (and (not (member "\\Deleted" (cdr elem))) | ||
| 912 | (not (member "\\Seen" (cdr elem))))) | ||
| 913 | (push (car elem) new))) | ||
| 914 | (gnus-compress-sequence (nreverse new)))) | ||
| 915 | |||
| 916 | (defun nnimap-make-split-specs (list) | ||
| 917 | (let ((specs nil) | ||
| 918 | entry) | ||
| 919 | (dolist (elem list) | ||
| 920 | (destructuring-bind (article spec) elem | ||
| 921 | (dolist (group (delete nil (mapcar #'car spec))) | ||
| 922 | (unless (setq entry (assoc group specs)) | ||
| 923 | (push (setq entry (list group)) specs)) | ||
| 924 | (setcdr entry (cons article (cdr entry)))))) | ||
| 925 | (dolist (entry specs) | ||
| 926 | (setcdr entry (gnus-compress-sequence (sort (cdr entry) #'<)))) | ||
| 927 | specs)) | ||
| 928 | |||
| 929 | (defun nnimap-transform-split-mail () | ||
| 930 | (goto-char (point-min)) | ||
| 931 | (let (article bytes) | ||
| 932 | (block nil | ||
| 933 | (while (not (eobp)) | ||
| 934 | (while (not (looking-at "^\\* [0-9]+ FETCH.*UID \\([0-9]+\\)")) | ||
| 935 | (delete-region (point) (progn (forward-line 1) (point))) | ||
| 936 | (when (eobp) | ||
| 937 | (return))) | ||
| 938 | (setq article (match-string 1) | ||
| 939 | bytes (nnimap-get-length)) | ||
| 940 | (delete-region (line-beginning-position) (line-end-position)) | ||
| 941 | ;; Insert MMDF separator, and a way to remember what this | ||
| 942 | ;; article UID is. | ||
| 943 | (insert (format "\^A\^A\^A\^A\n\nX-nnimap-article: %s" article)) | ||
| 944 | (forward-char (1+ bytes)) | ||
| 945 | (setq bytes (nnimap-get-length)) | ||
| 946 | (delete-region (line-beginning-position) (line-end-position)) | ||
| 947 | (forward-char (1+ bytes)) | ||
| 948 | (delete-region (line-beginning-position) (line-end-position)))))) | ||
| 949 | |||
| 950 | (defun nnimap-dummy-active-number (group &optional server) | ||
| 951 | 1) | ||
| 952 | |||
| 953 | (defun nnimap-save-mail-spec (group-art &optional server full-nov) | ||
| 954 | (let (article) | ||
| 955 | (goto-char (point-min)) | ||
| 956 | (if (not (re-search-forward "X-nnimap-article: \\([0-9]+\\)" nil t)) | ||
| 957 | (error "Invalid nnimap mail") | ||
| 958 | (setq article (string-to-number (match-string 1)))) | ||
| 959 | (push (list article group-art) | ||
| 960 | nnimap-incoming-split-list))) | ||
| 1812 | 961 | ||
| 1813 | (provide 'nnimap) | 962 | (provide 'nnimap) |
| 1814 | 963 | ||
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index 6096c6fb374..27610e7aba2 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el | |||
| @@ -744,8 +744,7 @@ and show thread that contains this article." | |||
| 744 | nnir-artlist | 744 | nnir-artlist |
| 745 | ;; Cache miss. | 745 | ;; Cache miss. |
| 746 | (setq nnir-artlist (nnir-run-query group))) | 746 | (setq nnir-artlist (nnir-run-query group))) |
| 747 | (save-excursion | 747 | (with-current-buffer nntp-server-buffer |
| 748 | (set-buffer nntp-server-buffer) | ||
| 749 | (if (zerop (length nnir-artlist)) | 748 | (if (zerop (length nnir-artlist)) |
| 750 | (progn | 749 | (progn |
| 751 | (setq nnir-current-query nil | 750 | (setq nnir-current-query nil |
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index b7d834ecd8c..3e6cee82521 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el | |||
| @@ -614,6 +614,7 @@ using different case (i.e. mailing-list@domain vs Mailing-List@Domain)." | |||
| 614 | 614 | ||
| 615 | (defvar nnmail-split-tracing nil) | 615 | (defvar nnmail-split-tracing nil) |
| 616 | (defvar nnmail-split-trace nil) | 616 | (defvar nnmail-split-trace nil) |
| 617 | (defvar nnmail-inhibit-default-split-group nil) | ||
| 617 | 618 | ||
| 618 | 619 | ||
| 619 | 620 | ||
| @@ -674,8 +675,7 @@ using different case (i.e. mailing-list@domain vs Mailing-List@Domain)." | |||
| 674 | "Returns an assoc of group names and active ranges. | 675 | "Returns an assoc of group names and active ranges. |
| 675 | nn*-request-list should have been called before calling this function." | 676 | nn*-request-list should have been called before calling this function." |
| 676 | ;; Go through all groups from the active list. | 677 | ;; Go through all groups from the active list. |
| 677 | (save-excursion | 678 | (with-current-buffer nntp-server-buffer |
| 678 | (set-buffer nntp-server-buffer) | ||
| 679 | (nnmail-parse-active))) | 679 | (nnmail-parse-active))) |
| 680 | 680 | ||
| 681 | (defun nnmail-parse-active () | 681 | (defun nnmail-parse-active () |
| @@ -1058,7 +1058,9 @@ If SOURCE is a directory spec, try to return the group name component." | |||
| 1058 | (defun nnmail-split-incoming (incoming func &optional exit-func | 1058 | (defun nnmail-split-incoming (incoming func &optional exit-func |
| 1059 | group artnum-func) | 1059 | group artnum-func) |
| 1060 | "Go through the entire INCOMING file and pick out each individual mail. | 1060 | "Go through the entire INCOMING file and pick out each individual mail. |
| 1061 | FUNC will be called with the buffer narrowed to each mail." | 1061 | FUNC will be called with the buffer narrowed to each mail. |
| 1062 | INCOMING can also be a buffer object. In that case, the mail | ||
| 1063 | will be copied over from that buffer." | ||
| 1062 | (let ( ;; If this is a group-specific split, we bind the split | 1064 | (let ( ;; If this is a group-specific split, we bind the split |
| 1063 | ;; methods to just this group. | 1065 | ;; methods to just this group. |
| 1064 | (nnmail-split-methods (if (and group | 1066 | (nnmail-split-methods (if (and group |
| @@ -1066,12 +1068,13 @@ FUNC will be called with the buffer narrowed to each mail." | |||
| 1066 | (list (list group "")) | 1068 | (list (list group "")) |
| 1067 | nnmail-split-methods)) | 1069 | nnmail-split-methods)) |
| 1068 | (nnmail-group-names-not-encoded-p t)) | 1070 | (nnmail-group-names-not-encoded-p t)) |
| 1069 | (save-excursion | 1071 | ;; Insert the incoming file. |
| 1070 | ;; Insert the incoming file. | 1072 | (with-current-buffer (get-buffer-create nnmail-article-buffer) |
| 1071 | (set-buffer (get-buffer-create nnmail-article-buffer)) | ||
| 1072 | (erase-buffer) | 1073 | (erase-buffer) |
| 1073 | (let ((coding-system-for-read nnmail-incoming-coding-system)) | 1074 | (if (bufferp incoming) |
| 1074 | (mm-insert-file-contents incoming)) | 1075 | (insert-buffer-substring incoming) |
| 1076 | (let ((coding-system-for-read nnmail-incoming-coding-system)) | ||
| 1077 | (mm-insert-file-contents incoming))) | ||
| 1075 | (prog1 | 1078 | (prog1 |
| 1076 | (if (zerop (buffer-size)) | 1079 | (if (zerop (buffer-size)) |
| 1077 | 0 | 1080 | 0 |
| @@ -1100,15 +1103,15 @@ FUNC will be called with the group name to determine the article number." | |||
| 1100 | (obuf (current-buffer)) | 1103 | (obuf (current-buffer)) |
| 1101 | group-art method grp) | 1104 | group-art method grp) |
| 1102 | (if (and (sequencep methods) | 1105 | (if (and (sequencep methods) |
| 1103 | (= (length methods) 1)) | 1106 | (= (length methods) 1) |
| 1107 | (not nnmail-inhibit-default-split-group)) | ||
| 1104 | ;; If there is only just one group to put everything in, we | 1108 | ;; If there is only just one group to put everything in, we |
| 1105 | ;; just return a list with just this one method in. | 1109 | ;; just return a list with just this one method in. |
| 1106 | (setq group-art | 1110 | (setq group-art |
| 1107 | (list (cons (caar methods) (funcall func (caar methods))))) | 1111 | (list (cons (caar methods) (funcall func (caar methods))))) |
| 1108 | ;; We do actual comparison. | 1112 | ;; We do actual comparison. |
| 1109 | (save-excursion | 1113 | ;; Copy the article into the work buffer. |
| 1110 | ;; Copy the article into the work buffer. | 1114 | (with-current-buffer nntp-server-buffer |
| 1111 | (set-buffer nntp-server-buffer) | ||
| 1112 | (erase-buffer) | 1115 | (erase-buffer) |
| 1113 | (insert-buffer-substring obuf) | 1116 | (insert-buffer-substring obuf) |
| 1114 | ;; Narrow to headers. | 1117 | ;; Narrow to headers. |
| @@ -1149,7 +1152,8 @@ FUNC will be called with the group name to determine the article number." | |||
| 1149 | ;; just call this function here and use the | 1152 | ;; just call this function here and use the |
| 1150 | ;; result. | 1153 | ;; result. |
| 1151 | (or (funcall nnmail-split-methods) | 1154 | (or (funcall nnmail-split-methods) |
| 1152 | '("bogus")) | 1155 | (and (not nnmail-inhibit-default-split-group) |
| 1156 | '("bogus"))) | ||
| 1153 | (error | 1157 | (error |
| 1154 | (nnheader-message | 1158 | (nnheader-message |
| 1155 | 5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info) | 1159 | 5 "Error in `nnmail-split-methods'; using `bogus' mail group: %S" error-info) |
| @@ -1194,12 +1198,14 @@ FUNC will be called with the group name to determine the article number." | |||
| 1194 | group-art)) | 1198 | group-art)) |
| 1195 | ;; This is the final group, which is used as a | 1199 | ;; This is the final group, which is used as a |
| 1196 | ;; catch-all. | 1200 | ;; catch-all. |
| 1197 | (unless group-art | 1201 | (when (and (not group-art) |
| 1202 | (not nnmail-inhibit-default-split-group)) | ||
| 1198 | (setq group-art | 1203 | (setq group-art |
| 1199 | (list (cons (car method) | 1204 | (list (cons (car method) |
| 1200 | (funcall func (car method)))))))) | 1205 | (funcall func (car method)))))))) |
| 1201 | ;; Fall back on "bogus" if all else fails. | 1206 | ;; Fall back on "bogus" if all else fails. |
| 1202 | (unless group-art | 1207 | (when (and (not group-art) |
| 1208 | (not nnmail-inhibit-default-split-group)) | ||
| 1203 | (setq group-art (list (cons "bogus" (funcall func "bogus")))))) | 1209 | (setq group-art (list (cons "bogus" (funcall func "bogus")))))) |
| 1204 | ;; Produce a trace if non-empty. | 1210 | ;; Produce a trace if non-empty. |
| 1205 | (when (and trace nnmail-split-trace) | 1211 | (when (and trace nnmail-split-trace) |
| @@ -1572,10 +1578,9 @@ See the documentation for the variable `nnmail-split-fancy' for details." | |||
| 1572 | (and nnmail-cache-buffer | 1578 | (and nnmail-cache-buffer |
| 1573 | (buffer-name nnmail-cache-buffer))) | 1579 | (buffer-name nnmail-cache-buffer))) |
| 1574 | () ; The buffer is open. | 1580 | () ; The buffer is open. |
| 1575 | (save-excursion | 1581 | (with-current-buffer |
| 1576 | (set-buffer | ||
| 1577 | (setq nnmail-cache-buffer | 1582 | (setq nnmail-cache-buffer |
| 1578 | (get-buffer-create " *nnmail message-id cache*"))) | 1583 | (get-buffer-create " *nnmail message-id cache*")) |
| 1579 | (gnus-add-buffer) | 1584 | (gnus-add-buffer) |
| 1580 | (when (file-exists-p nnmail-message-id-cache-file) | 1585 | (when (file-exists-p nnmail-message-id-cache-file) |
| 1581 | (nnheader-insert-file-contents nnmail-message-id-cache-file)) | 1586 | (nnheader-insert-file-contents nnmail-message-id-cache-file)) |
| @@ -1587,8 +1592,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." | |||
| 1587 | nnmail-treat-duplicates | 1592 | nnmail-treat-duplicates |
| 1588 | (buffer-name nnmail-cache-buffer) | 1593 | (buffer-name nnmail-cache-buffer) |
| 1589 | (buffer-modified-p nnmail-cache-buffer)) | 1594 | (buffer-modified-p nnmail-cache-buffer)) |
| 1590 | (save-excursion | 1595 | (with-current-buffer nnmail-cache-buffer |
| 1591 | (set-buffer nnmail-cache-buffer) | ||
| 1592 | ;; Weed out the excess number of Message-IDs. | 1596 | ;; Weed out the excess number of Message-IDs. |
| 1593 | (goto-char (point-max)) | 1597 | (goto-char (point-max)) |
| 1594 | (when (search-backward "\n" nil t nnmail-message-id-cache-length) | 1598 | (when (search-backward "\n" nil t nnmail-message-id-cache-length) |
| @@ -1623,8 +1627,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." | |||
| 1623 | ;; pass the first (of possibly >1) group which matches. -Josh | 1627 | ;; pass the first (of possibly >1) group which matches. -Josh |
| 1624 | (unless (gnus-buffer-live-p nnmail-cache-buffer) | 1628 | (unless (gnus-buffer-live-p nnmail-cache-buffer) |
| 1625 | (nnmail-cache-open)) | 1629 | (nnmail-cache-open)) |
| 1626 | (save-excursion | 1630 | (with-current-buffer nnmail-cache-buffer |
| 1627 | (set-buffer nnmail-cache-buffer) | ||
| 1628 | (goto-char (point-max)) | 1631 | (goto-char (point-max)) |
| 1629 | (if (and grp (not (string= "" grp)) | 1632 | (if (and grp (not (string= "" grp)) |
| 1630 | (gnus-methods-equal-p gnus-command-method | 1633 | (gnus-methods-equal-p gnus-command-method |
| @@ -1657,8 +1660,7 @@ See the documentation for the variable `nnmail-split-fancy' for details." | |||
| 1657 | ;; cache. | 1660 | ;; cache. |
| 1658 | (defun nnmail-cache-fetch-group (id) | 1661 | (defun nnmail-cache-fetch-group (id) |
| 1659 | (when (and nnmail-treat-duplicates nnmail-cache-buffer) | 1662 | (when (and nnmail-treat-duplicates nnmail-cache-buffer) |
| 1660 | (save-excursion | 1663 | (with-current-buffer nnmail-cache-buffer |
| 1661 | (set-buffer nnmail-cache-buffer) | ||
| 1662 | (goto-char (point-max)) | 1664 | (goto-char (point-max)) |
| 1663 | (when (search-backward id nil t) | 1665 | (when (search-backward id nil t) |
| 1664 | (beginning-of-line) | 1666 | (beginning-of-line) |
| @@ -1702,8 +1704,7 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details." | |||
| 1702 | 1704 | ||
| 1703 | (defun nnmail-cache-id-exists-p (id) | 1705 | (defun nnmail-cache-id-exists-p (id) |
| 1704 | (when nnmail-treat-duplicates | 1706 | (when nnmail-treat-duplicates |
| 1705 | (save-excursion | 1707 | (with-current-buffer nnmail-cache-buffer |
| 1706 | (set-buffer nnmail-cache-buffer) | ||
| 1707 | (goto-char (point-max)) | 1708 | (goto-char (point-max)) |
| 1708 | (search-backward id nil t)))) | 1709 | (search-backward id nil t)))) |
| 1709 | 1710 | ||
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 827eafdc7ed..b79e7103cef 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el | |||
| @@ -208,20 +208,16 @@ by nnmaildir-request-article.") | |||
| 208 | (eval param)) | 208 | (eval param)) |
| 209 | 209 | ||
| 210 | (defmacro nnmaildir--with-nntp-buffer (&rest body) | 210 | (defmacro nnmaildir--with-nntp-buffer (&rest body) |
| 211 | `(save-excursion | 211 | `(with-current-buffer nntp-server-buffer |
| 212 | (set-buffer nntp-server-buffer) | ||
| 213 | ,@body)) | 212 | ,@body)) |
| 214 | (defmacro nnmaildir--with-work-buffer (&rest body) | 213 | (defmacro nnmaildir--with-work-buffer (&rest body) |
| 215 | `(save-excursion | 214 | `(with-current-buffer (get-buffer-create " *nnmaildir work*") |
| 216 | (set-buffer (get-buffer-create " *nnmaildir work*")) | ||
| 217 | ,@body)) | 215 | ,@body)) |
| 218 | (defmacro nnmaildir--with-nov-buffer (&rest body) | 216 | (defmacro nnmaildir--with-nov-buffer (&rest body) |
| 219 | `(save-excursion | 217 | `(with-current-buffer (get-buffer-create " *nnmaildir nov*") |
| 220 | (set-buffer (get-buffer-create " *nnmaildir nov*")) | ||
| 221 | ,@body)) | 218 | ,@body)) |
| 222 | (defmacro nnmaildir--with-move-buffer (&rest body) | 219 | (defmacro nnmaildir--with-move-buffer (&rest body) |
| 223 | `(save-excursion | 220 | `(with-current-buffer (get-buffer-create " *nnmaildir move*") |
| 224 | (set-buffer (get-buffer-create " *nnmaildir move*")) | ||
| 225 | ,@body)) | 221 | ,@body)) |
| 226 | 222 | ||
| 227 | (defmacro nnmaildir--subdir (dir subdir) | 223 | (defmacro nnmaildir--subdir (dir subdir) |
| @@ -1249,8 +1245,7 @@ by nnmaildir-request-article.") | |||
| 1249 | (setf (nnmaildir--srv-error nnmaildir--cur-server) | 1245 | (setf (nnmaildir--srv-error nnmaildir--cur-server) |
| 1250 | "Article has expired") | 1246 | "Article has expired") |
| 1251 | (throw 'return nil)) | 1247 | (throw 'return nil)) |
| 1252 | (save-excursion | 1248 | (with-current-buffer (or to-buffer nntp-server-buffer) |
| 1253 | (set-buffer (or to-buffer nntp-server-buffer)) | ||
| 1254 | (erase-buffer) | 1249 | (erase-buffer) |
| 1255 | (nnheader-insert-file-contents nnmaildir-article-file-name)) | 1250 | (nnheader-insert-file-contents nnmaildir-article-file-name)) |
| 1256 | (cons gname num-msgid)))) | 1251 | (cons gname num-msgid)))) |
| @@ -1289,8 +1284,7 @@ by nnmaildir-request-article.") | |||
| 1289 | (setf (nnmaildir--srv-error nnmaildir--cur-server) | 1284 | (setf (nnmaildir--srv-error nnmaildir--cur-server) |
| 1290 | (concat "File exists: " tmpfile)) | 1285 | (concat "File exists: " tmpfile)) |
| 1291 | (throw 'return nil)) | 1286 | (throw 'return nil)) |
| 1292 | (save-excursion | 1287 | (with-current-buffer buffer |
| 1293 | (set-buffer buffer) | ||
| 1294 | (gmm-write-region (point-min) (point-max) tmpfile nil 'no-message nil | 1288 | (gmm-write-region (point-min) (point-max) tmpfile nil 'no-message nil |
| 1295 | 'excl)) | 1289 | 'excl)) |
| 1296 | (unix-sync) ;; no fsync :( | 1290 | (unix-sync) ;; no fsync :( |
diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 04db76b942a..b43a83e3a33 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el | |||
| @@ -445,8 +445,7 @@ Other back ends might or might not work.") | |||
| 445 | nil) | 445 | nil) |
| 446 | ((not query) | 446 | ((not query) |
| 447 | ;; No query -> return empty group | 447 | ;; No query -> return empty group |
| 448 | (save-excursion | 448 | (with-current-buffer nntp-server-buffer |
| 449 | (set-buffer nntp-server-buffer) | ||
| 450 | (erase-buffer) | 449 | (erase-buffer) |
| 451 | (insert (concat "211 0 1 0 " group)) | 450 | (insert (concat "211 0 1 0 " group)) |
| 452 | t)) | 451 | t)) |
| @@ -501,9 +500,9 @@ Other back ends might or might not work.") | |||
| 501 | (nnmairix-request-group-with-article-number-correction | 500 | (nnmairix-request-group-with-article-number-correction |
| 502 | folder qualgroup))) | 501 | folder qualgroup))) |
| 503 | ((and (= rval 1) | 502 | ((and (= rval 1) |
| 504 | (save-excursion (set-buffer nnmairix-mairix-output-buffer) | 503 | (with-current-buffer nnmairix-mairix-output-buffer |
| 505 | (goto-char (point-min)) | 504 | (goto-char (point-min)) |
| 506 | (looking-at "^Matched 0 messages"))) | 505 | (looking-at "^Matched 0 messages"))) |
| 507 | ;; No messages found -> return empty group | 506 | ;; No messages found -> return empty group |
| 508 | (nnheader-message 5 "Mairix: No matches found.") | 507 | (nnheader-message 5 "Mairix: No matches found.") |
| 509 | (set-buffer nntp-server-buffer) | 508 | (set-buffer nntp-server-buffer) |
| @@ -584,8 +583,7 @@ Other back ends might or might not work.") | |||
| 584 | (when server (nnmairix-open-server server)) | 583 | (when server (nnmairix-open-server server)) |
| 585 | (if (nnmairix-call-backend "request-list" nnmairix-backend-server) | 584 | (if (nnmairix-call-backend "request-list" nnmairix-backend-server) |
| 586 | (let (cpoint cur qualgroup folder) | 585 | (let (cpoint cur qualgroup folder) |
| 587 | (save-excursion | 586 | (with-current-buffer nntp-server-buffer |
| 588 | (set-buffer nntp-server-buffer) | ||
| 589 | (goto-char (point-min)) | 587 | (goto-char (point-min)) |
| 590 | (setq cpoint (point)) | 588 | (setq cpoint (point)) |
| 591 | (while (re-search-forward nnmairix-group-regexp (point-max) t) | 589 | (while (re-search-forward nnmairix-group-regexp (point-max) t) |
| @@ -699,8 +697,7 @@ Other back ends might or might not work.") | |||
| 699 | (when (or (eq nnmairix-propagate-marks-upon-close t) | 697 | (when (or (eq nnmairix-propagate-marks-upon-close t) |
| 700 | (and (eq nnmairix-propagate-marks-upon-close 'ask) | 698 | (and (eq nnmairix-propagate-marks-upon-close 'ask) |
| 701 | (y-or-n-p "Propagate marks to original articles? "))) | 699 | (y-or-n-p "Propagate marks to original articles? "))) |
| 702 | (save-excursion | 700 | (with-current-buffer gnus-group-buffer |
| 703 | (set-buffer gnus-group-buffer) | ||
| 704 | (nnmairix-propagate-marks) | 701 | (nnmairix-propagate-marks) |
| 705 | ;; update mairix group | 702 | ;; update mairix group |
| 706 | (gnus-group-jump-to-group qualgroup) | 703 | (gnus-group-jump-to-group qualgroup) |
| @@ -998,8 +995,7 @@ with m:msgid of the current article and enabled threads." | |||
| 998 | (if server | 995 | (if server |
| 999 | (if (gnus-buffer-live-p gnus-article-buffer) | 996 | (if (gnus-buffer-live-p gnus-article-buffer) |
| 1000 | (progn | 997 | (progn |
| 1001 | (save-excursion | 998 | (with-current-buffer gnus-article-buffer |
| 1002 | (set-buffer gnus-article-buffer) | ||
| 1003 | (gnus-summary-toggle-header 1) | 999 | (gnus-summary-toggle-header 1) |
| 1004 | (setq mid (message-fetch-field "Message-ID"))) | 1000 | (setq mid (message-fetch-field "Message-ID"))) |
| 1005 | (while (string-match "[<>]" mid) | 1001 | (while (string-match "[<>]" mid) |
| @@ -1021,8 +1017,7 @@ f:current_from." | |||
| 1021 | (if server | 1017 | (if server |
| 1022 | (if (gnus-buffer-live-p gnus-article-buffer) | 1018 | (if (gnus-buffer-live-p gnus-article-buffer) |
| 1023 | (progn | 1019 | (progn |
| 1024 | (save-excursion | 1020 | (with-current-buffer gnus-article-buffer |
| 1025 | (set-buffer gnus-article-buffer) | ||
| 1026 | (gnus-summary-toggle-header 1) | 1021 | (gnus-summary-toggle-header 1) |
| 1027 | (setq from (cadr (gnus-extract-address-components | 1022 | (setq from (cadr (gnus-extract-address-components |
| 1028 | (gnus-fetch-field "From")))) | 1023 | (gnus-fetch-field "From")))) |
| @@ -1046,8 +1041,7 @@ before deleting a group on the back end. SERVER specifies nnmairix server." | |||
| 1046 | (when (nnmairix-call-backend | 1041 | (when (nnmairix-call-backend |
| 1047 | "request-list" nnmairix-backend-server) | 1042 | "request-list" nnmairix-backend-server) |
| 1048 | (let (cur qualgroup folder) | 1043 | (let (cur qualgroup folder) |
| 1049 | (save-excursion | 1044 | (with-current-buffer nntp-server-buffer |
| 1050 | (set-buffer nntp-server-buffer) | ||
| 1051 | (goto-char (point-min)) | 1045 | (goto-char (point-min)) |
| 1052 | (while (re-search-forward nnmairix-group-regexp (point-max) t) | 1046 | (while (re-search-forward nnmairix-group-regexp (point-max) t) |
| 1053 | (setq cur (match-string 0) | 1047 | (setq cur (match-string 0) |
| @@ -1152,8 +1146,7 @@ nnmairix server. Only marks from current session will be set." | |||
| 1152 | (push (list (car ogroup) (list (list number) (nth 1 mid-marks) (nth 2 mid-marks))) | 1146 | (push (list (car ogroup) (list (list number) (nth 1 mid-marks) (nth 2 mid-marks))) |
| 1153 | number-cache))))) | 1147 | number-cache))))) |
| 1154 | ;; now we set the marks | 1148 | ;; now we set the marks |
| 1155 | (save-excursion | 1149 | (with-current-buffer gnus-group-buffer |
| 1156 | (set-buffer gnus-group-buffer) | ||
| 1157 | (nnheader-message 5 "nnmairix: Propagating marks...") | 1150 | (nnheader-message 5 "nnmairix: Propagating marks...") |
| 1158 | (dolist (cur number-cache) | 1151 | (dolist (cur number-cache) |
| 1159 | (setq method (gnus-find-method-for-group (car cur))) | 1152 | (setq method (gnus-find-method-for-group (car cur))) |
| @@ -1272,9 +1265,8 @@ Marks propagation has to be enabled for this to work." | |||
| 1272 | "Call mairix binary with COMMAND, using FOLDER and SEARCHQUERY. | 1265 | "Call mairix binary with COMMAND, using FOLDER and SEARCHQUERY. |
| 1273 | If THREADS is non-nil, enable full threads." | 1266 | If THREADS is non-nil, enable full threads." |
| 1274 | (let ((args (cons (car command) '(nil t nil)))) | 1267 | (let ((args (cons (car command) '(nil t nil)))) |
| 1275 | (save-excursion | 1268 | (with-current-buffer |
| 1276 | (set-buffer | 1269 | (get-buffer-create nnmairix-mairix-output-buffer) |
| 1277 | (get-buffer-create nnmairix-mairix-output-buffer)) | ||
| 1278 | (erase-buffer) | 1270 | (erase-buffer) |
| 1279 | (when (> (length command) 1) | 1271 | (when (> (length command) 1) |
| 1280 | (setq args (append args (cdr command)))) | 1272 | (setq args (append args (cdr command)))) |
| @@ -1291,9 +1283,8 @@ If THREADS is non-nil, enable full threads." | |||
| 1291 | (defun nnmairix-call-mairix-binary-raw (command query) | 1283 | (defun nnmairix-call-mairix-binary-raw (command query) |
| 1292 | "Call mairix binary with COMMAND and QUERY in raw mode." | 1284 | "Call mairix binary with COMMAND and QUERY in raw mode." |
| 1293 | (let ((args (cons (car command) '(nil t nil)))) | 1285 | (let ((args (cons (car command) '(nil t nil)))) |
| 1294 | (save-excursion | 1286 | (with-current-buffer |
| 1295 | (set-buffer | 1287 | (get-buffer-create nnmairix-mairix-output-buffer) |
| 1296 | (get-buffer-create nnmairix-mairix-output-buffer)) | ||
| 1297 | (erase-buffer) | 1288 | (erase-buffer) |
| 1298 | (when (> (length command) 1) | 1289 | (when (> (length command) 1) |
| 1299 | (setq args (append args (cdr command)))) | 1290 | (setq args (append args (cdr command)))) |
| @@ -1430,8 +1421,7 @@ MAIRIXGROUP. NUMC contains values for article number correction." | |||
| 1430 | (corr (not (zerop numc))) | 1421 | (corr (not (zerop numc))) |
| 1431 | (name (buffer-name nntp-server-buffer)) | 1422 | (name (buffer-name nntp-server-buffer)) |
| 1432 | header cur xref) | 1423 | header cur xref) |
| 1433 | (save-excursion | 1424 | (with-current-buffer buf |
| 1434 | (set-buffer buf) | ||
| 1435 | (erase-buffer) | 1425 | (erase-buffer) |
| 1436 | (set-buffer nntp-server-buffer) | 1426 | (set-buffer nntp-server-buffer) |
| 1437 | (goto-char (point-min)) | 1427 | (goto-char (point-min)) |
| @@ -1621,8 +1611,7 @@ search in raw mode." | |||
| 1621 | (let ((server (nth 1 gnus-current-select-method)) | 1611 | (let ((server (nth 1 gnus-current-select-method)) |
| 1622 | mid rval group allgroups) | 1612 | mid rval group allgroups) |
| 1623 | ;; get message id | 1613 | ;; get message id |
| 1624 | (save-excursion | 1614 | (with-current-buffer gnus-article-buffer |
| 1625 | (set-buffer gnus-article-buffer) | ||
| 1626 | (gnus-summary-toggle-header 1) | 1615 | (gnus-summary-toggle-header 1) |
| 1627 | (setq mid (message-fetch-field "Message-ID")) | 1616 | (setq mid (message-fetch-field "Message-ID")) |
| 1628 | ;; first check the registry (if available) | 1617 | ;; first check the registry (if available) |
| @@ -1678,8 +1667,7 @@ SERVER." | |||
| 1678 | (if (zerop (nnmairix-call-mairix-binary-raw | 1667 | (if (zerop (nnmairix-call-mairix-binary-raw |
| 1679 | (split-string nnmairix-mairix-command) | 1668 | (split-string nnmairix-mairix-command) |
| 1680 | (list (concat "m:" mid)))) | 1669 | (list (concat "m:" mid)))) |
| 1681 | (save-excursion | 1670 | (with-current-buffer nnmairix-mairix-output-buffer |
| 1682 | (set-buffer nnmairix-mairix-output-buffer) | ||
| 1683 | (goto-char (point-min)) | 1671 | (goto-char (point-min)) |
| 1684 | (while (re-search-forward "^/.*$" nil t) | 1672 | (while (re-search-forward "^/.*$" nil t) |
| 1685 | (push (nnmairix-get-group-from-file-path (match-string 0)) | 1673 | (push (nnmairix-get-group-from-file-path (match-string 0)) |
diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el index 7d71dc1c1e4..4b01bfa5c6e 100644 --- a/lisp/gnus/nnmbox.el +++ b/lisp/gnus/nnmbox.el | |||
| @@ -79,8 +79,7 @@ | |||
| 79 | (nnoo-define-basics nnmbox) | 79 | (nnoo-define-basics nnmbox) |
| 80 | 80 | ||
| 81 | (deffoo nnmbox-retrieve-headers (sequence &optional newsgroup server fetch-old) | 81 | (deffoo nnmbox-retrieve-headers (sequence &optional newsgroup server fetch-old) |
| 82 | (save-excursion | 82 | (with-current-buffer nntp-server-buffer |
| 83 | (set-buffer nntp-server-buffer) | ||
| 84 | (erase-buffer) | 83 | (erase-buffer) |
| 85 | (let ((number (length sequence)) | 84 | (let ((number (length sequence)) |
| 86 | (count 0) | 85 | (count 0) |
| @@ -149,8 +148,7 @@ | |||
| 149 | 148 | ||
| 150 | (deffoo nnmbox-request-article (article &optional newsgroup server buffer) | 149 | (deffoo nnmbox-request-article (article &optional newsgroup server buffer) |
| 151 | (nnmbox-possibly-change-newsgroup newsgroup server) | 150 | (nnmbox-possibly-change-newsgroup newsgroup server) |
| 152 | (save-excursion | 151 | (with-current-buffer nnmbox-mbox-buffer |
| 153 | (set-buffer nnmbox-mbox-buffer) | ||
| 154 | (when (nnmbox-find-article article) | 152 | (when (nnmbox-find-article article) |
| 155 | (let (start stop) | 153 | (let (start stop) |
| 156 | (re-search-backward (concat "^" message-unix-mail-delimiter) nil t) | 154 | (re-search-backward (concat "^" message-unix-mail-delimiter) nil t) |
| @@ -208,8 +206,7 @@ | |||
| 208 | (nnmail-get-new-mail | 206 | (nnmail-get-new-mail |
| 209 | 'nnmbox | 207 | 'nnmbox |
| 210 | (lambda () | 208 | (lambda () |
| 211 | (save-excursion | 209 | (with-current-buffer nnmbox-mbox-buffer |
| 212 | (set-buffer nnmbox-mbox-buffer) | ||
| 213 | (nnmbox-save-buffer))) | 210 | (nnmbox-save-buffer))) |
| 214 | (file-name-directory nnmbox-mbox-file) | 211 | (file-name-directory nnmbox-mbox-file) |
| 215 | group | 212 | group |
| @@ -253,8 +250,7 @@ | |||
| 253 | rest) | 250 | rest) |
| 254 | (nnmail-activate 'nnmbox) | 251 | (nnmail-activate 'nnmbox) |
| 255 | 252 | ||
| 256 | (save-excursion | 253 | (with-current-buffer nnmbox-mbox-buffer |
| 257 | (set-buffer nnmbox-mbox-buffer) | ||
| 258 | (while (and articles is-old) | 254 | (while (and articles is-old) |
| 259 | (when (nnmbox-find-article (car articles)) | 255 | (when (nnmbox-find-article (car articles)) |
| 260 | (if (setq is-old | 256 | (if (setq is-old |
| @@ -292,8 +288,7 @@ | |||
| 292 | result) | 288 | result) |
| 293 | (and | 289 | (and |
| 294 | (nnmbox-request-article article group server) | 290 | (nnmbox-request-article article group server) |
| 295 | (save-excursion | 291 | (with-current-buffer buf |
| 296 | (set-buffer buf) | ||
| 297 | (erase-buffer) | 292 | (erase-buffer) |
| 298 | (insert-buffer-substring nntp-server-buffer) | 293 | (insert-buffer-substring nntp-server-buffer) |
| 299 | (goto-char (point-min)) | 294 | (goto-char (point-min)) |
| @@ -364,8 +359,7 @@ | |||
| 364 | 359 | ||
| 365 | (deffoo nnmbox-request-replace-article (article group buffer) | 360 | (deffoo nnmbox-request-replace-article (article group buffer) |
| 366 | (nnmbox-possibly-change-newsgroup group) | 361 | (nnmbox-possibly-change-newsgroup group) |
| 367 | (save-excursion | 362 | (with-current-buffer nnmbox-mbox-buffer |
| 368 | (set-buffer nnmbox-mbox-buffer) | ||
| 369 | (if (not (nnmbox-find-article article)) | 363 | (if (not (nnmbox-find-article article)) |
| 370 | nil | 364 | nil |
| 371 | (nnmbox-delete-mail t t) | 365 | (nnmbox-delete-mail t t) |
| @@ -391,8 +385,7 @@ | |||
| 391 | ;; Delete all articles in GROUP. | 385 | ;; Delete all articles in GROUP. |
| 392 | (if (not force) | 386 | (if (not force) |
| 393 | () ; Don't delete the articles. | 387 | () ; Don't delete the articles. |
| 394 | (save-excursion | 388 | (with-current-buffer nnmbox-mbox-buffer |
| 395 | (set-buffer nnmbox-mbox-buffer) | ||
| 396 | (goto-char (point-min)) | 389 | (goto-char (point-min)) |
| 397 | ;; Delete all articles in this group. | 390 | ;; Delete all articles in this group. |
| 398 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":")) | 391 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":")) |
| @@ -412,8 +405,7 @@ | |||
| 412 | 405 | ||
| 413 | (deffoo nnmbox-request-rename-group (group new-name &optional server) | 406 | (deffoo nnmbox-request-rename-group (group new-name &optional server) |
| 414 | (nnmbox-possibly-change-newsgroup group server) | 407 | (nnmbox-possibly-change-newsgroup group server) |
| 415 | (save-excursion | 408 | (with-current-buffer nnmbox-mbox-buffer |
| 416 | (set-buffer nnmbox-mbox-buffer) | ||
| 417 | (goto-char (point-min)) | 409 | (goto-char (point-min)) |
| 418 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":")) | 410 | (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":")) |
| 419 | (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":")) | 411 | (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":")) |
| @@ -633,8 +625,7 @@ | |||
| 633 | (nnmbox-create-mbox) | 625 | (nnmbox-create-mbox) |
| 634 | (if (and nnmbox-mbox-buffer | 626 | (if (and nnmbox-mbox-buffer |
| 635 | (buffer-name nnmbox-mbox-buffer) | 627 | (buffer-name nnmbox-mbox-buffer) |
| 636 | (save-excursion | 628 | (with-current-buffer nnmbox-mbox-buffer |
| 637 | (set-buffer nnmbox-mbox-buffer) | ||
| 638 | (= (buffer-size) (nnheader-file-size nnmbox-mbox-file)))) | 629 | (= (buffer-size) (nnheader-file-size nnmbox-mbox-file)))) |
| 639 | () | 630 | () |
| 640 | (save-excursion | 631 | (save-excursion |
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index 6d676bb8514..5d62192819e 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el | |||
| @@ -160,8 +160,7 @@ non-nil.") | |||
| 160 | 160 | ||
| 161 | (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old) | 161 | (deffoo nnml-retrieve-headers (sequence &optional group server fetch-old) |
| 162 | (when (nnml-possibly-change-directory group server) | 162 | (when (nnml-possibly-change-directory group server) |
| 163 | (save-excursion | 163 | (with-current-buffer nntp-server-buffer |
| 164 | (set-buffer nntp-server-buffer) | ||
| 165 | (erase-buffer) | 164 | (erase-buffer) |
| 166 | (let* ((file nil) | 165 | (let* ((file nil) |
| 167 | (number (length sequence)) | 166 | (number (length sequence)) |
| @@ -405,8 +404,7 @@ non-nil.") | |||
| 405 | (let (nnml-current-directory | 404 | (let (nnml-current-directory |
| 406 | nnml-current-group | 405 | nnml-current-group |
| 407 | nnml-article-file-alist) | 406 | nnml-article-file-alist) |
| 408 | (save-excursion | 407 | (with-current-buffer buf |
| 409 | (set-buffer buf) | ||
| 410 | (insert-buffer-substring nntp-server-buffer) | 408 | (insert-buffer-substring nntp-server-buffer) |
| 411 | (setq result (eval accept-form)) | 409 | (setq result (eval accept-form)) |
| 412 | (kill-buffer (current-buffer)) | 410 | (kill-buffer (current-buffer)) |
| @@ -462,8 +460,7 @@ non-nil.") | |||
| 462 | 460 | ||
| 463 | (deffoo nnml-request-replace-article (article group buffer) | 461 | (deffoo nnml-request-replace-article (article group buffer) |
| 464 | (nnml-possibly-change-directory group) | 462 | (nnml-possibly-change-directory group) |
| 465 | (save-excursion | 463 | (with-current-buffer buffer |
| 466 | (set-buffer buffer) | ||
| 467 | (nnml-possibly-create-directory group) | 464 | (nnml-possibly-create-directory group) |
| 468 | (let ((chars (nnmail-insert-lines)) | 465 | (let ((chars (nnmail-insert-lines)) |
| 469 | (art (concat (int-to-string article) "\t")) | 466 | (art (concat (int-to-string article) "\t")) |
| @@ -478,8 +475,7 @@ non-nil.") | |||
| 478 | t) | 475 | t) |
| 479 | (setq headers (nnml-parse-head chars article)) | 476 | (setq headers (nnml-parse-head chars article)) |
| 480 | ;; Replace the NOV line in the NOV file. | 477 | ;; Replace the NOV line in the NOV file. |
| 481 | (save-excursion | 478 | (with-current-buffer (nnml-open-nov group) |
| 482 | (set-buffer (nnml-open-nov group)) | ||
| 483 | (goto-char (point-min)) | 479 | (goto-char (point-min)) |
| 484 | (if (or (looking-at art) | 480 | (if (or (looking-at art) |
| 485 | (search-forward (concat "\n" art) nil t)) | 481 | (search-forward (concat "\n" art) nil t)) |
| @@ -614,8 +610,7 @@ non-nil.") | |||
| 614 | 610 | ||
| 615 | ;; Find an article number in the current group given the Message-ID. | 611 | ;; Find an article number in the current group given the Message-ID. |
| 616 | (defun nnml-find-group-number (id server) | 612 | (defun nnml-find-group-number (id server) |
| 617 | (save-excursion | 613 | (with-current-buffer (get-buffer-create " *nnml id*") |
| 618 | (set-buffer (get-buffer-create " *nnml id*")) | ||
| 619 | (let ((alist nnml-group-alist) | 614 | (let ((alist nnml-group-alist) |
| 620 | number) | 615 | number) |
| 621 | ;; We want to look through all .overview files, but we want to | 616 | ;; We want to look through all .overview files, but we want to |
| @@ -657,8 +652,7 @@ non-nil.") | |||
| 657 | nil | 652 | nil |
| 658 | (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory))) | 653 | (let ((nov (expand-file-name nnml-nov-file-name nnml-current-directory))) |
| 659 | (when (file-exists-p nov) | 654 | (when (file-exists-p nov) |
| 660 | (save-excursion | 655 | (with-current-buffer nntp-server-buffer |
| 661 | (set-buffer nntp-server-buffer) | ||
| 662 | (erase-buffer) | 656 | (erase-buffer) |
| 663 | (nnheader-insert-file-contents nov) | 657 | (nnheader-insert-file-contents nov) |
| 664 | (if (and fetch-old | 658 | (if (and fetch-old |
| @@ -804,16 +798,14 @@ article number. This function is called narrowed to an article." | |||
| 804 | 798 | ||
| 805 | (defun nnml-add-incremental-nov (group article headers) | 799 | (defun nnml-add-incremental-nov (group article headers) |
| 806 | "Add a nov line for the GROUP nov headers, incrementally." | 800 | "Add a nov line for the GROUP nov headers, incrementally." |
| 807 | (save-excursion | 801 | (with-current-buffer (nnml-open-incremental-nov group) |
| 808 | (set-buffer (nnml-open-incremental-nov group)) | ||
| 809 | (goto-char (point-max)) | 802 | (goto-char (point-max)) |
| 810 | (mail-header-set-number headers article) | 803 | (mail-header-set-number headers article) |
| 811 | (nnheader-insert-nov headers))) | 804 | (nnheader-insert-nov headers))) |
| 812 | 805 | ||
| 813 | (defun nnml-add-nov (group article headers) | 806 | (defun nnml-add-nov (group article headers) |
| 814 | "Add a nov line for the GROUP base." | 807 | "Add a nov line for the GROUP base." |
| 815 | (save-excursion | 808 | (with-current-buffer (nnml-open-nov group) |
| 816 | (set-buffer (nnml-open-nov group)) | ||
| 817 | (goto-char (point-max)) | 809 | (goto-char (point-max)) |
| 818 | (mail-header-set-number headers article) | 810 | (mail-header-set-number headers article) |
| 819 | (nnheader-insert-nov headers))) | 811 | (nnheader-insert-nov headers))) |
| @@ -844,8 +836,7 @@ article number. This function is called narrowed to an article." | |||
| 844 | "") | 836 | "") |
| 845 | decoded))) | 837 | decoded))) |
| 846 | (file-name-coding-system nnmail-pathname-coding-system)) | 838 | (file-name-coding-system nnmail-pathname-coding-system)) |
| 847 | (save-excursion | 839 | (with-current-buffer buffer |
| 848 | (set-buffer buffer) | ||
| 849 | (set (make-local-variable 'nnml-nov-buffer-file-name) | 840 | (set (make-local-variable 'nnml-nov-buffer-file-name) |
| 850 | (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name)) | 841 | (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name)) |
| 851 | (erase-buffer) | 842 | (erase-buffer) |
| @@ -942,9 +933,8 @@ Unless no-active is non-nil, update the active file too." | |||
| 942 | (nov (concat dir nnml-nov-file-name)) | 933 | (nov (concat dir nnml-nov-file-name)) |
| 943 | (nov-buffer (get-buffer-create " *nov*")) | 934 | (nov-buffer (get-buffer-create " *nov*")) |
| 944 | chars file headers) | 935 | chars file headers) |
| 945 | (save-excursion | 936 | (with-current-buffer nov-buffer |
| 946 | ;; Init the nov buffer. | 937 | ;; Init the nov buffer. |
| 947 | (set-buffer nov-buffer) | ||
| 948 | (buffer-disable-undo) | 938 | (buffer-disable-undo) |
| 949 | (erase-buffer) | 939 | (erase-buffer) |
| 950 | (set-buffer nntp-server-buffer) | 940 | (set-buffer nntp-server-buffer) |
| @@ -964,20 +954,17 @@ Unless no-active is non-nil, update the active file too." | |||
| 964 | (unless (zerop (buffer-size)) | 954 | (unless (zerop (buffer-size)) |
| 965 | (goto-char (point-min)) | 955 | (goto-char (point-min)) |
| 966 | (setq headers (nnml-parse-head chars (caar files))) | 956 | (setq headers (nnml-parse-head chars (caar files))) |
| 967 | (save-excursion | 957 | (with-current-buffer nov-buffer |
| 968 | (set-buffer nov-buffer) | ||
| 969 | (goto-char (point-max)) | 958 | (goto-char (point-max)) |
| 970 | (nnheader-insert-nov headers))) | 959 | (nnheader-insert-nov headers))) |
| 971 | (widen)) | 960 | (widen)) |
| 972 | (setq files (cdr files))) | 961 | (setq files (cdr files))) |
| 973 | (save-excursion | 962 | (with-current-buffer nov-buffer |
| 974 | (set-buffer nov-buffer) | ||
| 975 | (nnmail-write-region (point-min) (point-max) nov nil 'nomesg) | 963 | (nnmail-write-region (point-min) (point-max) nov nil 'nomesg) |
| 976 | (kill-buffer (current-buffer)))))) | 964 | (kill-buffer (current-buffer)))))) |
| 977 | 965 | ||
| 978 | (defun nnml-nov-delete-article (group article) | 966 | (defun nnml-nov-delete-article (group article) |
| 979 | (save-excursion | 967 | (with-current-buffer (nnml-open-nov group) |
| 980 | (set-buffer (nnml-open-nov group)) | ||
| 981 | (when (nnheader-find-nov-line article) | 968 | (when (nnheader-find-nov-line article) |
| 982 | (delete-region (point) (progn (forward-line 1) (point))) | 969 | (delete-region (point) (progn (forward-line 1) (point))) |
| 983 | (when (bobp) | 970 | (when (bobp) |
| @@ -1260,8 +1247,7 @@ Use the nov database for the current group if available." | |||
| 1260 | (gnus-info-set-marks info newmarks)) | 1247 | (gnus-info-set-marks info newmarks)) |
| 1261 | ;; 3/ Update the NOV entry for this article: | 1248 | ;; 3/ Update the NOV entry for this article: |
| 1262 | (unless nnml-nov-is-evil | 1249 | (unless nnml-nov-is-evil |
| 1263 | (save-excursion | 1250 | (with-current-buffer (nnml-open-nov group) |
| 1264 | (set-buffer (nnml-open-nov group)) | ||
| 1265 | (when (nnheader-find-nov-line old-number) | 1251 | (when (nnheader-find-nov-line old-number) |
| 1266 | ;; Replace the article number: | 1252 | ;; Replace the article number: |
| 1267 | (looking-at old-number-string) | 1253 | (looking-at old-number-string) |
diff --git a/lisp/gnus/nnnil.el b/lisp/gnus/nnnil.el index f6bc35aec3c..dd5e9841c15 100644 --- a/lisp/gnus/nnnil.el +++ b/lisp/gnus/nnnil.el | |||
| @@ -58,8 +58,7 @@ | |||
| 58 | 58 | ||
| 59 | (defun nnnil-request-group (group &optional server fast) | 59 | (defun nnnil-request-group (group &optional server fast) |
| 60 | (let (deactivate-mark) | 60 | (let (deactivate-mark) |
| 61 | (save-excursion | 61 | (with-current-buffer nntp-server-buffer |
| 62 | (set-buffer nntp-server-buffer) | ||
| 63 | (erase-buffer) | 62 | (erase-buffer) |
| 64 | (insert "411 no such news group\n"))) | 63 | (insert "411 no such news group\n"))) |
| 65 | (setq nnnil-status-string "No such group") | 64 | (setq nnnil-status-string "No such group") |
diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el index cdf2b829ecc..ee1e36f55c7 100644 --- a/lisp/gnus/nnspool.el +++ b/lisp/gnus/nnspool.el | |||
| @@ -109,8 +109,7 @@ there.") | |||
| 109 | 109 | ||
| 110 | (deffoo nnspool-retrieve-headers (articles &optional group server fetch-old) | 110 | (deffoo nnspool-retrieve-headers (articles &optional group server fetch-old) |
| 111 | "Retrieve the headers of ARTICLES." | 111 | "Retrieve the headers of ARTICLES." |
| 112 | (save-excursion | 112 | (with-current-buffer nntp-server-buffer |
| 113 | (set-buffer nntp-server-buffer) | ||
| 114 | (erase-buffer) | 113 | (erase-buffer) |
| 115 | (when (nnspool-possibly-change-directory group) | 114 | (when (nnspool-possibly-change-directory group) |
| 116 | (let* ((number (length articles)) | 115 | (let* ((number (length articles)) |
| @@ -209,8 +208,7 @@ there.") | |||
| 209 | (nnspool-possibly-change-directory group) | 208 | (nnspool-possibly-change-directory group) |
| 210 | (let ((res (nnspool-request-article id))) | 209 | (let ((res (nnspool-request-article id))) |
| 211 | (when res | 210 | (when res |
| 212 | (save-excursion | 211 | (with-current-buffer nntp-server-buffer |
| 213 | (set-buffer nntp-server-buffer) | ||
| 214 | (goto-char (point-min)) | 212 | (goto-char (point-min)) |
| 215 | (when (search-forward "\n\n" nil t) | 213 | (when (search-forward "\n\n" nil t) |
| 216 | (delete-region (point-min) (point))) | 214 | (delete-region (point-min) (point))) |
| @@ -221,8 +219,7 @@ there.") | |||
| 221 | (nnspool-possibly-change-directory group) | 219 | (nnspool-possibly-change-directory group) |
| 222 | (let ((res (nnspool-request-article id))) | 220 | (let ((res (nnspool-request-article id))) |
| 223 | (when res | 221 | (when res |
| 224 | (save-excursion | 222 | (with-current-buffer nntp-server-buffer |
| 225 | (set-buffer nntp-server-buffer) | ||
| 226 | (goto-char (point-min)) | 223 | (goto-char (point-min)) |
| 227 | (when (search-forward "\n\n" nil t) | 224 | (when (search-forward "\n\n" nil t) |
| 228 | (delete-region (1- (point)) (point-max))) | 225 | (delete-region (1- (point)) (point-max))) |
| @@ -343,8 +340,7 @@ there.") | |||
| 343 | ;;; Internal functions. | 340 | ;;; Internal functions. |
| 344 | 341 | ||
| 345 | (defun nnspool-inews-sentinel (proc status) | 342 | (defun nnspool-inews-sentinel (proc status) |
| 346 | (save-excursion | 343 | (with-current-buffer (process-buffer proc) |
| 347 | (set-buffer (process-buffer proc)) | ||
| 348 | (goto-char (point-min)) | 344 | (goto-char (point-min)) |
| 349 | (if (or (zerop (buffer-size)) | 345 | (if (or (zerop (buffer-size)) |
| 350 | (search-forward "spooled" nil t)) | 346 | (search-forward "spooled" nil t)) |
| @@ -367,8 +363,7 @@ there.") | |||
| 367 | last) | 363 | last) |
| 368 | (if (not (file-exists-p nov)) | 364 | (if (not (file-exists-p nov)) |
| 369 | () | 365 | () |
| 370 | (save-excursion | 366 | (with-current-buffer nntp-server-buffer |
| 371 | (set-buffer nntp-server-buffer) | ||
| 372 | (erase-buffer) | 367 | (erase-buffer) |
| 373 | (if nnspool-sift-nov-with-sed | 368 | (if nnspool-sift-nov-with-sed |
| 374 | (nnspool-sift-nov-with-sed articles nov) | 369 | (nnspool-sift-nov-with-sed articles nov) |
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index 3cdd63084ef..59f803d8c6a 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el | |||
| @@ -1014,7 +1014,8 @@ command whose response triggered the error." | |||
| 1014 | (unless (assq 'nntp-address defs) | 1014 | (unless (assq 'nntp-address defs) |
| 1015 | (setq defs (append defs (list (list 'nntp-address server))))) | 1015 | (setq defs (append defs (list (list 'nntp-address server))))) |
| 1016 | (nnoo-change-server 'nntp server defs) | 1016 | (nnoo-change-server 'nntp server defs) |
| 1017 | (unless connectionless | 1017 | (if connectionless |
| 1018 | t | ||
| 1018 | (or (nntp-find-connection nntp-server-buffer) | 1019 | (or (nntp-find-connection nntp-server-buffer) |
| 1019 | (nntp-open-connection nntp-server-buffer))))) | 1020 | (nntp-open-connection nntp-server-buffer))))) |
| 1020 | 1021 | ||
diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index c94d1837fa9..18faa23a80e 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el | |||
| @@ -93,8 +93,7 @@ component group will show up when you enter the virtual group.") | |||
| 93 | (deffoo nnvirtual-retrieve-headers (articles &optional newsgroup | 93 | (deffoo nnvirtual-retrieve-headers (articles &optional newsgroup |
| 94 | server fetch-old) | 94 | server fetch-old) |
| 95 | (when (nnvirtual-possibly-change-server server) | 95 | (when (nnvirtual-possibly-change-server server) |
| 96 | (save-excursion | 96 | (with-current-buffer nntp-server-buffer |
| 97 | (set-buffer nntp-server-buffer) | ||
| 98 | (erase-buffer) | 97 | (erase-buffer) |
| 99 | (if (stringp (car articles)) | 98 | (if (stringp (car articles)) |
| 100 | 'headers | 99 | 'headers |
| @@ -170,8 +169,7 @@ component group will show up when you enter the virtual group.") | |||
| 170 | ;; the nntp-server-buffer, which is where Gnus expects to find | 169 | ;; the nntp-server-buffer, which is where Gnus expects to find |
| 171 | ;; them. | 170 | ;; them. |
| 172 | (prog1 | 171 | (prog1 |
| 173 | (save-excursion | 172 | (with-current-buffer nntp-server-buffer |
| 174 | (set-buffer nntp-server-buffer) | ||
| 175 | (erase-buffer) | 173 | (erase-buffer) |
| 176 | (insert-buffer-substring vbuf) | 174 | (insert-buffer-substring vbuf) |
| 177 | ;; FIX FIX FIX, we should be able to sort faster than | 175 | ;; FIX FIX FIX, we should be able to sort faster than |
| @@ -215,8 +213,7 @@ component group will show up when you enter the virtual group.") | |||
| 215 | (t | 213 | (t |
| 216 | (setq nnvirtual-last-accessed-component-group cgroup) | 214 | (setq nnvirtual-last-accessed-component-group cgroup) |
| 217 | (if buffer | 215 | (if buffer |
| 218 | (save-excursion | 216 | (with-current-buffer buffer |
| 219 | (set-buffer buffer) | ||
| 220 | ;; We bind this here to avoid double decoding. | 217 | ;; We bind this here to avoid double decoding. |
| 221 | (let ((gnus-article-decode-hook nil)) | 218 | (let ((gnus-article-decode-hook nil)) |
| 222 | (gnus-request-article-this-buffer (cdr amap) cgroup))) | 219 | (gnus-request-article-this-buffer (cdr amap) cgroup))) |
| @@ -335,8 +332,7 @@ component group will show up when you enter the virtual group.") | |||
| 335 | (when (not (numberp (gnus-group-unread g))) | 332 | (when (not (numberp (gnus-group-unread g))) |
| 336 | (gnus-activate-group g))) | 333 | (gnus-activate-group g))) |
| 337 | nnvirtual-component-groups) | 334 | nnvirtual-component-groups) |
| 338 | (save-excursion | 335 | (with-current-buffer gnus-group-buffer |
| 339 | (set-buffer gnus-group-buffer) | ||
| 340 | (gnus-group-catchup-current nil all))))) | 336 | (gnus-group-catchup-current nil all))))) |
| 341 | 337 | ||
| 342 | 338 | ||
diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el index 3b4f71c80aa..e6289c57bca 100644 --- a/lisp/gnus/nnweb.el +++ b/lisp/gnus/nnweb.el | |||
| @@ -104,8 +104,7 @@ Valid types include `google', `dejanews', and `gmane'.") | |||
| 104 | 104 | ||
| 105 | (deffoo nnweb-retrieve-headers (articles &optional group server fetch-old) | 105 | (deffoo nnweb-retrieve-headers (articles &optional group server fetch-old) |
| 106 | (nnweb-possibly-change-server group server) | 106 | (nnweb-possibly-change-server group server) |
| 107 | (save-excursion | 107 | (with-current-buffer nntp-server-buffer |
| 108 | (set-buffer nntp-server-buffer) | ||
| 109 | (erase-buffer) | 108 | (erase-buffer) |
| 110 | (let (article header) | 109 | (let (article header) |
| 111 | (mm-with-unibyte-current-buffer | 110 | (mm-with-unibyte-current-buffer |
| @@ -147,16 +146,14 @@ Valid types include `google', `dejanews', and `gmane'.") | |||
| 147 | (deffoo nnweb-close-group (group &optional server) | 146 | (deffoo nnweb-close-group (group &optional server) |
| 148 | (nnweb-possibly-change-server group server) | 147 | (nnweb-possibly-change-server group server) |
| 149 | (when (gnus-buffer-live-p nnweb-buffer) | 148 | (when (gnus-buffer-live-p nnweb-buffer) |
| 150 | (save-excursion | 149 | (with-current-buffer nnweb-buffer |
| 151 | (set-buffer nnweb-buffer) | ||
| 152 | (set-buffer-modified-p nil) | 150 | (set-buffer-modified-p nil) |
| 153 | (kill-buffer nnweb-buffer))) | 151 | (kill-buffer nnweb-buffer))) |
| 154 | t) | 152 | t) |
| 155 | 153 | ||
| 156 | (deffoo nnweb-request-article (article &optional group server buffer) | 154 | (deffoo nnweb-request-article (article &optional group server buffer) |
| 157 | (nnweb-possibly-change-server group server) | 155 | (nnweb-possibly-change-server group server) |
| 158 | (save-excursion | 156 | (with-current-buffer (or buffer nntp-server-buffer) |
| 159 | (set-buffer (or buffer nntp-server-buffer)) | ||
| 160 | (let* ((header (cadr (assq article nnweb-articles))) | 157 | (let* ((header (cadr (assq article nnweb-articles))) |
| 161 | (url (and header (mail-header-xref header)))) | 158 | (url (and header (mail-header-xref header)))) |
| 162 | (when (or (and url | 159 | (when (or (and url |
| @@ -185,16 +182,14 @@ Valid types include `google', `dejanews', and `gmane'.") | |||
| 185 | (deffoo nnweb-close-server (&optional server) | 182 | (deffoo nnweb-close-server (&optional server) |
| 186 | (when (and (nnweb-server-opened server) | 183 | (when (and (nnweb-server-opened server) |
| 187 | (gnus-buffer-live-p nnweb-buffer)) | 184 | (gnus-buffer-live-p nnweb-buffer)) |
| 188 | (save-excursion | 185 | (with-current-buffer nnweb-buffer |
| 189 | (set-buffer nnweb-buffer) | ||
| 190 | (set-buffer-modified-p nil) | 186 | (set-buffer-modified-p nil) |
| 191 | (kill-buffer nnweb-buffer))) | 187 | (kill-buffer nnweb-buffer))) |
| 192 | (nnoo-close-server 'nnweb server)) | 188 | (nnoo-close-server 'nnweb server)) |
| 193 | 189 | ||
| 194 | (deffoo nnweb-request-list (&optional server) | 190 | (deffoo nnweb-request-list (&optional server) |
| 195 | (nnweb-possibly-change-server nil server) | 191 | (nnweb-possibly-change-server nil server) |
| 196 | (save-excursion | 192 | (with-current-buffer nntp-server-buffer |
| 197 | (set-buffer nntp-server-buffer) | ||
| 198 | (nnmail-generate-active (list (assoc server nnweb-group-alist))) | 193 | (nnmail-generate-active (list (assoc server nnweb-group-alist))) |
| 199 | t)) | 194 | t)) |
| 200 | 195 | ||
| @@ -402,8 +397,7 @@ Valid types include `google', `dejanews', and `gmane'.") | |||
| 402 | 397 | ||
| 403 | (defun nnweb-google-create-mapping () | 398 | (defun nnweb-google-create-mapping () |
| 404 | "Perform the search and create a number-to-url alist." | 399 | "Perform the search and create a number-to-url alist." |
| 405 | (save-excursion | 400 | (with-current-buffer nnweb-buffer |
| 406 | (set-buffer nnweb-buffer) | ||
| 407 | (erase-buffer) | 401 | (erase-buffer) |
| 408 | (nnheader-message 7 "Searching google...") | 402 | (nnheader-message 7 "Searching google...") |
| 409 | (when (funcall (nnweb-definition 'search) nnweb-search) | 403 | (when (funcall (nnweb-definition 'search) nnweb-search) |
| @@ -459,8 +453,7 @@ Valid types include `google', `dejanews', and `gmane'.") | |||
| 459 | ;;; | 453 | ;;; |
| 460 | (defun nnweb-gmane-create-mapping () | 454 | (defun nnweb-gmane-create-mapping () |
| 461 | "Perform the search and create a number-to-url alist." | 455 | "Perform the search and create a number-to-url alist." |
| 462 | (save-excursion | 456 | (with-current-buffer nnweb-buffer |
| 463 | (set-buffer nnweb-buffer) | ||
| 464 | (let ((case-fold-search t) | 457 | (let ((case-fold-search t) |
| 465 | (active (or (cadr (assoc nnweb-group nnweb-group-alist)) | 458 | (active (or (cadr (assoc nnweb-group nnweb-group-alist)) |
| 466 | (cons 1 0))) | 459 | (cons 1 0))) |
diff --git a/lisp/gnus/pop3.el b/lisp/gnus/pop3.el index 950cae25c4e..63ed8004a9f 100644 --- a/lisp/gnus/pop3.el +++ b/lisp/gnus/pop3.el | |||
| @@ -279,9 +279,9 @@ Returns the process associated with the connection." | |||
| 279 | (let ((coding-system-for-read 'binary) | 279 | (let ((coding-system-for-read 'binary) |
| 280 | (coding-system-for-write 'binary) | 280 | (coding-system-for-write 'binary) |
| 281 | process) | 281 | process) |
| 282 | (with-current-buffer | 282 | (save-excursion |
| 283 | (get-buffer-create (concat " trace of POP session to " | 283 | (set-buffer (get-buffer-create (concat " trace of POP session to " |
| 284 | mailhost)) | 284 | mailhost))) |
| 285 | (erase-buffer) | 285 | (erase-buffer) |
| 286 | (setq pop3-read-point (point-min)) | 286 | (setq pop3-read-point (point-min)) |
| 287 | (setq process | 287 | (setq process |
| @@ -353,7 +353,8 @@ Returns the process associated with the connection." | |||
| 353 | Return the response string if optional second argument is non-nil." | 353 | Return the response string if optional second argument is non-nil." |
| 354 | (let ((case-fold-search nil) | 354 | (let ((case-fold-search nil) |
| 355 | match-end) | 355 | match-end) |
| 356 | (with-current-buffer (process-buffer process) | 356 | (save-excursion |
| 357 | (set-buffer (process-buffer process)) | ||
| 357 | (goto-char pop3-read-point) | 358 | (goto-char pop3-read-point) |
| 358 | (while (and (memq (process-status process) '(open run)) | 359 | (while (and (memq (process-status process) '(open run)) |
| 359 | (not (search-forward "\r\n" nil t))) | 360 | (not (search-forward "\r\n" nil t))) |
| @@ -510,7 +511,8 @@ Otherwise, return the size of the message-id MSG" | |||
| 510 | (if msg | 511 | (if msg |
| 511 | (string-to-number (nth 2 (split-string response " "))) | 512 | (string-to-number (nth 2 (split-string response " "))) |
| 512 | (let ((start pop3-read-point) end) | 513 | (let ((start pop3-read-point) end) |
| 513 | (with-current-buffer (process-buffer process) | 514 | (save-excursion |
| 515 | (set-buffer (process-buffer process)) | ||
| 514 | (while (not (re-search-forward "^\\.\r\n" nil t)) | 516 | (while (not (re-search-forward "^\\.\r\n" nil t)) |
| 515 | (pop3-accept-process-output process) | 517 | (pop3-accept-process-output process) |
| 516 | (goto-char start)) | 518 | (goto-char start)) |
| @@ -528,7 +530,8 @@ Otherwise, return the size of the message-id MSG" | |||
| 528 | (pop3-send-command process (format "RETR %s" msg)) | 530 | (pop3-send-command process (format "RETR %s" msg)) |
| 529 | (pop3-read-response process) | 531 | (pop3-read-response process) |
| 530 | (let ((start pop3-read-point) end) | 532 | (let ((start pop3-read-point) end) |
| 531 | (with-current-buffer (process-buffer process) | 533 | (save-excursion |
| 534 | (set-buffer (process-buffer process)) | ||
| 532 | (while (not (re-search-forward "^\\.\r\n" nil t)) | 535 | (while (not (re-search-forward "^\\.\r\n" nil t)) |
| 533 | (pop3-accept-process-output process) | 536 | (pop3-accept-process-output process) |
| 534 | (goto-char start)) | 537 | (goto-char start)) |
| @@ -544,7 +547,8 @@ Otherwise, return the size of the message-id MSG" | |||
| 544 | (setq end (point-marker)) | 547 | (setq end (point-marker)) |
| 545 | (pop3-clean-region start end) | 548 | (pop3-clean-region start end) |
| 546 | (pop3-munge-message-separator start end) | 549 | (pop3-munge-message-separator start end) |
| 547 | (with-current-buffer crashbuf | 550 | (save-excursion |
| 551 | (set-buffer crashbuf) | ||
| 548 | (erase-buffer)) | 552 | (erase-buffer)) |
| 549 | (copy-to-buffer crashbuf start end) | 553 | (copy-to-buffer crashbuf start end) |
| 550 | (delete-region start end) | 554 | (delete-region start end) |
| @@ -581,7 +585,8 @@ and close the connection." | |||
| 581 | (pop3-send-command process "QUIT") | 585 | (pop3-send-command process "QUIT") |
| 582 | (pop3-read-response process t) | 586 | (pop3-read-response process t) |
| 583 | (if process | 587 | (if process |
| 584 | (with-current-buffer (process-buffer process) | 588 | (save-excursion |
| 589 | (set-buffer (process-buffer process)) | ||
| 585 | (goto-char (point-max)) | 590 | (goto-char (point-max)) |
| 586 | (delete-process process)))) | 591 | (delete-process process)))) |
| 587 | 592 | ||
diff --git a/lisp/gnus/smime.el b/lisp/gnus/smime.el index d836f320164..a2668199469 100644 --- a/lisp/gnus/smime.el +++ b/lisp/gnus/smime.el | |||
| @@ -708,8 +708,7 @@ The following commands are available: | |||
| 708 | "Go to the SMIME buffer." | 708 | "Go to the SMIME buffer." |
| 709 | (interactive) | 709 | (interactive) |
| 710 | (unless (get-buffer smime-buffer) | 710 | (unless (get-buffer smime-buffer) |
| 711 | (save-excursion | 711 | (with-current-buffer (get-buffer-create smime-buffer) |
| 712 | (set-buffer (get-buffer-create smime-buffer)) | ||
| 713 | (smime-mode))) | 712 | (smime-mode))) |
| 714 | (smime-draw-buffer) | 713 | (smime-draw-buffer) |
| 715 | (switch-to-buffer smime-buffer)) | 714 | (switch-to-buffer smime-buffer)) |
diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el index 0e32e934040..e73444e85c0 100644 --- a/lisp/gnus/spam-report.el +++ b/lisp/gnus/spam-report.el | |||
| @@ -109,8 +109,7 @@ Reports is as ham when HAM is set." | |||
| 109 | ;; select this particular article | 109 | ;; select this particular article |
| 110 | (gnus-summary-select-article nil nil nil article) | 110 | (gnus-summary-select-article nil nil nil article) |
| 111 | ;; resend it to the destination address | 111 | ;; resend it to the destination address |
| 112 | (save-excursion | 112 | (with-current-buffer gnus-original-article-buffer |
| 113 | (set-buffer gnus-original-article-buffer) | ||
| 114 | (message-resend spam-report-resend-to)))) | 113 | (message-resend spam-report-resend-to)))) |
| 115 | 114 | ||
| 116 | (defun spam-report-resend-ham (articles) | 115 | (defun spam-report-resend-ham (articles) |
| @@ -292,8 +291,7 @@ symbol `ask', query before flushing the queue file." | |||
| 292 | (gnus-message 7 "Processing requests using `%s'." | 291 | (gnus-message 7 "Processing requests using `%s'." |
| 293 | spam-report-url-ping-function)) | 292 | spam-report-url-ping-function)) |
| 294 | (or file (setq file spam-report-requests-file)) | 293 | (or file (setq file spam-report-requests-file)) |
| 295 | (save-excursion | 294 | (with-current-buffer (find-file-noselect file) |
| 296 | (set-buffer (find-file-noselect file)) | ||
| 297 | (goto-char (point-min)) | 295 | (goto-char (point-min)) |
| 298 | (while (and (not (eobp)) | 296 | (while (and (not (eobp)) |
| 299 | (re-search-forward | 297 | (re-search-forward |
diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el index d079be2fcd2..b7908e5507b 100644 --- a/lisp/gnus/spam.el +++ b/lisp/gnus/spam.el | |||
| @@ -1605,8 +1605,7 @@ to find it out)." | |||
| 1605 | article)))) | 1605 | article)))) |
| 1606 | 1606 | ||
| 1607 | (defun spam-fetch-article-header (article) | 1607 | (defun spam-fetch-article-header (article) |
| 1608 | (save-excursion | 1608 | (with-current-buffer gnus-summary-buffer |
| 1609 | (set-buffer gnus-summary-buffer) | ||
| 1610 | (gnus-read-header article) | 1609 | (gnus-read-header article) |
| 1611 | (nth 3 (assq article gnus-newsgroup-data)))) | 1610 | (nth 3 (assq article gnus-newsgroup-data)))) |
| 1612 | ;;}}} | 1611 | ;;}}} |
| @@ -2172,8 +2171,7 @@ See `spam-ifile-database'." | |||
| 2172 | (with-temp-buffer | 2171 | (with-temp-buffer |
| 2173 | (let ((temp-buffer-name (buffer-name)) | 2172 | (let ((temp-buffer-name (buffer-name)) |
| 2174 | (db-param (spam-get-ifile-database-parameter))) | 2173 | (db-param (spam-get-ifile-database-parameter))) |
| 2175 | (save-excursion | 2174 | (with-current-buffer article-buffer-name |
| 2176 | (set-buffer article-buffer-name) | ||
| 2177 | (apply 'call-process-region | 2175 | (apply 'call-process-region |
| 2178 | (point-min) (point-max) spam-ifile-program | 2176 | (point-min) (point-max) spam-ifile-program |
| 2179 | nil temp-buffer-name nil "-c" | 2177 | nil temp-buffer-name nil "-c" |
| @@ -2318,9 +2316,8 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2318 | ;; else, we have a list of addresses here | 2316 | ;; else, we have a list of addresses here |
| 2319 | (unless (file-exists-p (file-name-directory file)) | 2317 | (unless (file-exists-p (file-name-directory file)) |
| 2320 | (make-directory (file-name-directory file) t)) | 2318 | (make-directory (file-name-directory file) t)) |
| 2321 | (save-excursion | 2319 | (with-current-buffer |
| 2322 | (set-buffer | 2320 | (find-file-noselect file) |
| 2323 | (find-file-noselect file)) | ||
| 2324 | (dolist (a addresses) | 2321 | (dolist (a addresses) |
| 2325 | (when (stringp a) | 2322 | (when (stringp a) |
| 2326 | (goto-char (point-min)) | 2323 | (goto-char (point-min)) |
| @@ -2521,8 +2518,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2521 | return) | 2518 | return) |
| 2522 | (with-temp-buffer | 2519 | (with-temp-buffer |
| 2523 | (let ((temp-buffer-name (buffer-name))) | 2520 | (let ((temp-buffer-name (buffer-name))) |
| 2524 | (save-excursion | 2521 | (with-current-buffer article-buffer-name |
| 2525 | (set-buffer article-buffer-name) | ||
| 2526 | (apply 'call-process-region | 2522 | (apply 'call-process-region |
| 2527 | (point-min) (point-max) | 2523 | (point-min) (point-max) |
| 2528 | spam-bogofilter-program | 2524 | spam-bogofilter-program |
| @@ -2579,8 +2575,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2579 | (let ((article-buffer-name (buffer-name))) | 2575 | (let ((article-buffer-name (buffer-name))) |
| 2580 | (with-temp-buffer | 2576 | (with-temp-buffer |
| 2581 | (let ((temp-buffer-name (buffer-name))) | 2577 | (let ((temp-buffer-name (buffer-name))) |
| 2582 | (save-excursion | 2578 | (with-current-buffer article-buffer-name |
| 2583 | (set-buffer article-buffer-name) | ||
| 2584 | (let ((status | 2579 | (let ((status |
| 2585 | (apply 'call-process-region | 2580 | (apply 'call-process-region |
| 2586 | (point-min) (point-max) | 2581 | (point-min) (point-max) |
| @@ -2656,8 +2651,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2656 | (let ((article-buffer-name (buffer-name))) | 2651 | (let ((article-buffer-name (buffer-name))) |
| 2657 | (with-temp-buffer | 2652 | (with-temp-buffer |
| 2658 | (let ((temp-buffer-name (buffer-name))) | 2653 | (let ((temp-buffer-name (buffer-name))) |
| 2659 | (save-excursion | 2654 | (with-current-buffer article-buffer-name |
| 2660 | (set-buffer article-buffer-name) | ||
| 2661 | (apply 'call-process-region | 2655 | (apply 'call-process-region |
| 2662 | (point-min) (point-max) spam-assassin-program | 2656 | (point-min) (point-max) spam-assassin-program |
| 2663 | nil temp-buffer-name nil spam-spamassassin-arguments)) | 2657 | nil temp-buffer-name nil spam-spamassassin-arguments)) |
| @@ -2691,8 +2685,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2691 | ;; group the articles into mbox format | 2685 | ;; group the articles into mbox format |
| 2692 | (dolist (article articles) | 2686 | (dolist (article articles) |
| 2693 | (let (article-string) | 2687 | (let (article-string) |
| 2694 | (save-excursion | 2688 | (with-current-buffer summary-buffer-name |
| 2695 | (set-buffer summary-buffer-name) | ||
| 2696 | (setq article-string (spam-get-article-as-string article))) | 2689 | (setq article-string (spam-get-article-as-string article))) |
| 2697 | (when (stringp article-string) | 2690 | (when (stringp article-string) |
| 2698 | (insert "From \n") ; mbox separator (sa-learn only checks the | 2691 | (insert "From \n") ; mbox separator (sa-learn only checks the |
| @@ -2755,8 +2748,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2755 | return) | 2748 | return) |
| 2756 | (with-temp-buffer | 2749 | (with-temp-buffer |
| 2757 | (let ((temp-buffer-name (buffer-name))) | 2750 | (let ((temp-buffer-name (buffer-name))) |
| 2758 | (save-excursion | 2751 | (with-current-buffer article-buffer-name |
| 2759 | (set-buffer article-buffer-name) | ||
| 2760 | (apply 'call-process-region | 2752 | (apply 'call-process-region |
| 2761 | (point-min) (point-max) | 2753 | (point-min) (point-max) |
| 2762 | spam-bsfilter-program | 2754 | spam-bsfilter-program |
| @@ -2841,8 +2833,7 @@ With a non-nil REMOVE, remove the ADDRESSES." | |||
| 2841 | return) | 2833 | return) |
| 2842 | (with-temp-buffer | 2834 | (with-temp-buffer |
| 2843 | (let ((temp-buffer-name (buffer-name))) | 2835 | (let ((temp-buffer-name (buffer-name))) |
| 2844 | (save-excursion | 2836 | (with-current-buffer article-buffer-name |
| 2845 | (set-buffer article-buffer-name) | ||
| 2846 | (apply 'call-process-region | 2837 | (apply 'call-process-region |
| 2847 | (point-min) (point-max) | 2838 | (point-min) (point-max) |
| 2848 | spam-crm114-program | 2839 | spam-crm114-program |
diff --git a/lisp/gnus/starttls.el b/lisp/gnus/starttls.el index 02a557de5cc..bf1982f54dd 100644 --- a/lisp/gnus/starttls.el +++ b/lisp/gnus/starttls.el | |||
| @@ -254,8 +254,7 @@ handshake, or nil on failure." | |||
| 254 | (starttls-set-process-query-on-exit-flag process nil) | 254 | (starttls-set-process-query-on-exit-flag process nil) |
| 255 | (while (and (processp process) | 255 | (while (and (processp process) |
| 256 | (eq (process-status process) 'run) | 256 | (eq (process-status process) 'run) |
| 257 | (save-excursion | 257 | (with-current-buffer buffer |
| 258 | (set-buffer buffer) | ||
| 259 | (goto-char old-max) | 258 | (goto-char old-max) |
| 260 | (not (setq done (re-search-forward | 259 | (not (setq done (re-search-forward |
| 261 | starttls-connect nil t))))) | 260 | starttls-connect nil t))))) |
diff --git a/lisp/gnus/utf7.el b/lisp/gnus/utf7.el index cca647d94b2..74bd092a3dd 100644 --- a/lisp/gnus/utf7.el +++ b/lisp/gnus/utf7.el | |||
| @@ -205,6 +205,7 @@ Characters are in raw byte pairs in narrowed buffer." | |||
| 205 | (mm-decode-coding-region (point-min) (point-max) 'iso-8859-1) | 205 | (mm-decode-coding-region (point-min) (point-max) 'iso-8859-1) |
| 206 | (mm-enable-multibyte)) | 206 | (mm-enable-multibyte)) |
| 207 | 207 | ||
| 208 | ;;;###autoload | ||
| 208 | (defun utf7-encode (string &optional for-imap) | 209 | (defun utf7-encode (string &optional for-imap) |
| 209 | "Encode UTF-7 STRING. Use IMAP modification if FOR-IMAP is non-nil." | 210 | "Encode UTF-7 STRING. Use IMAP modification if FOR-IMAP is non-nil." |
| 210 | (if (and (coding-system-p 'utf-7) (coding-system-p 'utf-7-imap)) | 211 | (if (and (coding-system-p 'utf-7) (coding-system-p 'utf-7-imap)) |
diff --git a/lisp/net/netrc.el b/lisp/net/netrc.el index 408eca9bac7..3636c892726 100644 --- a/lisp/net/netrc.el +++ b/lisp/net/netrc.el | |||
| @@ -228,6 +228,7 @@ MODE can be \"login\" or \"password\", suitable for passing to | |||
| 228 | (eq type (car (cddr service))))))) | 228 | (eq type (car (cddr service))))))) |
| 229 | (cadr service))) | 229 | (cadr service))) |
| 230 | 230 | ||
| 231 | ;;;###autoload | ||
| 231 | (defun netrc-credentials (machine &rest ports) | 232 | (defun netrc-credentials (machine &rest ports) |
| 232 | "Return a user name/password pair. | 233 | "Return a user name/password pair. |
| 233 | Port specifications will be prioritised in the order they are | 234 | Port specifications will be prioritised in the order they are |