summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2020-09-04 21:50:03 -0700
committerSean Whitton <spwhitton@spwhitton.name>2020-09-04 21:50:03 -0700
commita516a7d547cc4bd7ea5a0031a828833889e3dc60 (patch)
tree85b3c90d7b3cc371967782b7fd3863ba11bd6669
parentff8d10f3d2534ab7c91af3d7ede7353d65d0f3a1 (diff)
New upstream version 2.22
-rw-r--r--ChangeLog4
-rw-r--r--seq-24.el4
-rw-r--r--seq-25.el189
-rw-r--r--seq-pkg.el4
-rw-r--r--seq.el6
5 files changed, 141 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog
index 07f4988..43f0cfe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2020-09-04 Stefan Kangas <stefankangas@gmail.com>
+
+ ; Sync seq.el with Emacs master and bump version to 2.22
+
2017-05-04 Nicolas Petton <nicolas@petton.fr>
Update seq.el to 2.20
diff --git a/seq-24.el b/seq-24.el
index d7ea729..3ca0964 100644
--- a/seq-24.el
+++ b/seq-24.el
@@ -1,6 +1,6 @@
;;; seq-24.el --- seq.el implementation for Emacs 24.x -*- lexical-binding: t -*-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
@@ -20,7 +20,7 @@
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
diff --git a/seq-25.el b/seq-25.el
index d26bde6..d3f8277 100644
--- a/seq-25.el
+++ b/seq-25.el
@@ -1,6 +1,6 @@
;;; seq-25.el --- seq.el implementation for Emacs 25.x -*- lexical-binding: t -*-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
@@ -20,7 +20,7 @@
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
@@ -60,8 +60,11 @@
(seq--when-emacs-25-p
-(require 'cl-generic)
-(require 'cl-lib) ;; for cl-subseq
+ (eval-when-compile (require 'cl-generic))
+
+;; We used to use some sequence functions from cl-lib, but this
+;; dependency was swapped around so that it will be easier to make
+;; seq.el preloaded in the future. See also Bug#39761#26.
(defmacro seq-doseq (spec &rest body)
"Loop over a sequence.
@@ -114,6 +117,14 @@ name to be bound to the rest of SEQUENCE."
"Return the number of elements of SEQUENCE."
(length sequence))
+(defun seq-first (sequence)
+ "Return the first element of SEQUENCE."
+ (seq-elt sequence 0))
+
+(defun seq-rest (sequence)
+ "Return a sequence of the elements of SEQUENCE except the first one."
+ (seq-drop sequence 1))
+
(cl-defgeneric seq-do (function sequence)
"Apply FUNCTION to each element of SEQUENCE, presumably for side effects.
Return SEQUENCE."
@@ -121,9 +132,19 @@ Return SEQUENCE."
(defalias 'seq-each #'seq-do)
-(cl-defgeneric seqp (sequence)
- "Return non-nil if SEQUENCE is a sequence, nil otherwise."
- (sequencep sequence))
+(defun seq-do-indexed (function sequence)
+ "Apply FUNCTION to each element of SEQUENCE and return nil.
+Unlike `seq-map', FUNCTION takes two arguments: the element of
+the sequence, and its index within the sequence."
+ (let ((index 0))
+ (seq-do (lambda (elt)
+ (funcall function elt index)
+ (setq index (1+ index)))
+ sequence)))
+
+(cl-defgeneric seqp (object)
+ "Return non-nil if OBJECT is a sequence, nil otherwise."
+ (sequencep object))
(cl-defgeneric seq-copy (sequence)
"Return a shallow copy of SEQUENCE."
@@ -137,7 +158,27 @@ If END is omitted, it defaults to the length of the sequence. If
START or END is negative, it counts from the end. Signal an
error if START or END are outside of the sequence (i.e too large
if positive or too small if negative)."
- (cl-subseq sequence start end))
+ (cond
+ ((or (stringp sequence) (vectorp sequence)) (substring sequence start end))
+ ((listp sequence)
+ (let (len
+ (errtext (format "Bad bounding indices: %s, %s" start end)))
+ (and end (< end 0) (setq end (+ end (setq len (length sequence)))))
+ (if (< start 0) (setq start (+ start (or len (setq len (length sequence))))))
+ (unless (>= start 0)
+ (error "%s" errtext))
+ (when (> start 0)
+ (setq sequence (nthcdr (1- start) sequence))
+ (or sequence (error "%s" errtext))
+ (setq sequence (cdr sequence)))
+ (if end
+ (let ((res nil))
+ (while (and (>= (setq end (1- end)) start) sequence)
+ (push (pop sequence) res))
+ (or (= (1+ end) start) (error "%s" errtext))
+ (nreverse res))
+ (copy-sequence sequence))))
+ (t (error "Unsupported sequence: %s" sequence))))
(cl-defgeneric seq-map (function sequence)
@@ -159,6 +200,7 @@ the sequence, and its index within the sequence."
(setq index (1+ index))))
sequence)))
+
;; faster implementation for sequences (sequencep)
(cl-defmethod seq-map (function (sequence sequence))
(mapcar function sequence))
@@ -219,6 +261,9 @@ The result is a sequence of the same type as SEQUENCE."
(let ((result (seq-sort pred (append sequence nil))))
(seq-into result (type-of sequence))))
+(cl-defmethod seq-sort (pred (list list))
+ (sort (seq-copy list) pred))
+
(defun seq-sort-by (function pred sequence)
"Sort SEQUENCE using PRED as a comparison function.
Elements of SEQUENCE are transformed by FUNCTION before being
@@ -229,9 +274,6 @@ sorted. FUNCTION must be a function of one argument."
(funcall function b)))
sequence))
-(cl-defmethod seq-sort (pred (list list))
- (sort (seq-copy list) pred))
-
(cl-defgeneric seq-reverse (sequence)
"Return a sequence with elements of SEQUENCE in reverse order."
(let ((result '()))
@@ -249,7 +291,11 @@ sorted. FUNCTION must be a function of one argument."
TYPE must be one of following symbols: vector, string or list.
\n(fn TYPE SEQUENCE...)"
- (apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences)))
+ (pcase type
+ ('vector (apply #'vconcat sequences))
+ ('string (apply #'concat sequences))
+ ('list (apply #'append (append sequences '(nil))))
+ (_ (error "Not a sequence type name: %S" type))))
(cl-defgeneric seq-into-sequence (sequence)
"Convert SEQUENCE into a sequence.
@@ -310,7 +356,8 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called."
t))
(cl-defgeneric seq-some (pred sequence)
- "Return the first value for which if (PRED element) is non-nil for in SEQUENCE."
+ "Return non-nil if PRED is satisfied for at least one element of SEQUENCE.
+If so, return the first non-nil value returned by PRED."
(catch 'seq--break
(seq-doseq (elt sequence)
(let ((result (funcall pred elt)))
@@ -340,17 +387,28 @@ found or not."
count))
(cl-defgeneric seq-contains (sequence elt &optional testfn)
+ (declare (obsolete seq-contains-p "27.1"))
"Return the first element in SEQUENCE that is equal to ELT.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-some (lambda (e)
- (funcall (or testfn #'equal) elt e))
+ (when (funcall (or testfn #'equal) elt e)
+ e))
sequence))
+(cl-defgeneric seq-contains-p (sequence elt &optional testfn)
+ "Return non-nil if SEQUENCE contains an element equal to ELT.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+ (catch 'seq--break
+ (seq-doseq (e sequence)
+ (when (funcall (or testfn #'equal) e elt)
+ (throw 'seq--break t)))
+ nil))
+
(cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn)
"Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
- (and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1)
- (seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2)))
+ (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1)
+ (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2)))
(cl-defgeneric seq-position (sequence elt &optional testfn)
"Return the index of the first element in SEQUENCE that is equal to ELT.
@@ -368,7 +426,7 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
TESTFN is used to compare elements, or `equal' if TESTFN is nil."
(let ((result '()))
(seq-doseq (elt sequence)
- (unless (seq-contains result elt testfn)
+ (unless (seq-contains-p result elt testfn)
(setq result (cons elt result))))
(nreverse result)))
@@ -393,7 +451,7 @@ negative integer or 0, nil is returned."
"Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-reduce (lambda (acc elt)
- (if (seq-contains sequence2 elt testfn)
+ (if (seq-contains-p sequence2 elt testfn)
(cons elt acc)
acc))
(seq-reverse sequence1)
@@ -403,9 +461,9 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
"Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-reduce (lambda (acc elt)
- (if (not (seq-contains sequence2 elt testfn))
- (cons elt acc)
- acc))
+ (if (seq-contains-p sequence2 elt testfn)
+ acc
+ (cons elt acc)))
(seq-reverse sequence1)
'()))
@@ -443,6 +501,47 @@ SEQUENCE must be a sequence of numbers or markers."
(setq n (+ 1 n)))
n))
+(defun seq--make-pcase-bindings (args)
+ "Return a list of bindings of the variables in ARGS to the elements of a sequence."
+ (let ((bindings '())
+ (index 0)
+ (rest-marker nil))
+ (seq-doseq (name args)
+ (unless rest-marker
+ (pcase name
+ (`&rest
+ (progn (push `(app (pcase--flip seq-drop ,index)
+ ,(seq--elt-safe args (1+ index)))
+ bindings)
+ (setq rest-marker t)))
+ (_
+ (push `(app (pcase--flip seq--elt-safe ,index) ,name) bindings))))
+ (setq index (1+ index)))
+ bindings))
+
+(defun seq--make-pcase-patterns (args)
+ "Return a list of `(seq ...)' pcase patterns from the argument list ARGS."
+ (cons 'seq
+ (seq-map (lambda (elt)
+ (if (seqp elt)
+ (seq--make-pcase-patterns elt)
+ elt))
+ args)))
+
+;; TODO: make public?
+(defun seq--elt-safe (sequence n)
+ "Return element of SEQUENCE at the index N.
+If no element is found, return nil."
+ (ignore-errors (seq-elt sequence n)))
+
+(cl-defgeneric seq-random-elt (sequence)
+ "Return a random element from SEQUENCE.
+Signal an error if SEQUENCE is empty."
+ (if (seq-empty-p sequence)
+ (error "Sequence cannot be empty")
+ (seq-elt sequence (random (seq-length sequence)))))
+
+
;;; Optimized implementations for lists
(cl-defmethod seq-drop ((list list) n)
@@ -466,8 +565,8 @@ SEQUENCE must be a sequence of numbers or markers."
(cl-defmethod seq-empty-p ((list list))
"Optimized implementation of `seq-empty-p' for lists."
(null list))
-
+
(defun seq--into-list (sequence)
"Concatenate the elements of SEQUENCE into a list."
(if (listp sequence)
@@ -486,45 +585,17 @@ SEQUENCE must be a sequence of numbers or markers."
sequence
(concat sequence)))
-(defun seq--make-pcase-bindings (args)
- "Return a list of bindings of the variables in ARGS to the elements of a sequence."
- (let ((bindings '())
- (index 0)
- (rest-marker nil))
- (seq-doseq (name args)
- (unless rest-marker
- (pcase name
- (`&rest
- (progn (push `(app (pcase--flip seq-drop ,index)
- ,(seq--elt-safe args (1+ index)))
- bindings)
- (setq rest-marker t)))
- (_
- (push `(app (pcase--flip seq--elt-safe ,index) ,name) bindings))))
- (setq index (1+ index)))
- bindings))
+(defun seq--activate-font-lock-keywords ()
+ "Activate font-lock keywords for some symbols defined in seq."
+ (font-lock-add-keywords 'emacs-lisp-mode
+ '("\\<seq-doseq\\>" "\\<seq-let\\>")))
-(defun seq--make-pcase-patterns (args)
- "Return a list of `(seq ...)' pcase patterns from the argument list ARGS."
- (cons 'seq
- (seq-map (lambda (elt)
- (if (seqp elt)
- (seq--make-pcase-patterns elt)
- elt))
- args)))
-
-;; TODO: make public?
-(defun seq--elt-safe (sequence n)
- "Return element of SEQUENCE at the index N.
-If no element is found, return nil."
- (ignore-errors (seq-elt sequence n))))
+(unless (fboundp 'elisp--font-lock-flush-elisp-buffers)
+ ;; In Emacsā‰„25, (via elisp--font-lock-flush-elisp-buffers and a few others)
+ ;; we automatically highlight macros.
+ (add-hook 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords))
-(cl-defgeneric seq-random-elt (sequence)
- "Return a random element from SEQUENCE.
-Signal an error if SEQUENCE is empty."
- (if (seq-empty-p sequence)
- (error "Sequence cannot be empty")
- (seq-elt sequence (random (seq-length sequence)))))
+) ; end seq--when-emacs-25-p
(provide 'seq-25)
;;; seq-25.el ends here
diff --git a/seq-pkg.el b/seq-pkg.el
index 0ce3587..8a0cffb 100644
--- a/seq-pkg.el
+++ b/seq-pkg.el
@@ -1,2 +1,2 @@
-;; Generated package description from seq.el
-(define-package "seq" "2.20" "Sequence manipulation functions" 'nil :url "http://elpa.gnu.org/packages/seq.html" :keywords '("sequences"))
+;; Generated package description from seq.el -*- no-byte-compile: t -*-
+(define-package "seq" "2.22" "Sequence manipulation functions" 'nil :url "http://elpa.gnu.org/packages/seq.html" :keywords '("sequences") :authors '(("Nicolas Petton" . "nicolas@petton.fr")) :maintainer '(nil . "emacs-devel@gnu.org"))
diff --git a/seq.el b/seq.el
index 83d4392..d02e25a 100644
--- a/seq.el
+++ b/seq.el
@@ -1,10 +1,10 @@
;;; seq.el --- Sequence manipulation functions -*- lexical-binding: t -*-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
-;; Version: 2.20
+;; Version: 2.22
;; Package: seq
;; Maintainer: emacs-devel@gnu.org
@@ -22,7 +22,7 @@
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary: