diff options
| author | Lars Ingebrigtsen | 2022-01-17 12:40:43 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-01-17 15:47:50 +0100 |
| commit | 39d4e1ca21f3270d4835d5efa8862efc618c4cd9 (patch) | |
| tree | c7449bb32cc89e37d3ce8266ad4f135bda70d3a1 | |
| parent | ab17e353253a88d92f68b3909b27ded9e536fb28 (diff) | |
| download | emacs-39d4e1ca21f3270d4835d5efa8862efc618c4cd9.tar.gz emacs-39d4e1ca21f3270d4835d5efa8862efc618c4cd9.zip | |
Move the Gnus range functions to a new range.el file
* lisp/emacs-lisp/range.el: New file.
* lisp/gnus/gnus-agent.el (range):
(gnus-agent-synchronize-group-flags):
(gnus-agent-possibly-alter-active):
(gnus-agent-fetch-headers):
(gnus-agent-read-agentview):
(gnus-agent-fetch-group-1):
(gnus-agent-read-p):
(gnus-agent-expire-group-1):
(gnus-agent-retrieve-headers): Adjust callers.
* lisp/gnus/gnus-art.el (range):
(gnus-article-describe-bindings):
* lisp/gnus/gnus-cloud.el (range):
(gnus-cloud-available-chunks):
* lisp/gnus/gnus-draft.el (gnus-group-send-queue):
* lisp/gnus/gnus-group.el (range):
(gnus-group-line-format-alist):
(gnus-number-of-unseen-articles-in-group):
(gnus-group-update-eval-form):
(gnus-group-read-group):
(gnus-group-delete-articles):
(gnus-group-catchup):
(gnus-group-expire-articles-1):
(gnus-add-marked-articles):
* lisp/gnus/gnus-int.el (gnus-request-marks):
* lisp/gnus/gnus-kill.el (gnus-apply-kill-file-internal):
* lisp/gnus/gnus-range.el (gnus-range-difference)
(gnus-sorted-range-intersection, gnus-uncompress-range)
(gnus-add-to-range, gnus-remove-from-range)
(gnus-member-of-range, gnus-list-range-intersection)
(gnus-list-range-difference, gnus-range-length, gnus-range-add)
(gnus-range-map): Make into obsolete aliases.
* lisp/gnus/gnus-start.el (gnus-make-articles-unread):
(gnus-convert-old-ticks):
(gnus-read-old-newsrc-el-file):
* lisp/gnus/gnus-sum.el (gnus-select-newsgroup):
(gnus-articles-to-read):
(gnus-articles-to-read):
(gnus-killed-articles):
(gnus-adjust-marked-articles):
(gnus-update-marks):
(gnus-update-marks):
(gnus-compute-read-articles):
(gnus-list-of-read-articles):
(gnus-summary-update-info):
(gnus-summary-move-article):
(gnus-summary-expire-articles):
(gnus-update-read-articles):
(gnus-summary-insert-old-articles):
(gnus-summary-insert-old-articles):
(gnus-summary-insert-old-articles):
* lisp/gnus/mail-source.el (gnus-range):
(gnus-compress-sequence):
* lisp/gnus/nnheader.el (range):
(gnus-range-add):
(nnheader-update-marks-actions):
* lisp/gnus/nnimap.el (nnimap-update-info):
(nnimap-update-info):
(nnimap-update-info):
(nnimap-update-qresync-info):
(nnimap-update-qresync-info):
(nnimap-update-qresync-info):
(nnimap-parse-copied-articles):
* lisp/gnus/nnmaildir.el (nnmaildir-request-update-info):
(nnmaildir-request-update-info):
(nnmaildir-request-expire-articles):
(nnmaildir-request-expire-articles):
(nnmaildir-request-set-mark):
* lisp/gnus/nnmairix.el (nnmairix-request-set-mark):
* lisp/gnus/nnmbox.el (nnmbox-record-active-article):
(nnmbox-record-deleted-article):
* lisp/gnus/nnml.el (nnml-request-compact-group):
* lisp/gnus/nnvirtual.el (nnvirtual-request-expire-articles):
* lisp/gnus/nnselect.el (numbers-by-group):
(nnselect-request-update-info):
(nnselect-push-info):
| -rw-r--r-- | lisp/emacs-lisp/range.el | 467 | ||||
| -rw-r--r-- | lisp/gnus/gnus-agent.el | 45 | ||||
| -rw-r--r-- | lisp/gnus/gnus-art.el | 3 | ||||
| -rw-r--r-- | lisp/gnus/gnus-cloud.el | 3 | ||||
| -rw-r--r-- | lisp/gnus/gnus-draft.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/gnus-group.el | 52 | ||||
| -rw-r--r-- | lisp/gnus/gnus-int.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/gnus-kill.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/gnus-range.el | 443 | ||||
| -rw-r--r-- | lisp/gnus/gnus-start.el | 14 | ||||
| -rw-r--r-- | lisp/gnus/gnus-sum.el | 64 | ||||
| -rw-r--r-- | lisp/gnus/mail-source.el | 3 | ||||
| -rw-r--r-- | lisp/gnus/nnheader.el | 8 | ||||
| -rw-r--r-- | lisp/gnus/nnimap.el | 29 | ||||
| -rw-r--r-- | lisp/gnus/nnmaildir.el | 16 | ||||
| -rw-r--r-- | lisp/gnus/nnmairix.el | 2 | ||||
| -rw-r--r-- | lisp/gnus/nnmbox.el | 6 | ||||
| -rw-r--r-- | lisp/gnus/nnml.el | 19 | ||||
| -rw-r--r-- | lisp/gnus/nnselect.el | 30 | ||||
| -rw-r--r-- | lisp/gnus/nnvirtual.el | 2 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/range-tests.el | 65 |
21 files changed, 710 insertions, 567 deletions
diff --git a/lisp/emacs-lisp/range.el b/lisp/emacs-lisp/range.el new file mode 100644 index 00000000000..38c2866cd4c --- /dev/null +++ b/lisp/emacs-lisp/range.el | |||
| @@ -0,0 +1,467 @@ | |||
| 1 | ;;; ranges.el --- range functions -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 1996-2022 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 6 | |||
| 7 | ;; This file is part of GNU Emacs. | ||
| 8 | |||
| 9 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 10 | ;; it under the terms of the GNU General Public License as published by | ||
| 11 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU General Public License for more details. | ||
| 18 | |||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Commentary: | ||
| 23 | |||
| 24 | ;; A "range" is a list that represents a list of integers. A range is | ||
| 25 | ;; a list containing cons cells of start/end pairs, as well as integers. | ||
| 26 | ;; | ||
| 27 | ;; ((2 . 5) 9 (11 . 13)) | ||
| 28 | ;; | ||
| 29 | ;; represents the list (2 3 4 5 9 11 12 13). | ||
| 30 | |||
| 31 | ;;; Code: | ||
| 32 | |||
| 33 | (defun range-normalize (range) | ||
| 34 | "Normalize RANGE. | ||
| 35 | If RANGE is a single range, return (RANGE). Otherwise, return RANGE." | ||
| 36 | (if (listp (cdr-safe range)) | ||
| 37 | range | ||
| 38 | (list range))) | ||
| 39 | |||
| 40 | (defun range-denormalize (range) | ||
| 41 | "If RANGE contains a single range, then return that. | ||
| 42 | If not, return RANGE as is." | ||
| 43 | (if (and (consp (car range)) | ||
| 44 | (length= range 1)) | ||
| 45 | (car range) | ||
| 46 | range)) | ||
| 47 | |||
| 48 | (defun range-difference (range1 range2) | ||
| 49 | "Return the range of elements in RANGE1 that do not appear in RANGE2. | ||
| 50 | Both ranges must be in ascending order." | ||
| 51 | (setq range1 (range-normalize range1)) | ||
| 52 | (setq range2 (range-normalize range2)) | ||
| 53 | (let* ((new-range (cons nil (copy-sequence range1))) | ||
| 54 | (r new-range)) | ||
| 55 | (while (cdr r) | ||
| 56 | (let* ((r1 (cadr r)) | ||
| 57 | (r2 (car range2)) | ||
| 58 | (min1 (if (numberp r1) r1 (car r1))) | ||
| 59 | (max1 (if (numberp r1) r1 (cdr r1))) | ||
| 60 | (min2 (if (numberp r2) r2 (car r2))) | ||
| 61 | (max2 (if (numberp r2) r2 (cdr r2)))) | ||
| 62 | |||
| 63 | (cond ((> min1 max1) | ||
| 64 | ;; Invalid range: may result from overlap condition (below) | ||
| 65 | ;; remove Invalid range | ||
| 66 | (setcdr r (cddr r))) | ||
| 67 | ((and (= min1 max1) | ||
| 68 | (listp r1)) | ||
| 69 | ;; Inefficient representation: may result from overlap | ||
| 70 | ;; condition (below) | ||
| 71 | (setcar (cdr r) min1)) | ||
| 72 | ((not min2) | ||
| 73 | ;; All done with range2 | ||
| 74 | (setq r nil)) | ||
| 75 | ((< max1 min2) | ||
| 76 | ;; No overlap: range1 precedes range2 | ||
| 77 | (pop r)) | ||
| 78 | ((< max2 min1) | ||
| 79 | ;; No overlap: range2 precedes range1 | ||
| 80 | (pop range2)) | ||
| 81 | ((and (<= min2 min1) (<= max1 max2)) | ||
| 82 | ;; Complete overlap: range1 removed | ||
| 83 | (setcdr r (cddr r))) | ||
| 84 | (t | ||
| 85 | (setcdr r (nconc (list (cons min1 (1- min2)) | ||
| 86 | (cons (1+ max2) max1)) | ||
| 87 | (cddr r))))))) | ||
| 88 | (cdr new-range))) | ||
| 89 | |||
| 90 | (defun range-intersection (range1 range2) | ||
| 91 | "Return intersection of RANGE1 and RANGE2." | ||
| 92 | (let* (out | ||
| 93 | (min1 (car range1)) | ||
| 94 | (max1 (if (numberp min1) | ||
| 95 | (if (numberp (cdr range1)) | ||
| 96 | (prog1 (cdr range1) | ||
| 97 | (setq range1 nil)) min1) | ||
| 98 | (prog1 (cdr min1) | ||
| 99 | (setq min1 (car min1))))) | ||
| 100 | (min2 (car range2)) | ||
| 101 | (max2 (if (numberp min2) | ||
| 102 | (if (numberp (cdr range2)) | ||
| 103 | (prog1 (cdr range2) | ||
| 104 | (setq range2 nil)) min2) | ||
| 105 | (prog1 (cdr min2) | ||
| 106 | (setq min2 (car min2)))))) | ||
| 107 | (setq range1 (cdr range1) | ||
| 108 | range2 (cdr range2)) | ||
| 109 | (while (and min1 min2) | ||
| 110 | (cond ((< max1 min2) ; range1 precedes range2 | ||
| 111 | (setq range1 (cdr range1) | ||
| 112 | min1 nil)) | ||
| 113 | ((< max2 min1) ; range2 precedes range1 | ||
| 114 | (setq range2 (cdr range2) | ||
| 115 | min2 nil)) | ||
| 116 | (t ; some sort of overlap is occurring | ||
| 117 | (let ((min (max min1 min2)) | ||
| 118 | (max (min max1 max2))) | ||
| 119 | (setq out (if (= min max) | ||
| 120 | (cons min out) | ||
| 121 | (cons (cons min max) out)))) | ||
| 122 | (if (< max1 max2) ; range1 ends before range2 | ||
| 123 | (setq min1 nil) ; incr range1 | ||
| 124 | (setq min2 nil)))) ; incr range2 | ||
| 125 | (unless min1 | ||
| 126 | (setq min1 (car range1) | ||
| 127 | max1 (if (numberp min1) min1 | ||
| 128 | (prog1 (cdr min1) (setq min1 (car min1)))) | ||
| 129 | range1 (cdr range1))) | ||
| 130 | (unless min2 | ||
| 131 | (setq min2 (car range2) | ||
| 132 | max2 (if (numberp min2) min2 | ||
| 133 | (prog1 (cdr min2) (setq min2 (car min2)))) | ||
| 134 | range2 (cdr range2)))) | ||
| 135 | (cond ((cdr out) | ||
| 136 | (nreverse out)) | ||
| 137 | ((numberp (car out)) | ||
| 138 | out) | ||
| 139 | (t | ||
| 140 | (car out))))) | ||
| 141 | |||
| 142 | (defun range-compress-list (numbers) | ||
| 143 | "Convert a sorted list of numbers to a range list." | ||
| 144 | (let ((first (car numbers)) | ||
| 145 | (last (car numbers)) | ||
| 146 | result) | ||
| 147 | (cond | ||
| 148 | ((null numbers) | ||
| 149 | nil) | ||
| 150 | ((not (listp (cdr numbers))) | ||
| 151 | numbers) | ||
| 152 | (t | ||
| 153 | (while numbers | ||
| 154 | (cond ((= last (car numbers)) nil) ;Omit duplicated number | ||
| 155 | ((= (1+ last) (car numbers)) ;Still in sequence | ||
| 156 | (setq last (car numbers))) | ||
| 157 | (t ;End of one sequence | ||
| 158 | (setq result | ||
| 159 | (cons (if (= first last) first | ||
| 160 | (cons first last)) | ||
| 161 | result)) | ||
| 162 | (setq first (car numbers)) | ||
| 163 | (setq last (car numbers)))) | ||
| 164 | (setq numbers (cdr numbers))) | ||
| 165 | (nreverse (cons (if (= first last) first (cons first last)) | ||
| 166 | result)))))) | ||
| 167 | |||
| 168 | (defun range-uncompress (ranges) | ||
| 169 | "Expand a list of ranges into a list of numbers. | ||
| 170 | RANGES is either a single range on the form `(num . num)' or a list of | ||
| 171 | these ranges." | ||
| 172 | (let (first last result) | ||
| 173 | (cond | ||
| 174 | ((null ranges) | ||
| 175 | nil) | ||
| 176 | ((not (listp (cdr ranges))) | ||
| 177 | (setq first (car ranges)) | ||
| 178 | (setq last (cdr ranges)) | ||
| 179 | (while (<= first last) | ||
| 180 | (setq result (cons first result)) | ||
| 181 | (setq first (1+ first))) | ||
| 182 | (nreverse result)) | ||
| 183 | (t | ||
| 184 | (while ranges | ||
| 185 | (if (atom (car ranges)) | ||
| 186 | (when (numberp (car ranges)) | ||
| 187 | (setq result (cons (car ranges) result))) | ||
| 188 | (setq first (caar ranges)) | ||
| 189 | (setq last (cdar ranges)) | ||
| 190 | (while (<= first last) | ||
| 191 | (setq result (cons first result)) | ||
| 192 | (setq first (1+ first)))) | ||
| 193 | (setq ranges (cdr ranges))) | ||
| 194 | (nreverse result))))) | ||
| 195 | |||
| 196 | (defun range-add-list (ranges list) | ||
| 197 | "Return a list of ranges that has all articles from both RANGES and LIST. | ||
| 198 | Note: LIST has to be sorted over `<'." | ||
| 199 | (if (not ranges) | ||
| 200 | (range-compress-list list) | ||
| 201 | (setq list (copy-sequence list)) | ||
| 202 | (unless (listp (cdr ranges)) | ||
| 203 | (setq ranges (list ranges))) | ||
| 204 | (let ((out ranges) | ||
| 205 | ilist lowest highest temp) | ||
| 206 | (while (and ranges list) | ||
| 207 | (setq ilist list) | ||
| 208 | (setq lowest (or (and (atom (car ranges)) (car ranges)) | ||
| 209 | (caar ranges))) | ||
| 210 | (while (and list (cdr list) (< (cadr list) lowest)) | ||
| 211 | (setq list (cdr list))) | ||
| 212 | (when (< (car ilist) lowest) | ||
| 213 | (setq temp list) | ||
| 214 | (setq list (cdr list)) | ||
| 215 | (setcdr temp nil) | ||
| 216 | (setq out (nconc (range-compress-list ilist) out))) | ||
| 217 | (setq highest (or (and (atom (car ranges)) (car ranges)) | ||
| 218 | (cdar ranges))) | ||
| 219 | (while (and list (<= (car list) highest)) | ||
| 220 | (setq list (cdr list))) | ||
| 221 | (setq ranges (cdr ranges))) | ||
| 222 | (when list | ||
| 223 | (setq out (nconc (range-compress-list list) out))) | ||
| 224 | (setq out (sort out (lambda (r1 r2) | ||
| 225 | (< (or (and (atom r1) r1) (car r1)) | ||
| 226 | (or (and (atom r2) r2) (car r2)))))) | ||
| 227 | (setq ranges out) | ||
| 228 | (while ranges | ||
| 229 | (if (atom (car ranges)) | ||
| 230 | (when (cdr ranges) | ||
| 231 | (if (atom (cadr ranges)) | ||
| 232 | (when (= (1+ (car ranges)) (cadr ranges)) | ||
| 233 | (setcar ranges (cons (car ranges) | ||
| 234 | (cadr ranges))) | ||
| 235 | (setcdr ranges (cddr ranges))) | ||
| 236 | (when (= (1+ (car ranges)) (caadr ranges)) | ||
| 237 | (setcar (cadr ranges) (car ranges)) | ||
| 238 | (setcar ranges (cadr ranges)) | ||
| 239 | (setcdr ranges (cddr ranges))))) | ||
| 240 | (when (cdr ranges) | ||
| 241 | (if (atom (cadr ranges)) | ||
| 242 | (when (= (1+ (cdar ranges)) (cadr ranges)) | ||
| 243 | (setcdr (car ranges) (cadr ranges)) | ||
| 244 | (setcdr ranges (cddr ranges))) | ||
| 245 | (when (= (1+ (cdar ranges)) (caadr ranges)) | ||
| 246 | (setcdr (car ranges) (cdadr ranges)) | ||
| 247 | (setcdr ranges (cddr ranges)))))) | ||
| 248 | (setq ranges (cdr ranges))) | ||
| 249 | out))) | ||
| 250 | |||
| 251 | (defun range-remove (range1 range2) | ||
| 252 | "Return a range that has all articles from RANGE2 removed from RANGE1. | ||
| 253 | The returned range is always a list. RANGE2 can also be a unsorted | ||
| 254 | list of articles. RANGE1 is modified by side effects, RANGE2 is not | ||
| 255 | modified." | ||
| 256 | (if (or (null range1) (null range2)) | ||
| 257 | range1 | ||
| 258 | (let (out r1 r2 r1-min r1-max r2-min r2-max | ||
| 259 | (range2 (copy-tree range2))) | ||
| 260 | (setq range1 (if (listp (cdr range1)) range1 (list range1)) | ||
| 261 | range2 (sort (if (listp (cdr range2)) range2 (list range2)) | ||
| 262 | (lambda (e1 e2) | ||
| 263 | (< (if (consp e1) (car e1) e1) | ||
| 264 | (if (consp e2) (car e2) e2)))) | ||
| 265 | r1 (car range1) | ||
| 266 | r2 (car range2) | ||
| 267 | r1-min (if (consp r1) (car r1) r1) | ||
| 268 | r1-max (if (consp r1) (cdr r1) r1) | ||
| 269 | r2-min (if (consp r2) (car r2) r2) | ||
| 270 | r2-max (if (consp r2) (cdr r2) r2)) | ||
| 271 | (while (and range1 range2) | ||
| 272 | (cond ((< r2-max r1-min) ; r2 < r1 | ||
| 273 | (pop range2) | ||
| 274 | (setq r2 (car range2) | ||
| 275 | r2-min (if (consp r2) (car r2) r2) | ||
| 276 | r2-max (if (consp r2) (cdr r2) r2))) | ||
| 277 | ((and (<= r2-min r1-min) (<= r1-max r2-max)) ; r2 overlap r1 | ||
| 278 | (pop range1) | ||
| 279 | (setq r1 (car range1) | ||
| 280 | r1-min (if (consp r1) (car r1) r1) | ||
| 281 | r1-max (if (consp r1) (cdr r1) r1))) | ||
| 282 | ((and (<= r2-min r1-min) (<= r2-max r1-max)) ; r2 overlap min r1 | ||
| 283 | (pop range2) | ||
| 284 | (setq r1-min (1+ r2-max) | ||
| 285 | r2 (car range2) | ||
| 286 | r2-min (if (consp r2) (car r2) r2) | ||
| 287 | r2-max (if (consp r2) (cdr r2) r2))) | ||
| 288 | ((and (<= r1-min r2-min) (<= r2-max r1-max)) ; r2 contained in r1 | ||
| 289 | (if (eq r1-min (1- r2-min)) | ||
| 290 | (push r1-min out) | ||
| 291 | (push (cons r1-min (1- r2-min)) out)) | ||
| 292 | (pop range2) | ||
| 293 | (if (< r2-max r1-max) ; finished with r1? | ||
| 294 | (setq r1-min (1+ r2-max)) | ||
| 295 | (pop range1) | ||
| 296 | (setq r1 (car range1) | ||
| 297 | r1-min (if (consp r1) (car r1) r1) | ||
| 298 | r1-max (if (consp r1) (cdr r1) r1))) | ||
| 299 | (setq r2 (car range2) | ||
| 300 | r2-min (if (consp r2) (car r2) r2) | ||
| 301 | r2-max (if (consp r2) (cdr r2) r2))) | ||
| 302 | ((and (<= r2-min r1-max) (<= r1-max r2-max)) ; r2 overlap max r1 | ||
| 303 | (if (eq r1-min (1- r2-min)) | ||
| 304 | (push r1-min out) | ||
| 305 | (push (cons r1-min (1- r2-min)) out)) | ||
| 306 | (pop range1) | ||
| 307 | (setq r1 (car range1) | ||
| 308 | r1-min (if (consp r1) (car r1) r1) | ||
| 309 | r1-max (if (consp r1) (cdr r1) r1))) | ||
| 310 | ((< r1-max r2-min) ; r2 > r1 | ||
| 311 | (pop range1) | ||
| 312 | (if (eq r1-min r1-max) | ||
| 313 | (push r1-min out) | ||
| 314 | (push (cons r1-min r1-max) out)) | ||
| 315 | (setq r1 (car range1) | ||
| 316 | r1-min (if (consp r1) (car r1) r1) | ||
| 317 | r1-max (if (consp r1) (cdr r1) r1))))) | ||
| 318 | (when r1 | ||
| 319 | (if (eq r1-min r1-max) | ||
| 320 | (push r1-min out) | ||
| 321 | (push (cons r1-min r1-max) out)) | ||
| 322 | (pop range1)) | ||
| 323 | (while range1 | ||
| 324 | (push (pop range1) out)) | ||
| 325 | (nreverse out)))) | ||
| 326 | |||
| 327 | (defun range-member-p (number ranges) | ||
| 328 | "Say whether NUMBER is in RANGES." | ||
| 329 | (if (not (listp (cdr ranges))) | ||
| 330 | (and (>= number (car ranges)) | ||
| 331 | (<= number (cdr ranges))) | ||
| 332 | (let ((not-stop t)) | ||
| 333 | (while (and ranges | ||
| 334 | (if (numberp (car ranges)) | ||
| 335 | (>= number (car ranges)) | ||
| 336 | (>= number (caar ranges))) | ||
| 337 | not-stop) | ||
| 338 | (when (if (numberp (car ranges)) | ||
| 339 | (= number (car ranges)) | ||
| 340 | (and (>= number (caar ranges)) | ||
| 341 | (<= number (cdar ranges)))) | ||
| 342 | (setq not-stop nil)) | ||
| 343 | (setq ranges (cdr ranges))) | ||
| 344 | (not not-stop)))) | ||
| 345 | |||
| 346 | (defun range-list-intersection (list ranges) | ||
| 347 | "Return a list of numbers in LIST that are members of RANGES. | ||
| 348 | oLIST is a sorted list." | ||
| 349 | (setq ranges (range-normalize ranges)) | ||
| 350 | (let (number result) | ||
| 351 | (while (setq number (pop list)) | ||
| 352 | (while (and ranges | ||
| 353 | (if (numberp (car ranges)) | ||
| 354 | (< (car ranges) number) | ||
| 355 | (< (cdar ranges) number))) | ||
| 356 | (setq ranges (cdr ranges))) | ||
| 357 | (when (and ranges | ||
| 358 | (if (numberp (car ranges)) | ||
| 359 | (= (car ranges) number) | ||
| 360 | ;; (caar ranges) <= number <= (cdar ranges) | ||
| 361 | (>= number (caar ranges)))) | ||
| 362 | (push number result))) | ||
| 363 | (nreverse result))) | ||
| 364 | |||
| 365 | (defun range-list-difference (list ranges) | ||
| 366 | "Return a list of numbers in LIST that are not members of RANGES. | ||
| 367 | LIST is a sorted list." | ||
| 368 | (setq ranges (range-normalize ranges)) | ||
| 369 | (let (number result) | ||
| 370 | (while (setq number (pop list)) | ||
| 371 | (while (and ranges | ||
| 372 | (if (numberp (car ranges)) | ||
| 373 | (< (car ranges) number) | ||
| 374 | (< (cdar ranges) number))) | ||
| 375 | (setq ranges (cdr ranges))) | ||
| 376 | (when (or (not ranges) | ||
| 377 | (if (numberp (car ranges)) | ||
| 378 | (not (= (car ranges) number)) | ||
| 379 | ;; not ((caar ranges) <= number <= (cdar ranges)) | ||
| 380 | (< number (caar ranges)))) | ||
| 381 | (push number result))) | ||
| 382 | (nreverse result))) | ||
| 383 | |||
| 384 | (defun range-length (range) | ||
| 385 | "Return the length RANGE would have if uncompressed." | ||
| 386 | (cond | ||
| 387 | ((null range) | ||
| 388 | 0) | ||
| 389 | ((not (listp (cdr range))) | ||
| 390 | (- (cdr range) (car range) -1)) | ||
| 391 | (t | ||
| 392 | (let ((sum 0)) | ||
| 393 | (dolist (x range sum) | ||
| 394 | (setq sum | ||
| 395 | (+ sum (if (consp x) (- (cdr x) (car x) -1) 1)))))))) | ||
| 396 | |||
| 397 | (defun range-concat (range1 range2) | ||
| 398 | "Add RANGE2 to RANGE1 (nondestructively)." | ||
| 399 | (unless (listp (cdr range1)) | ||
| 400 | (setq range1 (list range1))) | ||
| 401 | (unless (listp (cdr range2)) | ||
| 402 | (setq range2 (list range2))) | ||
| 403 | (let ((item1 (pop range1)) | ||
| 404 | (item2 (pop range2)) | ||
| 405 | range item selector) | ||
| 406 | (while (or item1 item2) | ||
| 407 | (setq selector | ||
| 408 | (cond | ||
| 409 | ((null item1) nil) | ||
| 410 | ((null item2) t) | ||
| 411 | ((and (numberp item1) (numberp item2)) (< item1 item2)) | ||
| 412 | ((numberp item1) (< item1 (car item2))) | ||
| 413 | ((numberp item2) (< (car item1) item2)) | ||
| 414 | (t (< (car item1) (car item2))))) | ||
| 415 | (setq item | ||
| 416 | (or | ||
| 417 | (let ((tmp1 item) (tmp2 (if selector item1 item2))) | ||
| 418 | (cond | ||
| 419 | ((null tmp1) tmp2) | ||
| 420 | ((null tmp2) tmp1) | ||
| 421 | ((and (numberp tmp1) (numberp tmp2)) | ||
| 422 | (cond | ||
| 423 | ((eq tmp1 tmp2) tmp1) | ||
| 424 | ((eq (1+ tmp1) tmp2) (cons tmp1 tmp2)) | ||
| 425 | ((eq (1+ tmp2) tmp1) (cons tmp2 tmp1)) | ||
| 426 | (t nil))) | ||
| 427 | ((numberp tmp1) | ||
| 428 | (cond | ||
| 429 | ((and (>= tmp1 (car tmp2)) (<= tmp1 (cdr tmp2))) tmp2) | ||
| 430 | ((eq (1+ tmp1) (car tmp2)) (cons tmp1 (cdr tmp2))) | ||
| 431 | ((eq (1- tmp1) (cdr tmp2)) (cons (car tmp2) tmp1)) | ||
| 432 | (t nil))) | ||
| 433 | ((numberp tmp2) | ||
| 434 | (cond | ||
| 435 | ((and (>= tmp2 (car tmp1)) (<= tmp2 (cdr tmp1))) tmp1) | ||
| 436 | ((eq (1+ tmp2) (car tmp1)) (cons tmp2 (cdr tmp1))) | ||
| 437 | ((eq (1- tmp2) (cdr tmp1)) (cons (car tmp1) tmp2)) | ||
| 438 | (t nil))) | ||
| 439 | ((< (1+ (cdr tmp1)) (car tmp2)) nil) | ||
| 440 | ((< (1+ (cdr tmp2)) (car tmp1)) nil) | ||
| 441 | (t (cons (min (car tmp1) (car tmp2)) | ||
| 442 | (max (cdr tmp1) (cdr tmp2)))))) | ||
| 443 | (progn | ||
| 444 | (if item (push item range)) | ||
| 445 | (if selector item1 item2)))) | ||
| 446 | (if selector | ||
| 447 | (setq item1 (pop range1)) | ||
| 448 | (setq item2 (pop range2)))) | ||
| 449 | (if item (push item range)) | ||
| 450 | (reverse range))) | ||
| 451 | |||
| 452 | (defun range-map (func range) | ||
| 453 | "Apply FUNC to each value contained by RANGE." | ||
| 454 | (setq range (range-normalize range)) | ||
| 455 | (while range | ||
| 456 | (let ((span (pop range))) | ||
| 457 | (if (numberp span) | ||
| 458 | (funcall func span) | ||
| 459 | (let ((first (car span)) | ||
| 460 | (last (cdr span))) | ||
| 461 | (while (<= first last) | ||
| 462 | (funcall func first) | ||
| 463 | (setq first (1+ first)))))))) | ||
| 464 | |||
| 465 | (provide 'range) | ||
| 466 | |||
| 467 | ;;; range.el ends here | ||
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el index fd66135b5c6..e4704b35c8d 100644 --- a/lisp/gnus/gnus-agent.el +++ b/lisp/gnus/gnus-agent.el | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | (require 'gnus-srvr) | 31 | (require 'gnus-srvr) |
| 32 | (require 'gnus-util) | 32 | (require 'gnus-util) |
| 33 | (require 'timer) | 33 | (require 'timer) |
| 34 | (require 'range) | ||
| 34 | (eval-when-compile (require 'cl-lib)) | 35 | (eval-when-compile (require 'cl-lib)) |
| 35 | 36 | ||
| 36 | (autoload 'gnus-server-update-server "gnus-srvr") | 37 | (autoload 'gnus-server-update-server "gnus-srvr") |
| @@ -1219,8 +1220,8 @@ This can be added to `gnus-select-article-hook' or | |||
| 1219 | (cond ((eq mark 'read) | 1220 | (cond ((eq mark 'read) |
| 1220 | (setf (gnus-info-read info) | 1221 | (setf (gnus-info-read info) |
| 1221 | (funcall (if (eq what 'add) | 1222 | (funcall (if (eq what 'add) |
| 1222 | #'gnus-range-add | 1223 | #'range-concat |
| 1223 | #'gnus-remove-from-range) | 1224 | #'range-remove) |
| 1224 | (gnus-info-read info) | 1225 | (gnus-info-read info) |
| 1225 | range)) | 1226 | range)) |
| 1226 | (gnus-get-unread-articles-in-group | 1227 | (gnus-get-unread-articles-in-group |
| @@ -1233,8 +1234,8 @@ This can be added to `gnus-select-article-hook' or | |||
| 1233 | (gnus-info-marks info))) | 1234 | (gnus-info-marks info))) |
| 1234 | (setcdr info-marks | 1235 | (setcdr info-marks |
| 1235 | (funcall (if (eq what 'add) | 1236 | (funcall (if (eq what 'add) |
| 1236 | #'gnus-range-add | 1237 | #'range-concat |
| 1237 | #'gnus-remove-from-range) | 1238 | #'range-remove) |
| 1238 | (cdr info-marks) | 1239 | (cdr info-marks) |
| 1239 | range)))))))) | 1240 | range)))))))) |
| 1240 | 1241 | ||
| @@ -1307,7 +1308,7 @@ downloaded into the agent." | |||
| 1307 | 1308 | ||
| 1308 | (let ((read (gnus-info-read info))) | 1309 | (let ((read (gnus-info-read info))) |
| 1309 | (setf (gnus-info-read info) | 1310 | (setf (gnus-info-read info) |
| 1310 | (gnus-range-add | 1311 | (range-concat |
| 1311 | read | 1312 | read |
| 1312 | (list (cons (1+ agent-max) | 1313 | (list (cons (1+ agent-max) |
| 1313 | (1- active-min)))))) | 1314 | (1- active-min)))))) |
| @@ -1796,13 +1797,13 @@ article numbers will be returned." | |||
| 1796 | (articles (if fetch-all | 1797 | (articles (if fetch-all |
| 1797 | (if gnus-newsgroup-maximum-articles | 1798 | (if gnus-newsgroup-maximum-articles |
| 1798 | (let ((active (gnus-active group))) | 1799 | (let ((active (gnus-active group))) |
| 1799 | (gnus-uncompress-range | 1800 | (range-uncompress |
| 1800 | (cons (max (car active) | 1801 | (cons (max (car active) |
| 1801 | (- (cdr active) | 1802 | (- (cdr active) |
| 1802 | gnus-newsgroup-maximum-articles | 1803 | gnus-newsgroup-maximum-articles |
| 1803 | -1)) | 1804 | -1)) |
| 1804 | (cdr active)))) | 1805 | (cdr active)))) |
| 1805 | (gnus-uncompress-range (gnus-active group))) | 1806 | (range-uncompress (gnus-active group))) |
| 1806 | (gnus-list-of-unread-articles group))) | 1807 | (gnus-list-of-unread-articles group))) |
| 1807 | (gnus-decode-encoded-word-function 'identity) | 1808 | (gnus-decode-encoded-word-function 'identity) |
| 1808 | (gnus-decode-encoded-address-function 'identity) | 1809 | (gnus-decode-encoded-address-function 'identity) |
| @@ -1817,7 +1818,7 @@ article numbers will be returned." | |||
| 1817 | ;; because otherwise the agent will remove their marks.) | 1818 | ;; because otherwise the agent will remove their marks.) |
| 1818 | (dolist (arts (gnus-info-marks (gnus-get-info group))) | 1819 | (dolist (arts (gnus-info-marks (gnus-get-info group))) |
| 1819 | (unless (memq (car arts) '(seen recent killed cache)) | 1820 | (unless (memq (car arts) '(seen recent killed cache)) |
| 1820 | (setq articles (gnus-range-add articles (cdr arts))))) | 1821 | (setq articles (range-concat articles (cdr arts))))) |
| 1821 | (setq articles (sort (gnus-uncompress-sequence articles) #'<))) | 1822 | (setq articles (sort (gnus-uncompress-sequence articles) #'<))) |
| 1822 | 1823 | ||
| 1823 | ;; At this point, I have the list of articles to consider for | 1824 | ;; At this point, I have the list of articles to consider for |
| @@ -1851,15 +1852,15 @@ article numbers will be returned." | |||
| 1851 | ;; gnus-agent-article-alist) equals (cdr (gnus-active | 1852 | ;; gnus-agent-article-alist) equals (cdr (gnus-active |
| 1852 | ;; group))}. The addition of one(the 1+ above) then | 1853 | ;; group))}. The addition of one(the 1+ above) then |
| 1853 | ;; forces Low to be greater than High. When this happens, | 1854 | ;; forces Low to be greater than High. When this happens, |
| 1854 | ;; gnus-list-range-intersection returns nil which | 1855 | ;; range-list-intersection returns nil which |
| 1855 | ;; indicates that no headers need to be fetched. -- Kevin | 1856 | ;; indicates that no headers need to be fetched. -- Kevin |
| 1856 | (setq articles (gnus-list-range-intersection | 1857 | (setq articles (range-list-intersection |
| 1857 | articles (list (cons low high))))))) | 1858 | articles (list (cons low high))))))) |
| 1858 | 1859 | ||
| 1859 | (when articles | 1860 | (when articles |
| 1860 | (gnus-message | 1861 | (gnus-message |
| 1861 | 10 "gnus-agent-fetch-headers: undownloaded articles are `%s'" | 1862 | 10 "gnus-agent-fetch-headers: undownloaded articles are `%s'" |
| 1862 | (gnus-compress-sequence articles t))) | 1863 | (range-compress-list articles))) |
| 1863 | 1864 | ||
| 1864 | (with-current-buffer nntp-server-buffer | 1865 | (with-current-buffer nntp-server-buffer |
| 1865 | (if articles | 1866 | (if articles |
| @@ -2060,7 +2061,7 @@ doesn't exist, to valid the overview buffer." | |||
| 2060 | (let (state sequence uncomp) | 2061 | (let (state sequence uncomp) |
| 2061 | (while alist | 2062 | (while alist |
| 2062 | (setq state (caar alist) | 2063 | (setq state (caar alist) |
| 2063 | sequence (inline (gnus-uncompress-range (cdar alist))) | 2064 | sequence (inline (range-uncompress (cdar alist))) |
| 2064 | alist (cdr alist)) | 2065 | alist (cdr alist)) |
| 2065 | (while sequence | 2066 | (while sequence |
| 2066 | (push (cons (pop sequence) state) uncomp))) | 2067 | (push (cons (pop sequence) state) uncomp))) |
| @@ -2404,7 +2405,7 @@ contents, they are first saved to their own file." | |||
| 2404 | (let ((arts (cdr (assq mark (gnus-info-marks | 2405 | (let ((arts (cdr (assq mark (gnus-info-marks |
| 2405 | (setq info (gnus-get-info group))))))) | 2406 | (setq info (gnus-get-info group))))))) |
| 2406 | (when arts | 2407 | (when arts |
| 2407 | (setq marked-articles (nconc (gnus-uncompress-range arts) | 2408 | (setq marked-articles (nconc (range-uncompress arts) |
| 2408 | marked-articles)) | 2409 | marked-articles)) |
| 2409 | )))) | 2410 | )))) |
| 2410 | (setq marked-articles (sort marked-articles #'<)) | 2411 | (setq marked-articles (sort marked-articles #'<)) |
| @@ -2544,7 +2545,7 @@ contents, they are first saved to their own file." | |||
| 2544 | (let ((read (gnus-info-read | 2545 | (let ((read (gnus-info-read |
| 2545 | (or info (setq info (gnus-get-info group)))))) | 2546 | (or info (setq info (gnus-get-info group)))))) |
| 2546 | (setf (gnus-info-read info) | 2547 | (setf (gnus-info-read info) |
| 2547 | (gnus-add-to-range read unfetched-articles))) | 2548 | (range-add-list read unfetched-articles))) |
| 2548 | 2549 | ||
| 2549 | (gnus-group-update-group group t) | 2550 | (gnus-group-update-group group t) |
| 2550 | (sit-for 0) | 2551 | (sit-for 0) |
| @@ -2898,8 +2899,8 @@ The following commands are available: | |||
| 2898 | 2899 | ||
| 2899 | (defun gnus-agent-read-p () | 2900 | (defun gnus-agent-read-p () |
| 2900 | "Say whether an article is read or not." | 2901 | "Say whether an article is read or not." |
| 2901 | (gnus-member-of-range (mail-header-number gnus-headers) | 2902 | (range-member-p (mail-header-number gnus-headers) |
| 2902 | (gnus-info-read (gnus-get-info gnus-newsgroup-name)))) | 2903 | (gnus-info-read (gnus-get-info gnus-newsgroup-name)))) |
| 2903 | 2904 | ||
| 2904 | (defun gnus-category-make-function (predicate) | 2905 | (defun gnus-category-make-function (predicate) |
| 2905 | "Make a function from PREDICATE." | 2906 | "Make a function from PREDICATE." |
| @@ -3115,7 +3116,7 @@ FORCE is equivalent to setting the expiration predicates to true." | |||
| 3115 | ;; All articles EXCEPT those named by the caller | 3116 | ;; All articles EXCEPT those named by the caller |
| 3116 | ;; are protected from expiration | 3117 | ;; are protected from expiration |
| 3117 | (gnus-sorted-difference | 3118 | (gnus-sorted-difference |
| 3118 | (gnus-uncompress-range | 3119 | (range-uncompress |
| 3119 | (cons (caar alist) | 3120 | (cons (caar alist) |
| 3120 | (caar (last alist)))) | 3121 | (caar (last alist)))) |
| 3121 | (sort articles #'<))))) | 3122 | (sort articles #'<))))) |
| @@ -3137,9 +3138,9 @@ FORCE is equivalent to setting the expiration predicates to true." | |||
| 3137 | ;; Ticked and/or dormant articles are excluded | 3138 | ;; Ticked and/or dormant articles are excluded |
| 3138 | ;; from expiration | 3139 | ;; from expiration |
| 3139 | (nconc | 3140 | (nconc |
| 3140 | (gnus-uncompress-range | 3141 | (range-uncompress |
| 3141 | (cdr (assq 'tick (gnus-info-marks info)))) | 3142 | (cdr (assq 'tick (gnus-info-marks info)))) |
| 3142 | (gnus-uncompress-range | 3143 | (range-uncompress |
| 3143 | (cdr (assq 'dormant | 3144 | (cdr (assq 'dormant |
| 3144 | (gnus-info-marks info)))))))) | 3145 | (gnus-info-marks info)))))))) |
| 3145 | (nov-file (concat dir ".overview")) | 3146 | (nov-file (concat dir ".overview")) |
| @@ -3638,7 +3639,7 @@ has been fetched." | |||
| 3638 | (file-name-directory file) t)) | 3639 | (file-name-directory file) t)) |
| 3639 | 3640 | ||
| 3640 | (when fetch-old | 3641 | (when fetch-old |
| 3641 | (setq articles (gnus-uncompress-range | 3642 | (setq articles (range-uncompress |
| 3642 | (cons (if (numberp fetch-old) | 3643 | (cons (if (numberp fetch-old) |
| 3643 | (max 1 (- (car articles) fetch-old)) | 3644 | (max 1 (- (car articles) fetch-old)) |
| 3644 | 1) | 3645 | 1) |
| @@ -3694,7 +3695,7 @@ has been fetched." | |||
| 3694 | 3695 | ||
| 3695 | ;; Clip this list to the headers that will | 3696 | ;; Clip this list to the headers that will |
| 3696 | ;; actually be returned | 3697 | ;; actually be returned |
| 3697 | (setq fetched-articles (gnus-list-range-intersection | 3698 | (setq fetched-articles (range-list-intersection |
| 3698 | (cdr fetched-articles) | 3699 | (cdr fetched-articles) |
| 3699 | (cons min max))) | 3700 | (cons min max))) |
| 3700 | 3701 | ||
| @@ -3703,7 +3704,7 @@ has been fetched." | |||
| 3703 | ;; excluded IDs may be fetchable using HEAD. | 3704 | ;; excluded IDs may be fetchable using HEAD. |
| 3704 | (if (car tail-fetched-articles) | 3705 | (if (car tail-fetched-articles) |
| 3705 | (setq uncached-articles | 3706 | (setq uncached-articles |
| 3706 | (gnus-list-range-intersection | 3707 | (range-list-intersection |
| 3707 | uncached-articles | 3708 | uncached-articles |
| 3708 | (cons (car uncached-articles) | 3709 | (cons (car uncached-articles) |
| 3709 | (car tail-fetched-articles))))) | 3710 | (car tail-fetched-articles))))) |
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index a286c446724..d35d3bdd3a3 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | (require 'message) | 42 | (require 'message) |
| 43 | (require 'mouse) | 43 | (require 'mouse) |
| 44 | (require 'seq) | 44 | (require 'seq) |
| 45 | (require 'range) | ||
| 45 | 46 | ||
| 46 | (autoload 'gnus-msg-mail "gnus-msg" nil t) | 47 | (autoload 'gnus-msg-mail "gnus-msg" nil t) |
| 47 | (autoload 'gnus-button-mailto "gnus-msg") | 48 | (autoload 'gnus-button-mailto "gnus-msg") |
| @@ -7019,7 +7020,7 @@ then we display only bindings that start with that prefix." | |||
| 7019 | (setq sumkeys | 7020 | (setq sumkeys |
| 7020 | (append (mapcar | 7021 | (append (mapcar |
| 7021 | #'vector | 7022 | #'vector |
| 7022 | (nreverse (gnus-uncompress-range def))) | 7023 | (nreverse (range-uncompress def))) |
| 7023 | sumkeys)))) | 7024 | sumkeys)))) |
| 7024 | ((setq def (key-binding key)) | 7025 | ((setq def (key-binding key)) |
| 7025 | (unless (eq def 'undefined) | 7026 | (unless (eq def 'undefined) |
diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index 6ed9e32c919..9bd9f2155f7 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | (require 'parse-time) | 31 | (require 'parse-time) |
| 32 | (require 'nnimap) | 32 | (require 'nnimap) |
| 33 | (require 'range) | ||
| 33 | 34 | ||
| 34 | (eval-when-compile (require 'epg)) ;; setf-method for `epg-context-armor' | 35 | (eval-when-compile (require 'epg)) ;; setf-method for `epg-context-armor' |
| 35 | (autoload 'epg-make-context "epg") | 36 | (autoload 'epg-make-context "epg") |
| @@ -404,7 +405,7 @@ When FULL is t, upload everything, not just a difference from the last full." | |||
| 404 | (let* ((group (gnus-group-full-name gnus-cloud-group-name gnus-cloud-method)) | 405 | (let* ((group (gnus-group-full-name gnus-cloud-group-name gnus-cloud-method)) |
| 405 | (active (gnus-active group)) | 406 | (active (gnus-active group)) |
| 406 | headers head) | 407 | headers head) |
| 407 | (when (gnus-retrieve-headers (gnus-uncompress-range active) group) | 408 | (when (gnus-retrieve-headers (range-uncompress active) group) |
| 408 | (with-current-buffer nntp-server-buffer | 409 | (with-current-buffer nntp-server-buffer |
| 409 | (goto-char (point-min)) | 410 | (goto-char (point-min)) |
| 410 | (while (setq head (nnheader-parse-head)) | 411 | (while (setq head (nnheader-parse-head)) |
diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el index cd9b025ff0e..56d498cc4d3 100644 --- a/lisp/gnus/gnus-draft.el +++ b/lisp/gnus/gnus-draft.el | |||
| @@ -200,7 +200,7 @@ Obeys the standard process/prefix convention." | |||
| 200 | (gnus-activate-group "nndraft:queue") | 200 | (gnus-activate-group "nndraft:queue") |
| 201 | (save-excursion | 201 | (save-excursion |
| 202 | (let* ((articles (nndraft-articles)) | 202 | (let* ((articles (nndraft-articles)) |
| 203 | (unsendable (gnus-uncompress-range | 203 | (unsendable (range-uncompress |
| 204 | (cdr (assq 'unsend | 204 | (cdr (assq 'unsend |
| 205 | (gnus-info-marks | 205 | (gnus-info-marks |
| 206 | (gnus-get-info "nndraft:queue")))))) | 206 | (gnus-get-info "nndraft:queue")))))) |
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index ab874dd0608..d3a94e9f4e0 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | (require 'gnus-undo) | 35 | (require 'gnus-undo) |
| 36 | (require 'gmm-utils) | 36 | (require 'gmm-utils) |
| 37 | (require 'time-date) | 37 | (require 'time-date) |
| 38 | (require 'range) | ||
| 38 | 39 | ||
| 39 | (eval-when-compile | 40 | (eval-when-compile |
| 40 | (require 'mm-url) | 41 | (require 'mm-url) |
| @@ -512,8 +513,8 @@ simple manner." | |||
| 512 | ((numberp number) | 513 | ((numberp number) |
| 513 | (int-to-string | 514 | (int-to-string |
| 514 | (+ number | 515 | (+ number |
| 515 | (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) | 516 | (range-length (cdr (assq 'dormant gnus-tmp-marked))) |
| 516 | (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))))) | 517 | (range-length (cdr (assq 'tick gnus-tmp-marked)))))) |
| 517 | (t number)) | 518 | (t number)) |
| 518 | ?s) | 519 | ?s) |
| 519 | (?R gnus-tmp-number-of-read ?s) | 520 | (?R gnus-tmp-number-of-read ?s) |
| @@ -523,10 +524,10 @@ simple manner." | |||
| 523 | ?s) | 524 | ?s) |
| 524 | (?t gnus-tmp-number-total ?d) | 525 | (?t gnus-tmp-number-total ?d) |
| 525 | (?y gnus-tmp-number-of-unread ?s) | 526 | (?y gnus-tmp-number-of-unread ?s) |
| 526 | (?I (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d) | 527 | (?I (range-length (cdr (assq 'dormant gnus-tmp-marked))) ?d) |
| 527 | (?T (gnus-range-length (cdr (assq 'tick gnus-tmp-marked))) ?d) | 528 | (?T (range-length (cdr (assq 'tick gnus-tmp-marked))) ?d) |
| 528 | (?i (+ (gnus-range-length (cdr (assq 'dormant gnus-tmp-marked))) | 529 | (?i (+ (range-length (cdr (assq 'dormant gnus-tmp-marked))) |
| 529 | (gnus-range-length (cdr (assq 'tick gnus-tmp-marked)))) | 530 | (range-length (cdr (assq 'tick gnus-tmp-marked)))) |
| 530 | ?d) | 531 | ?d) |
| 531 | (?g gnus-tmp-group ?s) | 532 | (?g gnus-tmp-group ?s) |
| 532 | (?G gnus-tmp-qualified-group ?s) | 533 | (?G gnus-tmp-qualified-group ?s) |
| @@ -1482,9 +1483,9 @@ if it is a string, only list groups matching REGEXP." | |||
| 1482 | (active (gnus-active group))) | 1483 | (active (gnus-active group))) |
| 1483 | (if (not active) | 1484 | (if (not active) |
| 1484 | 0 | 1485 | 0 |
| 1485 | (length (gnus-uncompress-range | 1486 | (length (range-uncompress |
| 1486 | (gnus-range-difference | 1487 | (range-difference |
| 1487 | (gnus-range-difference (list active) (gnus-info-read info)) | 1488 | (range-difference (list active) (gnus-info-read info)) |
| 1488 | seen)))))) | 1489 | seen)))))) |
| 1489 | 1490 | ||
| 1490 | ;; Moving through the Group buffer (in topic mode) e.g. with C-n doesn't | 1491 | ;; Moving through the Group buffer (in topic mode) e.g. with C-n doesn't |
| @@ -1642,7 +1643,7 @@ Some value are bound so the form can use them." | |||
| 1642 | '(mail post-mail)))) | 1643 | '(mail post-mail)))) |
| 1643 | (cons 'level (or (gnus-info-level info) gnus-level-killed)) | 1644 | (cons 'level (or (gnus-info-level info) gnus-level-killed)) |
| 1644 | (cons 'score (or (gnus-info-score info) 0)) | 1645 | (cons 'score (or (gnus-info-score info) 0)) |
| 1645 | (cons 'ticked (gnus-range-length (cdr (assq 'tick marked)))) | 1646 | (cons 'ticked (range-length (cdr (assq 'tick marked)))) |
| 1646 | (cons 'group-age (gnus-group-timestamp-delta group))))) | 1647 | (cons 'group-age (gnus-group-timestamp-delta group))))) |
| 1647 | (while (and list | 1648 | (while (and list |
| 1648 | (not (eval (caar list) env))) | 1649 | (not (eval (caar list) env))) |
| @@ -2065,9 +2066,9 @@ that group." | |||
| 2065 | (- (1+ (cdr active)) (car active))))) | 2066 | (- (1+ (cdr active)) (car active))))) |
| 2066 | (gnus-summary-read-group | 2067 | (gnus-summary-read-group |
| 2067 | group (or all (and (numberp number) | 2068 | group (or all (and (numberp number) |
| 2068 | (zerop (+ number (gnus-range-length | 2069 | (zerop (+ number (range-length |
| 2069 | (cdr (assq 'tick marked))) | 2070 | (cdr (assq 'tick marked))) |
| 2070 | (gnus-range-length | 2071 | (range-length |
| 2071 | (cdr (assq 'dormant marked))))))) | 2072 | (cdr (assq 'dormant marked))))))) |
| 2072 | no-article nil no-display nil select-articles))) | 2073 | no-article nil no-display nil select-articles))) |
| 2073 | 2074 | ||
| @@ -2832,7 +2833,7 @@ according to the expiry settings. Note that this will delete old | |||
| 2832 | not-expirable articles, too." | 2833 | not-expirable articles, too." |
| 2833 | (interactive (list (gnus-group-group-name) current-prefix-arg) | 2834 | (interactive (list (gnus-group-group-name) current-prefix-arg) |
| 2834 | gnus-group-mode) | 2835 | gnus-group-mode) |
| 2835 | (let ((articles (gnus-uncompress-range (gnus-active group)))) | 2836 | (let ((articles (range-uncompress (gnus-active group)))) |
| 2836 | (when (gnus-yes-or-no-p | 2837 | (when (gnus-yes-or-no-p |
| 2837 | (format "Do you really want to delete these %d articles forever? " | 2838 | (format "Do you really want to delete these %d articles forever? " |
| 2838 | (length articles))) | 2839 | (length articles))) |
| @@ -3755,15 +3756,15 @@ or nil if no action could be taken." | |||
| 3755 | 'del '(tick)) | 3756 | 'del '(tick)) |
| 3756 | (list (cdr (assq 'dormant marks)) | 3757 | (list (cdr (assq 'dormant marks)) |
| 3757 | 'del '(dormant)))) | 3758 | 'del '(dormant)))) |
| 3758 | (setq unread (gnus-range-add (gnus-range-add | 3759 | (setq unread (range-concat (range-concat |
| 3759 | unread (cdr (assq 'dormant marks))) | 3760 | unread (cdr (assq 'dormant marks))) |
| 3760 | (cdr (assq 'tick marks)))) | 3761 | (cdr (assq 'tick marks)))) |
| 3761 | (gnus-add-marked-articles group 'tick nil nil 'force) | 3762 | (gnus-add-marked-articles group 'tick nil nil 'force) |
| 3762 | (gnus-add-marked-articles group 'dormant nil nil 'force)) | 3763 | (gnus-add-marked-articles group 'dormant nil nil 'force)) |
| 3763 | ;; Do auto-expirable marks if that's required. | 3764 | ;; Do auto-expirable marks if that's required. |
| 3764 | (when (and (gnus-group-auto-expirable-p group) | 3765 | (when (and (gnus-group-auto-expirable-p group) |
| 3765 | (not (gnus-group-read-only-p group))) | 3766 | (not (gnus-group-read-only-p group))) |
| 3766 | (gnus-range-map | 3767 | (range-map |
| 3767 | (lambda (article) | 3768 | (lambda (article) |
| 3768 | (gnus-add-marked-articles group 'expire (list article)) | 3769 | (gnus-add-marked-articles group 'expire (list article)) |
| 3769 | (gnus-request-set-mark group (list (list (list article) | 3770 | (gnus-request-set-mark group (list (list (list article) |
| @@ -3795,7 +3796,7 @@ Uses the process/prefix convention." | |||
| 3795 | (cons nil (gnus-list-of-read-articles group)) | 3796 | (cons nil (gnus-list-of-read-articles group)) |
| 3796 | (assq 'expire (gnus-info-marks info)))) | 3797 | (assq 'expire (gnus-info-marks info)))) |
| 3797 | (articles-to-expire | 3798 | (articles-to-expire |
| 3798 | (gnus-list-range-difference | 3799 | (range-list-difference |
| 3799 | (gnus-uncompress-sequence (cdr expirable)) | 3800 | (gnus-uncompress-sequence (cdr expirable)) |
| 3800 | (cdr (assq 'unexist (gnus-info-marks info))))) | 3801 | (cdr (assq 'unexist (gnus-info-marks info))))) |
| 3801 | (expiry-wait (gnus-group-find-parameter group 'expiry-wait)) | 3802 | (expiry-wait (gnus-group-find-parameter group 'expiry-wait)) |
| @@ -4671,23 +4672,22 @@ and the second element is the address." | |||
| 4671 | (and (not (setq marked (nthcdr 3 info))) | 4672 | (and (not (setq marked (nthcdr 3 info))) |
| 4672 | (or (null articles) | 4673 | (or (null articles) |
| 4673 | (setcdr (nthcdr 2 info) | 4674 | (setcdr (nthcdr 2 info) |
| 4674 | (list (list (cons type (gnus-compress-sequence | 4675 | (list (list (cons type (range-compress-list |
| 4675 | articles t))))))) | 4676 | articles))))))) |
| 4676 | (and (not (setq m (assq type (car marked)))) | 4677 | (and (not (setq m (assq type (car marked)))) |
| 4677 | (or (null articles) | 4678 | (or (null articles) |
| 4678 | (setcar marked | 4679 | (setcar marked |
| 4679 | (cons (cons type (gnus-compress-sequence articles t) ) | 4680 | (cons (cons type (range-compress-list articles)) |
| 4680 | (car marked))))) | 4681 | (car marked))))) |
| 4681 | (if force | 4682 | (if force |
| 4682 | (if (null articles) | 4683 | (if (null articles) |
| 4683 | (setcar (nthcdr 3 info) | 4684 | (setcar (nthcdr 3 info) |
| 4684 | (assq-delete-all type (car marked))) | 4685 | (assq-delete-all type (car marked))) |
| 4685 | (setcdr m (gnus-compress-sequence articles t))) | 4686 | (setcdr m (range-compress-list articles))) |
| 4686 | (setcdr m (gnus-compress-sequence | 4687 | (setcdr m (range-compress-list |
| 4687 | (sort (nconc (gnus-uncompress-range (cdr m)) | 4688 | (sort (nconc (range-uncompress (cdr m)) |
| 4688 | (copy-sequence articles)) | 4689 | (copy-sequence articles)) |
| 4689 | #'<) | 4690 | #'<))))))) |
| 4690 | t)))))) | ||
| 4691 | 4691 | ||
| 4692 | (declare-function gnus-summary-add-mark "gnus-sum" (article type)) | 4692 | (declare-function gnus-summary-add-mark "gnus-sum" (article type)) |
| 4693 | 4693 | ||
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 5a619e8f07b..f00f2a0d04e 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el | |||
| @@ -802,7 +802,7 @@ If GROUP is nil, all groups on COMMAND-METHOD are scanned." | |||
| 802 | (when (> min 1) | 802 | (when (> min 1) |
| 803 | (let* ((range (if (= min 2) 1 (cons 1 (1- min)))) | 803 | (let* ((range (if (= min 2) 1 (cons 1 (1- min)))) |
| 804 | (read (gnus-info-read info)) | 804 | (read (gnus-info-read info)) |
| 805 | (new-read (gnus-range-add read (list range)))) | 805 | (new-read (range-concat read (list range)))) |
| 806 | (setf (gnus-info-read info) new-read))) | 806 | (setf (gnus-info-read info) new-read))) |
| 807 | info)))))) | 807 | info)))))) |
| 808 | 808 | ||
diff --git a/lisp/gnus/gnus-kill.el b/lisp/gnus/gnus-kill.el index bee7860efdb..bc49f8385ea 100644 --- a/lisp/gnus/gnus-kill.el +++ b/lisp/gnus/gnus-kill.el | |||
| @@ -349,7 +349,7 @@ Returns the number of articles marked as read." | |||
| 349 | (setq gnus-newsgroup-kill-headers | 349 | (setq gnus-newsgroup-kill-headers |
| 350 | (mapcar #'mail-header-number headers)) | 350 | (mapcar #'mail-header-number headers)) |
| 351 | (while headers | 351 | (while headers |
| 352 | (unless (gnus-member-of-range | 352 | (unless (range-member-p |
| 353 | (mail-header-number (car headers)) | 353 | (mail-header-number (car headers)) |
| 354 | gnus-newsgroup-killed) | 354 | gnus-newsgroup-killed) |
| 355 | (push (mail-header-number (car headers)) | 355 | (push (mail-header-number (car headers)) |
diff --git a/lisp/gnus/gnus-range.el b/lisp/gnus/gnus-range.el index da3ff473725..23a71bda209 100644 --- a/lisp/gnus/gnus-range.el +++ b/lisp/gnus/gnus-range.el | |||
| @@ -26,10 +26,8 @@ | |||
| 26 | 26 | ||
| 27 | ;;; List and range functions | 27 | ;;; List and range functions |
| 28 | 28 | ||
| 29 | (defsubst gnus-range-normalize (range) | 29 | (require 'range) |
| 30 | "Normalize RANGE. | 30 | (define-obsolete-function-alias 'gnus-range-normalize #'range-normalize "29.1") |
| 31 | If RANGE is a single range, return (RANGE). Otherwise, return RANGE." | ||
| 32 | (if (listp (cdr-safe range)) range (list range))) | ||
| 33 | 31 | ||
| 34 | (defun gnus-last-element (list) | 32 | (defun gnus-last-element (list) |
| 35 | "Return last element of LIST." | 33 | "Return last element of LIST." |
| @@ -56,10 +54,10 @@ If RANGE is a single range, return (RANGE). Otherwise, return RANGE." | |||
| 56 | "Return a range comprising all the RANGES, which are pre-sorted. | 54 | "Return a range comprising all the RANGES, which are pre-sorted. |
| 57 | RANGES will be destructively altered." | 55 | RANGES will be destructively altered." |
| 58 | (setq ranges (delete nil ranges)) | 56 | (setq ranges (delete nil ranges)) |
| 59 | (let* ((result (gnus-range-normalize (pop ranges))) | 57 | (let* ((result (range-normalize (pop ranges))) |
| 60 | (last (last result))) | 58 | (last (last result))) |
| 61 | (dolist (range ranges) | 59 | (dolist (range ranges) |
| 62 | (setq range (gnus-range-normalize range)) | 60 | (setq range (range-normalize range)) |
| 63 | ;; Normalize the single-number case, so that we don't need to | 61 | ;; Normalize the single-number case, so that we don't need to |
| 64 | ;; special-case that so much. | 62 | ;; special-case that so much. |
| 65 | (when (numberp (car last)) | 63 | (when (numberp (car last)) |
| @@ -82,47 +80,8 @@ RANGES will be destructively altered." | |||
| 82 | (car result) | 80 | (car result) |
| 83 | result))) | 81 | result))) |
| 84 | 82 | ||
| 85 | (defun gnus-range-difference (range1 range2) | 83 | (define-obsolete-function-alias 'gnus-range-difference |
| 86 | "Return the range of elements in RANGE1 that do not appear in RANGE2. | 84 | #'range-difference "29.1") |
| 87 | Both ranges must be in ascending order." | ||
| 88 | (setq range1 (gnus-range-normalize range1)) | ||
| 89 | (setq range2 (gnus-range-normalize range2)) | ||
| 90 | (let* ((new-range (cons nil (copy-sequence range1))) | ||
| 91 | (r new-range) | ||
| 92 | ) ;; (safe t) | ||
| 93 | (while (cdr r) | ||
| 94 | (let* ((r1 (cadr r)) | ||
| 95 | (r2 (car range2)) | ||
| 96 | (min1 (if (numberp r1) r1 (car r1))) | ||
| 97 | (max1 (if (numberp r1) r1 (cdr r1))) | ||
| 98 | (min2 (if (numberp r2) r2 (car r2))) | ||
| 99 | (max2 (if (numberp r2) r2 (cdr r2)))) | ||
| 100 | |||
| 101 | (cond ((> min1 max1) | ||
| 102 | ;; Invalid range: may result from overlap condition (below) | ||
| 103 | ;; remove Invalid range | ||
| 104 | (setcdr r (cddr r))) | ||
| 105 | ((and (= min1 max1) | ||
| 106 | (listp r1)) | ||
| 107 | ;; Inefficient representation: may result from overlap condition (below) | ||
| 108 | (setcar (cdr r) min1)) | ||
| 109 | ((not min2) | ||
| 110 | ;; All done with range2 | ||
| 111 | (setq r nil)) | ||
| 112 | ((< max1 min2) | ||
| 113 | ;; No overlap: range1 precedes range2 | ||
| 114 | (pop r)) | ||
| 115 | ((< max2 min1) | ||
| 116 | ;; No overlap: range2 precedes range1 | ||
| 117 | (pop range2)) | ||
| 118 | ((and (<= min2 min1) (<= max1 max2)) | ||
| 119 | ;; Complete overlap: range1 removed | ||
| 120 | (setcdr r (cddr r))) | ||
| 121 | (t | ||
| 122 | (setcdr r (nconc (list (cons min1 (1- min2)) (cons (1+ max2) max1)) (cddr r))))))) | ||
| 123 | (cdr new-range))) | ||
| 124 | |||
| 125 | |||
| 126 | 85 | ||
| 127 | ;;;###autoload | 86 | ;;;###autoload |
| 128 | (defun gnus-sorted-difference (list1 list2) | 87 | (defun gnus-sorted-difference (list1 list2) |
| @@ -200,57 +159,8 @@ LIST1 and LIST2 have to be sorted over <." | |||
| 200 | (setq list2 (cdr list2))))) | 159 | (setq list2 (cdr list2))))) |
| 201 | (nreverse out))) | 160 | (nreverse out))) |
| 202 | 161 | ||
| 203 | ;;;###autoload | 162 | (define-obsolete-function-alias 'gnus-sorted-range-intersection |
| 204 | (defun gnus-sorted-range-intersection (range1 range2) | 163 | #'range-intersection "29.1") |
| 205 | "Return intersection of RANGE1 and RANGE2. | ||
| 206 | RANGE1 and RANGE2 have to be sorted over <." | ||
| 207 | (let* (out | ||
| 208 | (min1 (car range1)) | ||
| 209 | (max1 (if (numberp min1) | ||
| 210 | (if (numberp (cdr range1)) | ||
| 211 | (prog1 (cdr range1) | ||
| 212 | (setq range1 nil)) min1) | ||
| 213 | (prog1 (cdr min1) | ||
| 214 | (setq min1 (car min1))))) | ||
| 215 | (min2 (car range2)) | ||
| 216 | (max2 (if (numberp min2) | ||
| 217 | (if (numberp (cdr range2)) | ||
| 218 | (prog1 (cdr range2) | ||
| 219 | (setq range2 nil)) min2) | ||
| 220 | (prog1 (cdr min2) | ||
| 221 | (setq min2 (car min2)))))) | ||
| 222 | (setq range1 (cdr range1) | ||
| 223 | range2 (cdr range2)) | ||
| 224 | (while (and min1 min2) | ||
| 225 | (cond ((< max1 min2) ; range1 precedes range2 | ||
| 226 | (setq range1 (cdr range1) | ||
| 227 | min1 nil)) | ||
| 228 | ((< max2 min1) ; range2 precedes range1 | ||
| 229 | (setq range2 (cdr range2) | ||
| 230 | min2 nil)) | ||
| 231 | (t ; some sort of overlap is occurring | ||
| 232 | (let ((min (max min1 min2)) | ||
| 233 | (max (min max1 max2))) | ||
| 234 | (setq out (if (= min max) | ||
| 235 | (cons min out) | ||
| 236 | (cons (cons min max) out)))) | ||
| 237 | (if (< max1 max2) ; range1 ends before range2 | ||
| 238 | (setq min1 nil) ; incr range1 | ||
| 239 | (setq min2 nil)))) ; incr range2 | ||
| 240 | (unless min1 | ||
| 241 | (setq min1 (car range1) | ||
| 242 | max1 (if (numberp min1) min1 (prog1 (cdr min1) (setq min1 (car min1)))) | ||
| 243 | range1 (cdr range1))) | ||
| 244 | (unless min2 | ||
| 245 | (setq min2 (car range2) | ||
| 246 | max2 (if (numberp min2) min2 (prog1 (cdr min2) (setq min2 (car min2)))) | ||
| 247 | range2 (cdr range2)))) | ||
| 248 | (cond ((cdr out) | ||
| 249 | (nreverse out)) | ||
| 250 | ((numberp (car out)) | ||
| 251 | out) | ||
| 252 | (t | ||
| 253 | (car out))))) | ||
| 254 | 164 | ||
| 255 | ;;;###autoload | 165 | ;;;###autoload |
| 256 | (defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection) | 166 | (defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection) |
| @@ -327,315 +237,33 @@ LIST1 and LIST2 have to be sorted over <." | |||
| 327 | "Convert sorted list of numbers to a list of ranges or a single range. | 237 | "Convert sorted list of numbers to a list of ranges or a single range. |
| 328 | If ALWAYS-LIST is non-nil, this function will always release a list of | 238 | If ALWAYS-LIST is non-nil, this function will always release a list of |
| 329 | ranges." | 239 | ranges." |
| 330 | (let* ((first (car numbers)) | 240 | (if always-list |
| 331 | (last (car numbers)) | 241 | (range-compress-list numbers) |
| 332 | result) | 242 | (range-denormalize (range-compress-list numbers)))) |
| 333 | (if (null numbers) | ||
| 334 | nil | ||
| 335 | (if (not (listp (cdr numbers))) | ||
| 336 | numbers | ||
| 337 | (while numbers | ||
| 338 | (cond ((= last (car numbers)) nil) ;Omit duplicated number | ||
| 339 | ((= (1+ last) (car numbers)) ;Still in sequence | ||
| 340 | (setq last (car numbers))) | ||
| 341 | (t ;End of one sequence | ||
| 342 | (setq result | ||
| 343 | (cons (if (= first last) first | ||
| 344 | (cons first last)) | ||
| 345 | result)) | ||
| 346 | (setq first (car numbers)) | ||
| 347 | (setq last (car numbers)))) | ||
| 348 | (setq numbers (cdr numbers))) | ||
| 349 | (if (and (not always-list) (null result)) | ||
| 350 | (if (= first last) (list first) (cons first last)) | ||
| 351 | (nreverse (cons (if (= first last) first (cons first last)) | ||
| 352 | result))))))) | ||
| 353 | 243 | ||
| 354 | (defalias 'gnus-uncompress-sequence 'gnus-uncompress-range) | 244 | (defalias 'gnus-uncompress-sequence 'gnus-uncompress-range) |
| 355 | (defun gnus-uncompress-range (ranges) | 245 | (define-obsolete-function-alias 'gnus-uncompress-range |
| 356 | "Expand a list of ranges into a list of numbers. | 246 | #'range-uncompress "29.1") |
| 357 | RANGES is either a single range on the form `(num . num)' or a list of | 247 | |
| 358 | these ranges." | 248 | (define-obsolete-function-alias 'gnus-add-to-range |
| 359 | (let (first last result) | 249 | #'range-add-list "29.1") |
| 360 | (cond | 250 | |
| 361 | ((null ranges) | 251 | (define-obsolete-function-alias 'gnus-remove-from-range |
| 362 | nil) | 252 | #'range-remove "29.1") |
| 363 | ((not (listp (cdr ranges))) | 253 | |
| 364 | (setq first (car ranges)) | 254 | (define-obsolete-function-alias 'gnus-member-of-range #'range-member-p "29.1") |
| 365 | (setq last (cdr ranges)) | 255 | |
| 366 | (while (<= first last) | 256 | (define-obsolete-function-alias 'gnus-list-range-intersection |
| 367 | (setq result (cons first result)) | 257 | #'range-list-intersection "29.1") |
| 368 | (setq first (1+ first))) | ||
| 369 | (nreverse result)) | ||
| 370 | (t | ||
| 371 | (while ranges | ||
| 372 | (if (atom (car ranges)) | ||
| 373 | (when (numberp (car ranges)) | ||
| 374 | (setq result (cons (car ranges) result))) | ||
| 375 | (setq first (caar ranges)) | ||
| 376 | (setq last (cdar ranges)) | ||
| 377 | (while (<= first last) | ||
| 378 | (setq result (cons first result)) | ||
| 379 | (setq first (1+ first)))) | ||
| 380 | (setq ranges (cdr ranges))) | ||
| 381 | (nreverse result))))) | ||
| 382 | |||
| 383 | (defun gnus-add-to-range (ranges list) | ||
| 384 | "Return a list of ranges that has all articles from both RANGES and LIST. | ||
| 385 | Note: LIST has to be sorted over `<'." | ||
| 386 | (if (not ranges) | ||
| 387 | (gnus-compress-sequence list t) | ||
| 388 | (setq list (copy-sequence list)) | ||
| 389 | (unless (listp (cdr ranges)) | ||
| 390 | (setq ranges (list ranges))) | ||
| 391 | (let ((out ranges) | ||
| 392 | ilist lowest highest temp) | ||
| 393 | (while (and ranges list) | ||
| 394 | (setq ilist list) | ||
| 395 | (setq lowest (or (and (atom (car ranges)) (car ranges)) | ||
| 396 | (caar ranges))) | ||
| 397 | (while (and list (cdr list) (< (cadr list) lowest)) | ||
| 398 | (setq list (cdr list))) | ||
| 399 | (when (< (car ilist) lowest) | ||
| 400 | (setq temp list) | ||
| 401 | (setq list (cdr list)) | ||
| 402 | (setcdr temp nil) | ||
| 403 | (setq out (nconc (gnus-compress-sequence ilist t) out))) | ||
| 404 | (setq highest (or (and (atom (car ranges)) (car ranges)) | ||
| 405 | (cdar ranges))) | ||
| 406 | (while (and list (<= (car list) highest)) | ||
| 407 | (setq list (cdr list))) | ||
| 408 | (setq ranges (cdr ranges))) | ||
| 409 | (when list | ||
| 410 | (setq out (nconc (gnus-compress-sequence list t) out))) | ||
| 411 | (setq out (sort out (lambda (r1 r2) | ||
| 412 | (< (or (and (atom r1) r1) (car r1)) | ||
| 413 | (or (and (atom r2) r2) (car r2)))))) | ||
| 414 | (setq ranges out) | ||
| 415 | (while ranges | ||
| 416 | (if (atom (car ranges)) | ||
| 417 | (when (cdr ranges) | ||
| 418 | (if (atom (cadr ranges)) | ||
| 419 | (when (= (1+ (car ranges)) (cadr ranges)) | ||
| 420 | (setcar ranges (cons (car ranges) | ||
| 421 | (cadr ranges))) | ||
| 422 | (setcdr ranges (cddr ranges))) | ||
| 423 | (when (= (1+ (car ranges)) (caadr ranges)) | ||
| 424 | (setcar (cadr ranges) (car ranges)) | ||
| 425 | (setcar ranges (cadr ranges)) | ||
| 426 | (setcdr ranges (cddr ranges))))) | ||
| 427 | (when (cdr ranges) | ||
| 428 | (if (atom (cadr ranges)) | ||
| 429 | (when (= (1+ (cdar ranges)) (cadr ranges)) | ||
| 430 | (setcdr (car ranges) (cadr ranges)) | ||
| 431 | (setcdr ranges (cddr ranges))) | ||
| 432 | (when (= (1+ (cdar ranges)) (caadr ranges)) | ||
| 433 | (setcdr (car ranges) (cdadr ranges)) | ||
| 434 | (setcdr ranges (cddr ranges)))))) | ||
| 435 | (setq ranges (cdr ranges))) | ||
| 436 | out))) | ||
| 437 | |||
| 438 | (defun gnus-remove-from-range (range1 range2) | ||
| 439 | "Return a range that has all articles from RANGE2 removed from RANGE1. | ||
| 440 | The returned range is always a list. RANGE2 can also be a unsorted | ||
| 441 | list of articles. RANGE1 is modified by side effects, RANGE2 is not | ||
| 442 | modified." | ||
| 443 | (if (or (null range1) (null range2)) | ||
| 444 | range1 | ||
| 445 | (let (out r1 r2 r1_min r1_max r2_min r2_max | ||
| 446 | (range2 (copy-tree range2))) | ||
| 447 | (setq range1 (if (listp (cdr range1)) range1 (list range1)) | ||
| 448 | range2 (sort (if (listp (cdr range2)) range2 (list range2)) | ||
| 449 | (lambda (e1 e2) | ||
| 450 | (< (if (consp e1) (car e1) e1) | ||
| 451 | (if (consp e2) (car e2) e2)))) | ||
| 452 | r1 (car range1) | ||
| 453 | r2 (car range2) | ||
| 454 | r1_min (if (consp r1) (car r1) r1) | ||
| 455 | r1_max (if (consp r1) (cdr r1) r1) | ||
| 456 | r2_min (if (consp r2) (car r2) r2) | ||
| 457 | r2_max (if (consp r2) (cdr r2) r2)) | ||
| 458 | (while (and range1 range2) | ||
| 459 | (cond ((< r2_max r1_min) ; r2 < r1 | ||
| 460 | (pop range2) | ||
| 461 | (setq r2 (car range2) | ||
| 462 | r2_min (if (consp r2) (car r2) r2) | ||
| 463 | r2_max (if (consp r2) (cdr r2) r2))) | ||
| 464 | ((and (<= r2_min r1_min) (<= r1_max r2_max)) ; r2 overlap r1 | ||
| 465 | (pop range1) | ||
| 466 | (setq r1 (car range1) | ||
| 467 | r1_min (if (consp r1) (car r1) r1) | ||
| 468 | r1_max (if (consp r1) (cdr r1) r1))) | ||
| 469 | ((and (<= r2_min r1_min) (<= r2_max r1_max)) ; r2 overlap min r1 | ||
| 470 | (pop range2) | ||
| 471 | (setq r1_min (1+ r2_max) | ||
| 472 | r2 (car range2) | ||
| 473 | r2_min (if (consp r2) (car r2) r2) | ||
| 474 | r2_max (if (consp r2) (cdr r2) r2))) | ||
| 475 | ((and (<= r1_min r2_min) (<= r2_max r1_max)) ; r2 contained in r1 | ||
| 476 | (if (eq r1_min (1- r2_min)) | ||
| 477 | (push r1_min out) | ||
| 478 | (push (cons r1_min (1- r2_min)) out)) | ||
| 479 | (pop range2) | ||
| 480 | (if (< r2_max r1_max) ; finished with r1? | ||
| 481 | (setq r1_min (1+ r2_max)) | ||
| 482 | (pop range1) | ||
| 483 | (setq r1 (car range1) | ||
| 484 | r1_min (if (consp r1) (car r1) r1) | ||
| 485 | r1_max (if (consp r1) (cdr r1) r1))) | ||
| 486 | (setq r2 (car range2) | ||
| 487 | r2_min (if (consp r2) (car r2) r2) | ||
| 488 | r2_max (if (consp r2) (cdr r2) r2))) | ||
| 489 | ((and (<= r2_min r1_max) (<= r1_max r2_max)) ; r2 overlap max r1 | ||
| 490 | (if (eq r1_min (1- r2_min)) | ||
| 491 | (push r1_min out) | ||
| 492 | (push (cons r1_min (1- r2_min)) out)) | ||
| 493 | (pop range1) | ||
| 494 | (setq r1 (car range1) | ||
| 495 | r1_min (if (consp r1) (car r1) r1) | ||
| 496 | r1_max (if (consp r1) (cdr r1) r1))) | ||
| 497 | ((< r1_max r2_min) ; r2 > r1 | ||
| 498 | (pop range1) | ||
| 499 | (if (eq r1_min r1_max) | ||
| 500 | (push r1_min out) | ||
| 501 | (push (cons r1_min r1_max) out)) | ||
| 502 | (setq r1 (car range1) | ||
| 503 | r1_min (if (consp r1) (car r1) r1) | ||
| 504 | r1_max (if (consp r1) (cdr r1) r1))))) | ||
| 505 | (when r1 | ||
| 506 | (if (eq r1_min r1_max) | ||
| 507 | (push r1_min out) | ||
| 508 | (push (cons r1_min r1_max) out)) | ||
| 509 | (pop range1)) | ||
| 510 | (while range1 | ||
| 511 | (push (pop range1) out)) | ||
| 512 | (nreverse out)))) | ||
| 513 | |||
| 514 | (defun gnus-member-of-range (number ranges) | ||
| 515 | (if (not (listp (cdr ranges))) | ||
| 516 | (and (>= number (car ranges)) | ||
| 517 | (<= number (cdr ranges))) | ||
| 518 | (let ((not-stop t)) | ||
| 519 | (while (and ranges | ||
| 520 | (if (numberp (car ranges)) | ||
| 521 | (>= number (car ranges)) | ||
| 522 | (>= number (caar ranges))) | ||
| 523 | not-stop) | ||
| 524 | (when (if (numberp (car ranges)) | ||
| 525 | (= number (car ranges)) | ||
| 526 | (and (>= number (caar ranges)) | ||
| 527 | (<= number (cdar ranges)))) | ||
| 528 | (setq not-stop nil)) | ||
| 529 | (setq ranges (cdr ranges))) | ||
| 530 | (not not-stop)))) | ||
| 531 | |||
| 532 | (defun gnus-list-range-intersection (list ranges) | ||
| 533 | "Return a list of numbers in LIST that are members of RANGES. | ||
| 534 | LIST is a sorted list." | ||
| 535 | (setq ranges (gnus-range-normalize ranges)) | ||
| 536 | (let (number result) | ||
| 537 | (while (setq number (pop list)) | ||
| 538 | (while (and ranges | ||
| 539 | (if (numberp (car ranges)) | ||
| 540 | (< (car ranges) number) | ||
| 541 | (< (cdar ranges) number))) | ||
| 542 | (setq ranges (cdr ranges))) | ||
| 543 | (when (and ranges | ||
| 544 | (if (numberp (car ranges)) | ||
| 545 | (= (car ranges) number) | ||
| 546 | ;; (caar ranges) <= number <= (cdar ranges) | ||
| 547 | (>= number (caar ranges)))) | ||
| 548 | (push number result))) | ||
| 549 | (nreverse result))) | ||
| 550 | 258 | ||
| 551 | (defalias 'gnus-inverse-list-range-intersection 'gnus-list-range-difference) | 259 | (defalias 'gnus-inverse-list-range-intersection 'gnus-list-range-difference) |
| 552 | 260 | ||
| 553 | (defun gnus-list-range-difference (list ranges) | 261 | (define-obsolete-function-alias 'gnus-list-range-difference |
| 554 | "Return a list of numbers in LIST that are not members of RANGES. | 262 | #'range-list-difference "29.1") |
| 555 | LIST is a sorted list." | 263 | |
| 556 | (setq ranges (gnus-range-normalize ranges)) | 264 | (define-obsolete-function-alias 'gnus-range-length #'range-length "29.1") |
| 557 | (let (number result) | ||
| 558 | (while (setq number (pop list)) | ||
| 559 | (while (and ranges | ||
| 560 | (if (numberp (car ranges)) | ||
| 561 | (< (car ranges) number) | ||
| 562 | (< (cdar ranges) number))) | ||
| 563 | (setq ranges (cdr ranges))) | ||
| 564 | (when (or (not ranges) | ||
| 565 | (if (numberp (car ranges)) | ||
| 566 | (not (= (car ranges) number)) | ||
| 567 | ;; not ((caar ranges) <= number <= (cdar ranges)) | ||
| 568 | (< number (caar ranges)))) | ||
| 569 | (push number result))) | ||
| 570 | (nreverse result))) | ||
| 571 | 265 | ||
| 572 | (defun gnus-range-length (range) | 266 | (define-obsolete-function-alias 'gnus-range-add #'range-concat "29.1") |
| 573 | "Return the length RANGE would have if uncompressed." | ||
| 574 | (cond | ||
| 575 | ((null range) | ||
| 576 | 0) | ||
| 577 | ((not (listp (cdr range))) | ||
| 578 | (- (cdr range) (car range) -1)) | ||
| 579 | (t | ||
| 580 | (let ((sum 0)) | ||
| 581 | (dolist (x range sum) | ||
| 582 | (setq sum | ||
| 583 | (+ sum (if (consp x) (- (cdr x) (car x) -1) 1)))))))) | ||
| 584 | |||
| 585 | (defun gnus-range-add (range1 range2) | ||
| 586 | "Add RANGE2 to RANGE1 (nondestructively)." | ||
| 587 | (unless (listp (cdr range1)) | ||
| 588 | (setq range1 (list range1))) | ||
| 589 | (unless (listp (cdr range2)) | ||
| 590 | (setq range2 (list range2))) | ||
| 591 | (let ((item1 (pop range1)) | ||
| 592 | (item2 (pop range2)) | ||
| 593 | range item selector) | ||
| 594 | (while (or item1 item2) | ||
| 595 | (setq selector | ||
| 596 | (cond | ||
| 597 | ((null item1) nil) | ||
| 598 | ((null item2) t) | ||
| 599 | ((and (numberp item1) (numberp item2)) (< item1 item2)) | ||
| 600 | ((numberp item1) (< item1 (car item2))) | ||
| 601 | ((numberp item2) (< (car item1) item2)) | ||
| 602 | (t (< (car item1) (car item2))))) | ||
| 603 | (setq item | ||
| 604 | (or | ||
| 605 | (let ((tmp1 item) (tmp2 (if selector item1 item2))) | ||
| 606 | (cond | ||
| 607 | ((null tmp1) tmp2) | ||
| 608 | ((null tmp2) tmp1) | ||
| 609 | ((and (numberp tmp1) (numberp tmp2)) | ||
| 610 | (cond | ||
| 611 | ((eq tmp1 tmp2) tmp1) | ||
| 612 | ((eq (1+ tmp1) tmp2) (cons tmp1 tmp2)) | ||
| 613 | ((eq (1+ tmp2) tmp1) (cons tmp2 tmp1)) | ||
| 614 | (t nil))) | ||
| 615 | ((numberp tmp1) | ||
| 616 | (cond | ||
| 617 | ((and (>= tmp1 (car tmp2)) (<= tmp1 (cdr tmp2))) tmp2) | ||
| 618 | ((eq (1+ tmp1) (car tmp2)) (cons tmp1 (cdr tmp2))) | ||
| 619 | ((eq (1- tmp1) (cdr tmp2)) (cons (car tmp2) tmp1)) | ||
| 620 | (t nil))) | ||
| 621 | ((numberp tmp2) | ||
| 622 | (cond | ||
| 623 | ((and (>= tmp2 (car tmp1)) (<= tmp2 (cdr tmp1))) tmp1) | ||
| 624 | ((eq (1+ tmp2) (car tmp1)) (cons tmp2 (cdr tmp1))) | ||
| 625 | ((eq (1- tmp2) (cdr tmp1)) (cons (car tmp1) tmp2)) | ||
| 626 | (t nil))) | ||
| 627 | ((< (1+ (cdr tmp1)) (car tmp2)) nil) | ||
| 628 | ((< (1+ (cdr tmp2)) (car tmp1)) nil) | ||
| 629 | (t (cons (min (car tmp1) (car tmp2)) | ||
| 630 | (max (cdr tmp1) (cdr tmp2)))))) | ||
| 631 | (progn | ||
| 632 | (if item (push item range)) | ||
| 633 | (if selector item1 item2)))) | ||
| 634 | (if selector | ||
| 635 | (setq item1 (pop range1)) | ||
| 636 | (setq item2 (pop range2)))) | ||
| 637 | (if item (push item range)) | ||
| 638 | (reverse range))) | ||
| 639 | 267 | ||
| 640 | ;;;###autoload | 268 | ;;;###autoload |
| 641 | (defun gnus-add-to-sorted-list (list num) | 269 | (defun gnus-add-to-sorted-list (list num) |
| @@ -649,18 +277,7 @@ LIST is a sorted list." | |||
| 649 | (setcdr prev (cons num list))) | 277 | (setcdr prev (cons num list))) |
| 650 | (cdr top))) | 278 | (cdr top))) |
| 651 | 279 | ||
| 652 | (defun gnus-range-map (func range) | 280 | (define-obsolete-function-alias 'gnus-range-map #'range-map "29.1") |
| 653 | "Apply FUNC to each value contained by RANGE." | ||
| 654 | (setq range (gnus-range-normalize range)) | ||
| 655 | (while range | ||
| 656 | (let ((span (pop range))) | ||
| 657 | (if (numberp span) | ||
| 658 | (funcall func span) | ||
| 659 | (let ((first (car span)) | ||
| 660 | (last (cdr span))) | ||
| 661 | (while (<= first last) | ||
| 662 | (funcall func first) | ||
| 663 | (setq first (1+ first)))))))) | ||
| 664 | 281 | ||
| 665 | (provide 'gnus-range) | 282 | (provide 'gnus-range) |
| 666 | 283 | ||
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 252e6e22299..2cf11fb12f9 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el | |||
| @@ -1884,13 +1884,12 @@ The info element is shared with the same element of | |||
| 1884 | (ranges (gnus-info-read info)) | 1884 | (ranges (gnus-info-read info)) |
| 1885 | news article) | 1885 | news article) |
| 1886 | (while articles | 1886 | (while articles |
| 1887 | (when (gnus-member-of-range | 1887 | (when (range-member-p (setq article (pop articles)) ranges) |
| 1888 | (setq article (pop articles)) ranges) | ||
| 1889 | (push article news))) | 1888 | (push article news))) |
| 1890 | (when news | 1889 | (when news |
| 1891 | ;; Enter this list into the group info. | 1890 | ;; Enter this list into the group info. |
| 1892 | (setf (gnus-info-read info) | 1891 | (setf (gnus-info-read info) |
| 1893 | (gnus-remove-from-range (gnus-info-read info) (nreverse news))) | 1892 | (range-remove (gnus-info-read info) (nreverse news))) |
| 1894 | 1893 | ||
| 1895 | ;; Set the number of unread articles in gnus-newsrc-hashtb. | 1894 | ;; Set the number of unread articles in gnus-newsrc-hashtb. |
| 1896 | (gnus-get-unread-articles-in-group info (gnus-active group)) | 1895 | (gnus-get-unread-articles-in-group info (gnus-active group)) |
| @@ -2362,10 +2361,10 @@ The form should return either t or nil." | |||
| 2362 | ticked (cdr (assq 'tick marks))) | 2361 | ticked (cdr (assq 'tick marks))) |
| 2363 | (when (or dormant ticked) | 2362 | (when (or dormant ticked) |
| 2364 | (setf (gnus-info-read info) | 2363 | (setf (gnus-info-read info) |
| 2365 | (gnus-add-to-range | 2364 | (range-add-list |
| 2366 | (gnus-info-read info) | 2365 | (gnus-info-read info) |
| 2367 | (nconc (gnus-uncompress-range dormant) | 2366 | (nconc (range-uncompress dormant) |
| 2368 | (gnus-uncompress-range ticked))))))))) | 2367 | (range-uncompress ticked))))))))) |
| 2369 | 2368 | ||
| 2370 | (defun gnus-load (file) | 2369 | (defun gnus-load (file) |
| 2371 | "Load FILE, but in such a way that read errors can be reported." | 2370 | "Load FILE, but in such a way that read errors can be reported." |
| @@ -2457,8 +2456,7 @@ The form should return either t or nil." | |||
| 2457 | (unless (nthcdr 3 info) | 2456 | (unless (nthcdr 3 info) |
| 2458 | (nconc info (list nil))) | 2457 | (nconc info (list nil))) |
| 2459 | (setf (gnus-info-marks info) | 2458 | (setf (gnus-info-marks info) |
| 2460 | (list (cons 'tick (gnus-compress-sequence | 2459 | (list (cons 'tick (range-compress-list (sort (cdr m) #'<))))))) |
| 2461 | (sort (cdr m) #'<) t)))))) | ||
| 2462 | (setq newsrc killed) | 2460 | (setq newsrc killed) |
| 2463 | (while newsrc | 2461 | (while newsrc |
| 2464 | (setcar newsrc (caar newsrc)) | 2462 | (setcar newsrc (caar newsrc)) |
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 6dfdcaf55c7..8fb07d5905c 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el | |||
| @@ -5755,7 +5755,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 5755 | ;; (let ((n (cdr (gnus-active group)))) | 5755 | ;; (let ((n (cdr (gnus-active group)))) |
| 5756 | ;; (lambda () (> number (- n display)))) | 5756 | ;; (lambda () (> number (- n display)))) |
| 5757 | (setq select-articles | 5757 | (setq select-articles |
| 5758 | (gnus-uncompress-range | 5758 | (range-uncompress |
| 5759 | (cons (let ((tmp (- (cdr (gnus-active group)) display))) | 5759 | (cons (let ((tmp (- (cdr (gnus-active group)) display))) |
| 5760 | (if (> tmp 0) | 5760 | (if (> tmp 0) |
| 5761 | tmp | 5761 | tmp |
| @@ -5928,7 +5928,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 5928 | "Find out what articles the user wants to read." | 5928 | "Find out what articles the user wants to read." |
| 5929 | (let* ((only-read-p t) | 5929 | (let* ((only-read-p t) |
| 5930 | (articles | 5930 | (articles |
| 5931 | (gnus-list-range-difference | 5931 | (range-list-difference |
| 5932 | ;; Select all articles if `read-all' is non-nil, or if there | 5932 | ;; Select all articles if `read-all' is non-nil, or if there |
| 5933 | ;; are no unread articles. | 5933 | ;; are no unread articles. |
| 5934 | (if (or read-all | 5934 | (if (or read-all |
| @@ -5943,13 +5943,13 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 5943 | (or | 5943 | (or |
| 5944 | (if gnus-newsgroup-maximum-articles | 5944 | (if gnus-newsgroup-maximum-articles |
| 5945 | (let ((active (gnus-active group))) | 5945 | (let ((active (gnus-active group))) |
| 5946 | (gnus-uncompress-range | 5946 | (range-uncompress |
| 5947 | (cons (max (car active) | 5947 | (cons (max (car active) |
| 5948 | (- (cdr active) | 5948 | (- (cdr active) |
| 5949 | gnus-newsgroup-maximum-articles | 5949 | gnus-newsgroup-maximum-articles |
| 5950 | -1)) | 5950 | -1)) |
| 5951 | (cdr active)))) | 5951 | (cdr active)))) |
| 5952 | (gnus-uncompress-range (gnus-active group))) | 5952 | (range-uncompress (gnus-active group))) |
| 5953 | (gnus-cache-articles-in-group group)) | 5953 | (gnus-cache-articles-in-group group)) |
| 5954 | ;; Select only the "normal" subset of articles. | 5954 | ;; Select only the "normal" subset of articles. |
| 5955 | (setq only-read-p nil) | 5955 | (setq only-read-p nil) |
| @@ -6040,7 +6040,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 6040 | (defun gnus-killed-articles (killed articles) | 6040 | (defun gnus-killed-articles (killed articles) |
| 6041 | (let (out) | 6041 | (let (out) |
| 6042 | (while articles | 6042 | (while articles |
| 6043 | (when (inline (gnus-member-of-range (car articles) killed)) | 6043 | (when (inline (range-member-p (car articles) killed)) |
| 6044 | (push (car articles) out)) | 6044 | (push (car articles) out)) |
| 6045 | (setq articles (cdr articles))) | 6045 | (setq articles (cdr articles))) |
| 6046 | out)) | 6046 | out)) |
| @@ -6078,7 +6078,7 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 6078 | ;; Adjust "simple" lists - compressed yet unsorted | 6078 | ;; Adjust "simple" lists - compressed yet unsorted |
| 6079 | ((eq mark-type 'list) | 6079 | ((eq mark-type 'list) |
| 6080 | ;; Simultaneously uncompress and clip to active range | 6080 | ;; Simultaneously uncompress and clip to active range |
| 6081 | ;; See gnus-uncompress-range for a description of possible marks | 6081 | ;; See range-uncompress for a description of possible marks |
| 6082 | (let (l lh) | 6082 | (let (l lh) |
| 6083 | (if (not (cadr marks)) | 6083 | (if (not (cadr marks)) |
| 6084 | (set var nil) | 6084 | (set var nil) |
| @@ -6177,10 +6177,10 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 6177 | ;; When exiting the group, everything that's previously been | 6177 | ;; When exiting the group, everything that's previously been |
| 6178 | ;; unseen is now seen. | 6178 | ;; unseen is now seen. |
| 6179 | (when (eq (cdr type) 'seen) | 6179 | (when (eq (cdr type) 'seen) |
| 6180 | (setq list (gnus-range-add list gnus-newsgroup-unseen))) | 6180 | (setq list (range-concat list gnus-newsgroup-unseen))) |
| 6181 | 6181 | ||
| 6182 | (when (eq (gnus-article-mark-to-type (cdr type)) 'list) | 6182 | (when (eq (gnus-article-mark-to-type (cdr type)) 'list) |
| 6183 | (setq list (gnus-compress-sequence (set symbol (sort list #'<)) t))) | 6183 | (setq list (range-compress-list (set symbol (sort list #'<))))) |
| 6184 | 6184 | ||
| 6185 | (when (and (gnus-check-backend-function | 6185 | (when (and (gnus-check-backend-function |
| 6186 | 'request-set-mark gnus-newsgroup-name) | 6186 | 'request-set-mark gnus-newsgroup-name) |
| @@ -6189,20 +6189,19 @@ If SELECT-ARTICLES, only select those articles from GROUP." | |||
| 6189 | ;; Don't do anything about marks for articles we | 6189 | ;; Don't do anything about marks for articles we |
| 6190 | ;; didn't actually get any headers for. | 6190 | ;; didn't actually get any headers for. |
| 6191 | (del | 6191 | (del |
| 6192 | (gnus-list-range-intersection | 6192 | (range-list-intersection |
| 6193 | gnus-newsgroup-articles | 6193 | gnus-newsgroup-articles |
| 6194 | (gnus-remove-from-range (copy-tree old) list))) | 6194 | (range-remove (copy-tree old) list))) |
| 6195 | (add | 6195 | (add |
| 6196 | (gnus-list-range-intersection | 6196 | (range-list-intersection |
| 6197 | gnus-newsgroup-articles | 6197 | gnus-newsgroup-articles |
| 6198 | (gnus-remove-from-range | 6198 | (range-remove (copy-tree list) old)))) |
| 6199 | (copy-tree list) old)))) | ||
| 6200 | (when add | 6199 | (when add |
| 6201 | (push (list add 'add (list (cdr type))) delta-marks)) | 6200 | (push (list add 'add (list (cdr type))) delta-marks)) |
| 6202 | (when del | 6201 | (when del |
| 6203 | ;; Don't delete marks from outside the active range. | 6202 | ;; Don't delete marks from outside the active range. |
| 6204 | ;; This shouldn't happen, but is a sanity check. | 6203 | ;; This shouldn't happen, but is a sanity check. |
| 6205 | (setq del (gnus-sorted-range-intersection | 6204 | (setq del (range-intersection |
| 6206 | (gnus-active gnus-newsgroup-name) del)) | 6205 | (gnus-active gnus-newsgroup-name) del)) |
| 6207 | (push (list del 'del (list (cdr type))) delta-marks)))) | 6206 | (push (list del 'del (list (cdr type))) delta-marks)))) |
| 6208 | 6207 | ||
| @@ -6386,7 +6385,7 @@ The resulting hash table is returned, or nil if no Xrefs were found." | |||
| 6386 | (setq ninfo (cons 1 (1- (car active)))) | 6385 | (setq ninfo (cons 1 (1- (car active)))) |
| 6387 | (setq ninfo (gnus-info-read info))) | 6386 | (setq ninfo (gnus-info-read info))) |
| 6388 | ;; Then we add the read articles to the range. | 6387 | ;; Then we add the read articles to the range. |
| 6389 | (gnus-add-to-range | 6388 | (range-add-list |
| 6390 | ninfo (setq articles (sort articles #'<)))))) | 6389 | ninfo (setq articles (sort articles #'<)))))) |
| 6391 | 6390 | ||
| 6392 | (defun gnus-group-make-articles-read (group articles) | 6391 | (defun gnus-group-make-articles-read (group articles) |
| @@ -6967,10 +6966,10 @@ displayed, no centering will be performed." | |||
| 6967 | (marked (gnus-info-marks info)) | 6966 | (marked (gnus-info-marks info)) |
| 6968 | (active (gnus-active group))) | 6967 | (active (gnus-active group))) |
| 6969 | (and info active | 6968 | (and info active |
| 6970 | (gnus-list-range-difference | 6969 | (range-list-difference |
| 6971 | (gnus-list-range-difference | 6970 | (range-list-difference |
| 6972 | (gnus-sorted-complement | 6971 | (gnus-sorted-complement |
| 6973 | (gnus-uncompress-range | 6972 | (range-uncompress |
| 6974 | (if gnus-newsgroup-maximum-articles | 6973 | (if gnus-newsgroup-maximum-articles |
| 6975 | (cons (max (car active) | 6974 | (cons (max (car active) |
| 6976 | (- (cdr active) | 6975 | (- (cdr active) |
| @@ -7129,12 +7128,11 @@ The prefix argument ALL means to select all articles." | |||
| 7129 | (when group | 7128 | (when group |
| 7130 | (when gnus-newsgroup-kill-headers | 7129 | (when gnus-newsgroup-kill-headers |
| 7131 | (setq gnus-newsgroup-killed | 7130 | (setq gnus-newsgroup-killed |
| 7132 | (gnus-compress-sequence | 7131 | (range-compress-list |
| 7133 | (gnus-sorted-union | 7132 | (gnus-sorted-union |
| 7134 | (gnus-list-range-intersection | 7133 | (range-list-intersection |
| 7135 | gnus-newsgroup-unselected gnus-newsgroup-killed) | 7134 | gnus-newsgroup-unselected gnus-newsgroup-killed) |
| 7136 | gnus-newsgroup-unreads) | 7135 | gnus-newsgroup-unreads)))) |
| 7137 | t))) | ||
| 7138 | (unless (listp (cdr gnus-newsgroup-killed)) | 7136 | (unless (listp (cdr gnus-newsgroup-killed)) |
| 7139 | (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) | 7137 | (setq gnus-newsgroup-killed (list gnus-newsgroup-killed))) |
| 7140 | (let ((headers gnus-newsgroup-headers) | 7138 | (let ((headers gnus-newsgroup-headers) |
| @@ -10241,8 +10239,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'." | |||
| 10241 | (cdr art-group)) | 10239 | (cdr art-group)) |
| 10242 | (push 'read to-marks) | 10240 | (push 'read to-marks) |
| 10243 | (setf (gnus-info-read info) | 10241 | (setf (gnus-info-read info) |
| 10244 | (gnus-add-to-range (gnus-info-read info) | 10242 | (range-add-list (gnus-info-read info) |
| 10245 | (list (cdr art-group))))) | 10243 | (list (cdr art-group))))) |
| 10246 | 10244 | ||
| 10247 | ;; See whether the article is to be put in the cache. | 10245 | ;; See whether the article is to be put in the cache. |
| 10248 | (let* ((expirable (gnus-group-auto-expirable-p to-group)) | 10246 | (let* ((expirable (gnus-group-auto-expirable-p to-group)) |
| @@ -10525,7 +10523,7 @@ This will be the case if the article has both been mailed and posted." | |||
| 10525 | ;; This backend supports expiry. | 10523 | ;; This backend supports expiry. |
| 10526 | (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name)) | 10524 | (let* ((total (gnus-group-total-expirable-p gnus-newsgroup-name)) |
| 10527 | (expirable | 10525 | (expirable |
| 10528 | (gnus-list-range-difference | 10526 | (range-list-difference |
| 10529 | (if total | 10527 | (if total |
| 10530 | (progn | 10528 | (progn |
| 10531 | ;; We need to update the info for | 10529 | ;; We need to update the info for |
| @@ -12874,8 +12872,8 @@ UNREAD is a sorted list." | |||
| 12874 | (gnus-find-method-for-group group) | 12872 | (gnus-find-method-for-group group) |
| 12875 | 'server-marks) | 12873 | 'server-marks) |
| 12876 | (gnus-check-backend-function 'request-set-mark group)) | 12874 | (gnus-check-backend-function 'request-set-mark group)) |
| 12877 | (let ((del (gnus-remove-from-range (gnus-info-read info) read)) | 12875 | (let ((del (range-remove (gnus-info-read info) read)) |
| 12878 | (add (gnus-remove-from-range read (gnus-info-read info)))) | 12876 | (add (range-remove read (gnus-info-read info)))) |
| 12879 | (when (or add del) | 12877 | (when (or add del) |
| 12880 | (unless (gnus-check-group group) | 12878 | (unless (gnus-check-group group) |
| 12881 | (error "Can't open server for %s" group)) | 12879 | (error "Can't open server for %s" group)) |
| @@ -13133,10 +13131,10 @@ If ALL is a number, fetch this number of articles." | |||
| 13133 | ;; Some nntp servers lie about their active range. When | 13131 | ;; Some nntp servers lie about their active range. When |
| 13134 | ;; this happens, the active range can be in the millions. | 13132 | ;; this happens, the active range can be in the millions. |
| 13135 | ;; Use a compressed range to avoid creating a huge list. | 13133 | ;; Use a compressed range to avoid creating a huge list. |
| 13136 | (gnus-range-difference | 13134 | (range-difference |
| 13137 | (gnus-range-difference (list gnus-newsgroup-active) old) | 13135 | (range-difference (list gnus-newsgroup-active) old) |
| 13138 | gnus-newsgroup-unexist)) | 13136 | gnus-newsgroup-unexist)) |
| 13139 | (setq len (gnus-range-length older)) | 13137 | (setq len (range-length older)) |
| 13140 | (cond | 13138 | (cond |
| 13141 | ((null older) nil) | 13139 | ((null older) nil) |
| 13142 | ((numberp all) | 13140 | ((numberp all) |
| @@ -13153,9 +13151,9 @@ If ALL is a number, fetch this number of articles." | |||
| 13153 | (push max older) | 13151 | (push max older) |
| 13154 | (setq all (1- all) | 13152 | (setq all (1- all) |
| 13155 | max (1- max)))))) | 13153 | max (1- max)))))) |
| 13156 | (setq older (gnus-uncompress-range older)))) | 13154 | (setq older (range-uncompress older)))) |
| 13157 | (all | 13155 | (all |
| 13158 | (setq older (gnus-uncompress-range older))) | 13156 | (setq older (range-uncompress older))) |
| 13159 | (t | 13157 | (t |
| 13160 | (when (and (numberp gnus-large-newsgroup) | 13158 | (when (and (numberp gnus-large-newsgroup) |
| 13161 | (> len gnus-large-newsgroup)) | 13159 | (> len gnus-large-newsgroup)) |
| @@ -13190,7 +13188,7 @@ If ALL is a number, fetch this number of articles." | |||
| 13190 | (push max older) | 13188 | (push max older) |
| 13191 | (setq all (1- all) | 13189 | (setq all (1- all) |
| 13192 | max (1- max)))))))))) | 13190 | max (1- max)))))))))) |
| 13193 | (setq older (gnus-uncompress-range older)))) | 13191 | (setq older (range-uncompress older)))) |
| 13194 | (if (not older) | 13192 | (if (not older) |
| 13195 | (message "No old news.") | 13193 | (message "No old news.") |
| 13196 | (gnus-summary-insert-articles older) | 13194 | (gnus-summary-insert-articles older) |
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 9a48f710e55..5d0c0e2654b 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | (autoload 'pop3-movemail "pop3") | 31 | (autoload 'pop3-movemail "pop3") |
| 32 | (autoload 'pop3-get-message-count "pop3") | 32 | (autoload 'pop3-get-message-count "pop3") |
| 33 | (require 'mm-util) | 33 | (require 'mm-util) |
| 34 | (require 'gnus-range) | ||
| 34 | (require 'message) ;; for `message-directory' | 35 | (require 'message) ;; for `message-directory' |
| 35 | 36 | ||
| 36 | (defvar display-time-mail-function) | 37 | (defvar display-time-mail-function) |
| @@ -1048,8 +1049,6 @@ This only works when `display-time' is enabled." | |||
| 1048 | (autoload 'imap-range-to-message-set "imap") | 1049 | (autoload 'imap-range-to-message-set "imap") |
| 1049 | (autoload 'nnheader-ms-strip-cr "nnheader") | 1050 | (autoload 'nnheader-ms-strip-cr "nnheader") |
| 1050 | 1051 | ||
| 1051 | (autoload 'gnus-compress-sequence "gnus-range") | ||
| 1052 | |||
| 1053 | (defvar mail-source-imap-file-coding-system 'binary | 1052 | (defvar mail-source-imap-file-coding-system 'binary |
| 1054 | "Coding system for the crashbox made by `mail-source-fetch-imap'.") | 1053 | "Coding system for the crashbox made by `mail-source-fetch-imap'.") |
| 1055 | 1054 | ||
diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el index 8b3718ed7e8..c1c5f00ff7f 100644 --- a/lisp/gnus/nnheader.el +++ b/lisp/gnus/nnheader.el | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | ;;; Code: | 27 | ;;; Code: |
| 28 | 28 | ||
| 29 | (eval-when-compile (require 'cl-lib)) | 29 | (eval-when-compile (require 'cl-lib)) |
| 30 | (require 'range) | ||
| 30 | 31 | ||
| 31 | (defvar gnus-decode-encoded-word-function) | 32 | (defvar gnus-decode-encoded-word-function) |
| 32 | (defvar gnus-decode-encoded-address-function) | 33 | (defvar gnus-decode-encoded-address-function) |
| @@ -44,8 +45,6 @@ | |||
| 44 | (require 'mm-util) | 45 | (require 'mm-util) |
| 45 | (require 'gnus-util) | 46 | (require 'gnus-util) |
| 46 | (autoload 'gnus-remove-odd-characters "gnus-sum") | 47 | (autoload 'gnus-remove-odd-characters "gnus-sum") |
| 47 | (autoload 'gnus-range-add "gnus-range") | ||
| 48 | (autoload 'gnus-remove-from-range "gnus-range") | ||
| 49 | ;; FIXME none of these are used explicitly in this file. | 48 | ;; FIXME none of these are used explicitly in this file. |
| 50 | (autoload 'gnus-sorted-intersection "gnus-range") | 49 | (autoload 'gnus-sorted-intersection "gnus-range") |
| 51 | (autoload 'gnus-intersection "gnus-range") | 50 | (autoload 'gnus-intersection "gnus-range") |
| @@ -1044,10 +1043,9 @@ See `find-file-noselect' for the arguments." | |||
| 1044 | mark | 1043 | mark |
| 1045 | (cond | 1044 | (cond |
| 1046 | ((eq what 'add) | 1045 | ((eq what 'add) |
| 1047 | (gnus-range-add (cdr (assoc mark backend-marks)) range)) | 1046 | (range-concat (cdr (assoc mark backend-marks)) range)) |
| 1048 | ((eq what 'del) | 1047 | ((eq what 'del) |
| 1049 | (gnus-remove-from-range | 1048 | (range-remove (cdr (assoc mark backend-marks)) range)) |
| 1050 | (cdr (assoc mark backend-marks)) range)) | ||
| 1051 | ((eq what 'set) | 1049 | ((eq what 'set) |
| 1052 | range)) | 1050 | range)) |
| 1053 | backend-marks))))) | 1051 | backend-marks))))) |
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index cff628061e9..afd5418912f 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el | |||
| @@ -1660,13 +1660,13 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1660 | (cdr (assoc '%Seen flags)) | 1660 | (cdr (assoc '%Seen flags)) |
| 1661 | (cdr (assoc '%Deleted flags)))) | 1661 | (cdr (assoc '%Deleted flags)))) |
| 1662 | (cdr (assoc '%Flagged flags))))) | 1662 | (cdr (assoc '%Flagged flags))))) |
| 1663 | (read (gnus-range-difference | 1663 | (read (range-difference |
| 1664 | (cons start-article high) unread))) | 1664 | (cons start-article high) unread))) |
| 1665 | (when (> start-article 1) | 1665 | (when (> start-article 1) |
| 1666 | (setq read | 1666 | (setq read |
| 1667 | (gnus-range-nconcat | 1667 | (gnus-range-nconcat |
| 1668 | (if (> start-article 1) | 1668 | (if (> start-article 1) |
| 1669 | (gnus-sorted-range-intersection | 1669 | (range-intersection |
| 1670 | (cons 1 (1- start-article)) | 1670 | (cons 1 (1- start-article)) |
| 1671 | (gnus-info-read info)) | 1671 | (gnus-info-read info)) |
| 1672 | (gnus-info-read info)) | 1672 | (gnus-info-read info)) |
| @@ -1691,7 +1691,7 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1691 | (pop old-marks) | 1691 | (pop old-marks) |
| 1692 | (when (and old-marks | 1692 | (when (and old-marks |
| 1693 | (> start-article 1)) | 1693 | (> start-article 1)) |
| 1694 | (setq old-marks (gnus-range-difference | 1694 | (setq old-marks (range-difference |
| 1695 | old-marks | 1695 | old-marks |
| 1696 | (cons start-article high))) | 1696 | (cons start-article high))) |
| 1697 | (setq new-marks (gnus-range-nconcat old-marks new-marks))) | 1697 | (setq new-marks (gnus-range-nconcat old-marks new-marks))) |
| @@ -1702,15 +1702,15 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1702 | (active (gnus-active group)) | 1702 | (active (gnus-active group)) |
| 1703 | (unexists | 1703 | (unexists |
| 1704 | (if completep | 1704 | (if completep |
| 1705 | (gnus-range-difference | 1705 | (range-difference |
| 1706 | active | 1706 | active |
| 1707 | (gnus-compress-sequence existing)) | 1707 | (gnus-compress-sequence existing)) |
| 1708 | (gnus-add-to-range | 1708 | (range-add-list |
| 1709 | (cdr old-unexists) | 1709 | (cdr old-unexists) |
| 1710 | (gnus-list-range-difference | 1710 | (range-list-difference |
| 1711 | existing (gnus-active group)))))) | 1711 | existing (gnus-active group)))))) |
| 1712 | (when (> (car active) 1) | 1712 | (when (> (car active) 1) |
| 1713 | (setq unexists (gnus-range-add | 1713 | (setq unexists (range-concat |
| 1714 | (cons 1 (1- (car active))) | 1714 | (cons 1 (1- (car active))) |
| 1715 | unexists))) | 1715 | unexists))) |
| 1716 | (if old-unexists | 1716 | (if old-unexists |
| @@ -1733,10 +1733,9 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1733 | (defun nnimap-update-qresync-info (info existing vanished flags) | 1733 | (defun nnimap-update-qresync-info (info existing vanished flags) |
| 1734 | ;; Add all the vanished articles to the list of read articles. | 1734 | ;; Add all the vanished articles to the list of read articles. |
| 1735 | (setf (gnus-info-read info) | 1735 | (setf (gnus-info-read info) |
| 1736 | (gnus-add-to-range | 1736 | (range-add-list |
| 1737 | (gnus-add-to-range | 1737 | (range-add-list |
| 1738 | (gnus-range-add (gnus-info-read info) | 1738 | (range-concat (gnus-info-read info) vanished) |
| 1739 | vanished) | ||
| 1740 | (cdr (assq '%Flagged flags))) | 1739 | (cdr (assq '%Flagged flags))) |
| 1741 | (cdr (assq '%Seen flags)))) | 1740 | (cdr (assq '%Seen flags)))) |
| 1742 | (let ((marks (gnus-info-marks info))) | 1741 | (let ((marks (gnus-info-marks info))) |
| @@ -1750,9 +1749,9 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1750 | (setq marks (delq ticks marks)) | 1749 | (setq marks (delq ticks marks)) |
| 1751 | (pop ticks) | 1750 | (pop ticks) |
| 1752 | ;; Add the new marks we got. | 1751 | ;; Add the new marks we got. |
| 1753 | (setq ticks (gnus-add-to-range ticks new-marks)) | 1752 | (setq ticks (range-add-list ticks new-marks)) |
| 1754 | ;; Remove the marks from messages that don't have them. | 1753 | ;; Remove the marks from messages that don't have them. |
| 1755 | (setq ticks (gnus-remove-from-range | 1754 | (setq ticks (range-remove |
| 1756 | ticks | 1755 | ticks |
| 1757 | (gnus-compress-sequence | 1756 | (gnus-compress-sequence |
| 1758 | (gnus-sorted-complement existing new-marks)))) | 1757 | (gnus-sorted-complement existing new-marks)))) |
| @@ -1762,7 +1761,7 @@ If LIMIT, first try to limit the search to the N last articles." | |||
| 1762 | ;; Add vanished to the list of unexisting articles. | 1761 | ;; Add vanished to the list of unexisting articles. |
| 1763 | (when vanished | 1762 | (when vanished |
| 1764 | (let* ((old-unexists (assq 'unexist marks)) | 1763 | (let* ((old-unexists (assq 'unexist marks)) |
| 1765 | (unexists (gnus-range-add (cdr old-unexists) vanished))) | 1764 | (unexists (range-concat (cdr old-unexists) vanished))) |
| 1766 | (if old-unexists | 1765 | (if old-unexists |
| 1767 | (setcdr old-unexists unexists) | 1766 | (setcdr old-unexists unexists) |
| 1768 | (push (cons 'unexist unexists) marks))) | 1767 | (push (cons 'unexist unexists) marks))) |
| @@ -2242,7 +2241,7 @@ Return the server's response to the SELECT or EXAMINE command." | |||
| 2242 | (while (re-search-forward "^\\([0-9]+\\) OK\\b" nil t) | 2241 | (while (re-search-forward "^\\([0-9]+\\) OK\\b" nil t) |
| 2243 | (setq sequence (string-to-number (match-string 1))) | 2242 | (setq sequence (string-to-number (match-string 1))) |
| 2244 | (when (setq range (cadr (assq sequence sequences))) | 2243 | (when (setq range (cadr (assq sequence sequences))) |
| 2245 | (push (gnus-uncompress-range range) copied))) | 2244 | (push (range-uncompress range) copied))) |
| 2246 | (gnus-compress-sequence (sort (apply #'nconc copied) #'<)))) | 2245 | (gnus-compress-sequence (sort (apply #'nconc copied) #'<)))) |
| 2247 | 2246 | ||
| 2248 | (defun nnimap-new-articles (flags) | 2247 | (defun nnimap-new-articles (flags) |
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el index 690761a2d6c..30f473b1291 100644 --- a/lisp/gnus/nnmaildir.el +++ b/lisp/gnus/nnmaildir.el | |||
| @@ -1006,10 +1006,10 @@ This variable is set by `nnmaildir-request-article'.") | |||
| 1006 | existing (nnmaildir--grp-nlist group) | 1006 | existing (nnmaildir--grp-nlist group) |
| 1007 | existing (mapcar #'car existing) | 1007 | existing (mapcar #'car existing) |
| 1008 | existing (nreverse existing) | 1008 | existing (nreverse existing) |
| 1009 | existing (gnus-compress-sequence existing 'always-list) | 1009 | existing (range-compress-list existing) |
| 1010 | missing (list (cons 1 (nnmaildir--group-maxnum | 1010 | missing (list (cons 1 (nnmaildir--group-maxnum |
| 1011 | nnmaildir--cur-server group))) | 1011 | nnmaildir--cur-server group))) |
| 1012 | missing (gnus-range-difference missing existing) | 1012 | missing (range-difference missing existing) |
| 1013 | dir (nnmaildir--srv-dir nnmaildir--cur-server) | 1013 | dir (nnmaildir--srv-dir nnmaildir--cur-server) |
| 1014 | dir (nnmaildir--srvgrp-dir dir gname) | 1014 | dir (nnmaildir--srvgrp-dir dir gname) |
| 1015 | dir (nnmaildir--nndir dir) | 1015 | dir (nnmaildir--nndir dir) |
| @@ -1076,10 +1076,10 @@ This variable is set by `nnmaildir-request-article'.") | |||
| 1076 | (let ((article (nnmaildir--flist-art flist prefix))) | 1076 | (let ((article (nnmaildir--flist-art flist prefix))) |
| 1077 | (when article | 1077 | (when article |
| 1078 | (push (nnmaildir--art-num article) article-list)))))) | 1078 | (push (nnmaildir--art-num article) article-list)))))) |
| 1079 | (setq ranges (gnus-add-to-range ranges (sort article-list #'<))))) | 1079 | (setq ranges (range-add-list ranges (sort article-list #'<))))) |
| 1080 | (if (eq mark 'read) (setq read ranges) | 1080 | (if (eq mark 'read) (setq read ranges) |
| 1081 | (if ranges (setq marks (cons (cons mark ranges) marks))))) | 1081 | (if ranges (setq marks (cons (cons mark ranges) marks))))) |
| 1082 | (setf (gnus-info-read info) (gnus-range-add read missing)) | 1082 | (setf (gnus-info-read info) (range-concat read missing)) |
| 1083 | (gnus-info-set-marks info marks 'extend) | 1083 | (gnus-info-set-marks info marks 'extend) |
| 1084 | (setf (nnmaildir--grp-mmth group) new-mmth) | 1084 | (setf (nnmaildir--grp-mmth group) new-mmth) |
| 1085 | info))) | 1085 | info))) |
| @@ -1548,11 +1548,11 @@ This variable is set by `nnmaildir-request-article'.") | |||
| 1548 | (unless group | 1548 | (unless group |
| 1549 | (setf (nnmaildir--srv-error nnmaildir--cur-server) | 1549 | (setf (nnmaildir--srv-error nnmaildir--cur-server) |
| 1550 | (if gname (concat "No such group: " gname) "No current group")) | 1550 | (if gname (concat "No such group: " gname) "No current group")) |
| 1551 | (throw 'return (gnus-uncompress-range ranges))) | 1551 | (throw 'return (range-uncompress ranges))) |
| 1552 | (setq gname (nnmaildir--grp-name group) | 1552 | (setq gname (nnmaildir--grp-name group) |
| 1553 | pgname (nnmaildir--pgname nnmaildir--cur-server gname)) | 1553 | pgname (nnmaildir--pgname nnmaildir--cur-server gname)) |
| 1554 | (if (nnmaildir--param pgname 'read-only) | 1554 | (if (nnmaildir--param pgname 'read-only) |
| 1555 | (throw 'return (gnus-uncompress-range ranges))) | 1555 | (throw 'return (range-uncompress ranges))) |
| 1556 | (setq time (nnmaildir--param pgname 'expire-age)) | 1556 | (setq time (nnmaildir--param pgname 'expire-age)) |
| 1557 | (unless time | 1557 | (unless time |
| 1558 | (setq time (or (and nnmail-expiry-wait-function | 1558 | (setq time (or (and nnmail-expiry-wait-function |
| @@ -1564,7 +1564,7 @@ This variable is set by `nnmaildir-request-article'.") | |||
| 1564 | (setq time (round (* time 86400)))))) | 1564 | (setq time (round (* time 86400)))))) |
| 1565 | (when no-force | 1565 | (when no-force |
| 1566 | (unless (integerp time) ;; handle 'never | 1566 | (unless (integerp time) ;; handle 'never |
| 1567 | (throw 'return (gnus-uncompress-range ranges))) | 1567 | (throw 'return (range-uncompress ranges))) |
| 1568 | (setq boundary (time-since time))) | 1568 | (setq boundary (time-since time))) |
| 1569 | (setq dir (nnmaildir--srv-dir nnmaildir--cur-server) | 1569 | (setq dir (nnmaildir--srv-dir nnmaildir--cur-server) |
| 1570 | dir (nnmaildir--srvgrp-dir dir gname) | 1570 | dir (nnmaildir--srvgrp-dir dir gname) |
| @@ -1686,7 +1686,7 @@ This variable is set by `nnmaildir-request-article'.") | |||
| 1686 | (setf (nnmaildir--srv-error nnmaildir--cur-server) | 1686 | (setf (nnmaildir--srv-error nnmaildir--cur-server) |
| 1687 | (concat "No such group: " gname)) | 1687 | (concat "No such group: " gname)) |
| 1688 | (dolist (action actions) | 1688 | (dolist (action actions) |
| 1689 | (setq ranges (gnus-range-add ranges (car action)))) | 1689 | (setq ranges (range-concat ranges (car action)))) |
| 1690 | (throw 'return ranges)) | 1690 | (throw 'return ranges)) |
| 1691 | (setq nlist (nnmaildir--grp-nlist group) | 1691 | (setq nlist (nnmaildir--grp-nlist group) |
| 1692 | marksdir (nnmaildir--srv-dir nnmaildir--cur-server) | 1692 | marksdir (nnmaildir--srv-dir nnmaildir--cur-server) |
diff --git a/lisp/gnus/nnmairix.el b/lisp/gnus/nnmairix.el index 8ca1cf0fe8b..4e8e329f983 100644 --- a/lisp/gnus/nnmairix.el +++ b/lisp/gnus/nnmairix.el | |||
| @@ -597,7 +597,7 @@ Other back ends might or might not work.") | |||
| 597 | (dolist (cur actions) | 597 | (dolist (cur actions) |
| 598 | (let ((type (nth 1 cur)) | 598 | (let ((type (nth 1 cur)) |
| 599 | (cmdmarks (nth 2 cur)) | 599 | (cmdmarks (nth 2 cur)) |
| 600 | (range (gnus-uncompress-range (nth 0 cur))) | 600 | (range (range-uncompress (nth 0 cur))) |
| 601 | mid ogroup temp) ;; number method | 601 | mid ogroup temp) ;; number method |
| 602 | (when (and corr | 602 | (when (and corr |
| 603 | (not (zerop (cadr corr)))) | 603 | (not (zerop (cadr corr)))) |
diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el index 5a350aac746..96ecc34e156 100644 --- a/lisp/gnus/nnmbox.el +++ b/lisp/gnus/nnmbox.el | |||
| @@ -529,7 +529,7 @@ | |||
| 529 | ;; add article to index, either by building complete list | 529 | ;; add article to index, either by building complete list |
| 530 | ;; in reverse order, or as a list of ranges. | 530 | ;; in reverse order, or as a list of ranges. |
| 531 | (if (not nnmbox-group-building-active-articles) | 531 | (if (not nnmbox-group-building-active-articles) |
| 532 | (setcdr entry (gnus-add-to-range (cdr entry) (list article))) | 532 | (setcdr entry (range-add-list (cdr entry) (list article))) |
| 533 | (when (memq article (cdr entry)) | 533 | (when (memq article (cdr entry)) |
| 534 | (switch-to-buffer nnmbox-mbox-buffer) | 534 | (switch-to-buffer nnmbox-mbox-buffer) |
| 535 | (error "Article %s:%d already exists!" group article)) | 535 | (error "Article %s:%d already exists!" group article)) |
| @@ -548,10 +548,10 @@ | |||
| 548 | nnmbox-group-active-articles) | 548 | nnmbox-group-active-articles) |
| 549 | (car nnmbox-group-active-articles))))) | 549 | (car nnmbox-group-active-articles))))) |
| 550 | ;; remove article from index | 550 | ;; remove article from index |
| 551 | (setcdr entry (gnus-remove-from-range (cdr entry) (list article))))) | 551 | (setcdr entry (range-remove (cdr entry) (list article))))) |
| 552 | 552 | ||
| 553 | (defun nnmbox-is-article-active-p (article) | 553 | (defun nnmbox-is-article-active-p (article) |
| 554 | (gnus-member-of-range | 554 | (range-member-p |
| 555 | article | 555 | article |
| 556 | (cdr (assoc nnmbox-current-group | 556 | (cdr (assoc nnmbox-current-group |
| 557 | nnmbox-group-active-articles)))) | 557 | nnmbox-group-active-articles)))) |
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index afdb0c780a5..7fe2b516cce 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el | |||
| @@ -1078,21 +1078,20 @@ Use the nov database for the current group if available." | |||
| 1078 | ;; #### doing anything on them. | 1078 | ;; #### doing anything on them. |
| 1079 | ;; 2 a/ read articles: | 1079 | ;; 2 a/ read articles: |
| 1080 | (let ((read (gnus-info-read info))) | 1080 | (let ((read (gnus-info-read info))) |
| 1081 | (setq read (gnus-remove-from-range read (list new-number))) | 1081 | (setq read (range-remove read (list new-number))) |
| 1082 | (when (gnus-member-of-range old-number read) | 1082 | (when (range-member-p old-number read) |
| 1083 | (setq read (gnus-remove-from-range read (list old-number))) | 1083 | (setq read (range-remove read (list old-number))) |
| 1084 | (setq read (gnus-add-to-range read (list new-number)))) | 1084 | (setq read (range-add-list read (list new-number)))) |
| 1085 | (setf (gnus-info-read info) read)) | 1085 | (setf (gnus-info-read info) read)) |
| 1086 | ;; 2 b/ marked articles: | 1086 | ;; 2 b/ marked articles: |
| 1087 | (let ((oldmarks (gnus-info-marks info)) | 1087 | (let ((oldmarks (gnus-info-marks info)) |
| 1088 | mark newmarks) | 1088 | mark newmarks) |
| 1089 | (while (setq mark (pop oldmarks)) | 1089 | (while (setq mark (pop oldmarks)) |
| 1090 | (setcdr mark (gnus-remove-from-range (cdr mark) | 1090 | (setcdr mark (range-remove (cdr mark) (list new-number))) |
| 1091 | (list new-number))) | 1091 | (when (range-member-p old-number (cdr mark)) |
| 1092 | (when (gnus-member-of-range old-number (cdr mark)) | 1092 | (setcdr mark (range-remove (cdr mark) |
| 1093 | (setcdr mark (gnus-remove-from-range (cdr mark) | 1093 | (list old-number))) |
| 1094 | (list old-number))) | 1094 | (setcdr mark (range-add-list (cdr mark) |
| 1095 | (setcdr mark (gnus-add-to-range (cdr mark) | ||
| 1096 | (list new-number)))) | 1095 | (list new-number)))) |
| 1097 | (push mark newmarks)) | 1096 | (push mark newmarks)) |
| 1098 | (setf (gnus-info-marks info) newmarks)) | 1097 | (setf (gnus-info-marks info) newmarks)) |
diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el index 9d744ea411e..205456a57df 100644 --- a/lisp/gnus/nnselect.el +++ b/lisp/gnus/nnselect.el | |||
| @@ -207,7 +207,7 @@ as `(keyfunc member)' and the corresponding element is just | |||
| 207 | (inline-quote | 207 | (inline-quote |
| 208 | (cond | 208 | (cond |
| 209 | ((eq ,type 'range) | 209 | ((eq ,type 'range) |
| 210 | (nnselect-categorize (gnus-uncompress-range ,articles) | 210 | (nnselect-categorize (range-uncompress ,articles) |
| 211 | #'nnselect-article-group #'nnselect-article-number)) | 211 | #'nnselect-article-group #'nnselect-article-number)) |
| 212 | ((eq ,type 'tuple) | 212 | ((eq ,type 'tuple) |
| 213 | (nnselect-categorize ,articles | 213 | (nnselect-categorize ,articles |
| @@ -542,10 +542,10 @@ If this variable is nil, or if the provided function returns nil, | |||
| 542 | (group-info (gnus-get-info artgroup)) | 542 | (group-info (gnus-get-info artgroup)) |
| 543 | (marks (gnus-info-marks group-info)) | 543 | (marks (gnus-info-marks group-info)) |
| 544 | (unread (gnus-uncompress-sequence | 544 | (unread (gnus-uncompress-sequence |
| 545 | (gnus-range-difference (gnus-active artgroup) | 545 | (range-difference (gnus-active artgroup) |
| 546 | (gnus-info-read group-info))))) | 546 | (gnus-info-read group-info))))) |
| 547 | (setf (gnus-info-read info) | 547 | (setf (gnus-info-read info) |
| 548 | (gnus-add-to-range | 548 | (range-add-list |
| 549 | (gnus-info-read info) | 549 | (gnus-info-read info) |
| 550 | (delq nil (mapcar | 550 | (delq nil (mapcar |
| 551 | (lambda (art) | 551 | (lambda (art) |
| @@ -567,7 +567,7 @@ If this variable is nil, or if the provided function returns nil, | |||
| 567 | artids)) | 567 | artids)) |
| 568 | (t | 568 | (t |
| 569 | (setq mark-list | 569 | (setq mark-list |
| 570 | (gnus-uncompress-range mark-list)) | 570 | (range-uncompress mark-list)) |
| 571 | (mapcar | 571 | (mapcar |
| 572 | (lambda (id) | 572 | (lambda (id) |
| 573 | (when (memq (cdr id) mark-list) | 573 | (when (memq (cdr id) mark-list) |
| @@ -866,16 +866,16 @@ article came from is also searched." | |||
| 866 | (when (and (gnus-check-backend-function | 866 | (when (and (gnus-check-backend-function |
| 867 | 'request-set-mark artgroup) | 867 | 'request-set-mark artgroup) |
| 868 | (not (gnus-article-unpropagatable-p type))) | 868 | (not (gnus-article-unpropagatable-p type))) |
| 869 | (let* ((old (gnus-list-range-intersection | 869 | (let* ((old (range-list-intersection |
| 870 | artlist | 870 | artlist |
| 871 | (alist-get type (gnus-info-marks group-info)))) | 871 | (alist-get type (gnus-info-marks group-info)))) |
| 872 | (del (gnus-remove-from-range (copy-tree old) list)) | 872 | (del (range-remove (copy-tree old) list)) |
| 873 | (add (gnus-remove-from-range (copy-tree list) old))) | 873 | (add (range-remove (copy-tree list) old))) |
| 874 | (when add (push (list add 'add (list type)) delta-marks)) | 874 | (when add (push (list add 'add (list type)) delta-marks)) |
| 875 | (when del | 875 | (when del |
| 876 | ;; Don't delete marks from outside the active range. | 876 | ;; Don't delete marks from outside the active range. |
| 877 | ;; This shouldn't happen, but is a sanity check. | 877 | ;; This shouldn't happen, but is a sanity check. |
| 878 | (setq del (gnus-sorted-range-intersection | 878 | (setq del (range-intersection |
| 879 | (gnus-active artgroup) del)) | 879 | (gnus-active artgroup) del)) |
| 880 | (push (list del 'del (list type)) delta-marks)))) | 880 | (push (list del 'del (list type)) delta-marks)))) |
| 881 | 881 | ||
| @@ -910,18 +910,18 @@ article came from is also searched." | |||
| 910 | (< (car elt1) (car elt2)))))) | 910 | (< (car elt1) (car elt2)))))) |
| 911 | (t | 911 | (t |
| 912 | (setq list | 912 | (setq list |
| 913 | (gnus-compress-sequence | 913 | (range-compress-list |
| 914 | (gnus-sorted-union | 914 | (gnus-sorted-union |
| 915 | (gnus-sorted-difference | 915 | (gnus-sorted-difference |
| 916 | (gnus-uncompress-sequence | 916 | (gnus-uncompress-sequence |
| 917 | (alist-get type (gnus-info-marks group-info))) | 917 | (alist-get type (gnus-info-marks group-info))) |
| 918 | artlist) | 918 | artlist) |
| 919 | (sort list #'<)) t))) | 919 | (sort list #'<))))) |
| 920 | 920 | ||
| 921 | ;; When exiting the group, everything that's previously been | 921 | ;; When exiting the group, everything that's previously been |
| 922 | ;; unseen is now seen. | 922 | ;; unseen is now seen. |
| 923 | (when (eq type 'seen) | 923 | (when (eq type 'seen) |
| 924 | (setq list (gnus-range-add | 924 | (setq list (range-concat |
| 925 | list (cdr (assoc artgroup select-unseen)))))) | 925 | list (cdr (assoc artgroup select-unseen)))))) |
| 926 | 926 | ||
| 927 | (when (or list (eq type 'unexist)) | 927 | (when (or list (eq type 'unexist)) |
| @@ -944,9 +944,9 @@ article came from is also searched." | |||
| 944 | ;; update read and unread | 944 | ;; update read and unread |
| 945 | (gnus-update-read-articles | 945 | (gnus-update-read-articles |
| 946 | artgroup | 946 | artgroup |
| 947 | (gnus-uncompress-range | 947 | (range-uncompress |
| 948 | (gnus-add-to-range | 948 | (range-add-list |
| 949 | (gnus-remove-from-range | 949 | (range-remove |
| 950 | old-unread | 950 | old-unread |
| 951 | (cdr (assoc artgroup select-reads))) | 951 | (cdr (assoc artgroup select-reads))) |
| 952 | (sort (cdr (assoc artgroup select-unreads)) #'<)))) | 952 | (sort (cdr (assoc artgroup select-unreads)) #'<)))) |
diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el index 7478a2dd0af..cc87a707ce6 100644 --- a/lisp/gnus/nnvirtual.el +++ b/lisp/gnus/nnvirtual.el | |||
| @@ -365,7 +365,7 @@ It is computed from the marks of individual component groups.") | |||
| 365 | (lambda (article) | 365 | (lambda (article) |
| 366 | (nnvirtual-reverse-map-article | 366 | (nnvirtual-reverse-map-article |
| 367 | group article)) | 367 | group article)) |
| 368 | (gnus-uncompress-range | 368 | (range-uncompress |
| 369 | (gnus-group-expire-articles-1 group)))))) | 369 | (gnus-group-expire-articles-1 group)))))) |
| 370 | (sort (delq nil unexpired) #'<))) | 370 | (sort (delq nil unexpired) #'<))) |
| 371 | 371 | ||
diff --git a/test/lisp/emacs-lisp/range-tests.el b/test/lisp/emacs-lisp/range-tests.el new file mode 100644 index 00000000000..d3abbf9da31 --- /dev/null +++ b/test/lisp/emacs-lisp/range-tests.el | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | ;;; range-tests.el --- Tests for range.el -*- lexical-binding: t; -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2021 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 10 | ;; (at your option) any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | ;;; Commentary: | ||
| 21 | |||
| 22 | ;; | ||
| 23 | |||
| 24 | ;;; Code: | ||
| 25 | |||
| 26 | (require 'range) | ||
| 27 | (require 'ert) | ||
| 28 | (require 'ert-x) | ||
| 29 | |||
| 30 | (ert-deftest ranges () | ||
| 31 | (should (equal (range-compress-list '(2 3 4 5 9 11 12 13)) | ||
| 32 | '((2 . 5) 9 (11 . 13)))) | ||
| 33 | (should (equal (range-uncompress '((2 . 5) 9 (11 . 13))) | ||
| 34 | '(2 3 4 5 9 11 12 13))) | ||
| 35 | (should (equal (range-normalize '(1 . 2)) | ||
| 36 | '((1 . 2)))) | ||
| 37 | (should (equal (range-difference '((1 . 10)) | ||
| 38 | '((2 . 7))) | ||
| 39 | '(1 (8 . 10)))) | ||
| 40 | (should (equal (range-intersection '((2 . 5) 9 (11 . 13)) | ||
| 41 | '((5 . 12))) | ||
| 42 | '(5 9 (11 . 12)))) | ||
| 43 | (should (equal (range-add-list '((2 . 5) 9 (11 . 13)) | ||
| 44 | '(10 11 12 15 16 17)) | ||
| 45 | '((2 . 5) (9 . 10) (11 . 13) (15 . 17)))) | ||
| 46 | (should (equal (range-remove (copy-tree '((2 . 5) 9 (11 . 13))) | ||
| 47 | '((5 . 9))) | ||
| 48 | '((2 . 4) (11 . 13)))) | ||
| 49 | (should (range-member-p 9 '((2 . 5) 9 (11 . 13)))) | ||
| 50 | (should (range-member-p 12 '((2 . 5) 9 (11 . 13)))) | ||
| 51 | (should (equal (range-list-intersection | ||
| 52 | '(4 5 6 7 8 9) | ||
| 53 | '((2 . 5) 9 (11 . 13))) | ||
| 54 | '(4 5 9))) | ||
| 55 | (should (equal (range-list-difference | ||
| 56 | '(4 5 6 7 8 9) | ||
| 57 | '((2 . 5) 9 (11 . 13))) | ||
| 58 | '(6 7 8))) | ||
| 59 | (should (equal (range-length '((2 . 5) 9 (11 . 13))) | ||
| 60 | 8)) | ||
| 61 | (should (equal (range-concat '((2 . 5) 9 (11 . 13)) | ||
| 62 | '(6 (12 . 15))) | ||
| 63 | '((2 . 6) 9 (11 . 15))))) | ||
| 64 | |||
| 65 | ;;; range-tests.el ends here | ||