branch: externals/seq commit 9d9f51b0e3ca59e0a488801064512f4878ac910b Author: Stefan Kangas <stefankan...@gmail.com> Commit: Stefan Kangas <stefankan...@gmail.com>
Sync seq.el with Emacs master and bump version to 2.24 --- seq-24.el | 2 +- seq-25.el | 268 ++++++++++++++++++++++++++++++++++++++++++++------------------ seq.el | 15 +++- 3 files changed, 205 insertions(+), 80 deletions(-) diff --git a/seq-24.el b/seq-24.el index 3ca0964a49..51c3e36c24 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-2020 Free Software Foundation, Inc. +;; Copyright (C) 2014-2023 Free Software Foundation, Inc. ;; Author: Nicolas Petton <nico...@petton.fr> ;; Keywords: sequences diff --git a/seq-25.el b/seq-25.el index 30379ca044..55c78b49a7 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-2021 Free Software Foundation, Inc. +;; Copyright (C) 2014-2023 Free Software Foundation, Inc. ;; Author: Nicolas Petton <nico...@petton.fr> ;; Keywords: sequences @@ -58,17 +58,29 @@ (when (version<= "25" emacs-version) `(progn ,@body))) +(defalias 'seq--take + (if (>= emacs-major-version 29) + 'take + (lambda (n list) ; copied here from the `compat' package + "Return the first N elements of LIST. +If N is zero or negative, return nil. +If N is greater or equal to the length of LIST, return LIST (or a copy)." + (let (copy) + (while (and (< 0 n) list) + (push (pop list) copy) + (setq n (1- n))) + (nreverse copy))))) + (seq--when-emacs-25-p (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. +;; dependency was swapped around so that it's easier to make seq.el +;; preloaded. See also Bug#39761#26. (defmacro seq-doseq (spec &rest body) - "Loop over a sequence. -Evaluate BODY with VAR bound to each element of SEQUENCE, in turn. + "Loop over a SEQUENCE, evaluating BODY with VAR bound to each of its elements. Similar to `dolist' but can be applied to lists, strings, and vectors. @@ -99,7 +111,7 @@ name to be bound to the rest of SEQUENCE." ,@body)) (defmacro seq-setq (args sequence) - "Assign to the variables in ARGS the elements of SEQUENCE. + "Assign the elements of SEQUENCE to the variables in ARGS. ARGS can also include the `&rest' marker followed by a variable name to be bound to the rest of SEQUENCE." @@ -109,7 +121,7 @@ name to be bound to the rest of SEQUENCE." ;;; Basic seq functions that have to be implemented by new sequence types (cl-defgeneric seq-elt (sequence n) - "Return Nth element of SEQUENCE." + "Return the Nth element of SEQUENCE." (elt sequence n)) ;; Default gv setters for `seq-elt'. @@ -122,7 +134,7 @@ name to be bound to the rest of SEQUENCE." (setcar (nthcdr n sequence) store)) (cl-defgeneric seq-length (sequence) - "Return the number of elements of SEQUENCE." + "Return the number of elements in SEQUENCE." (length sequence)) (defun seq-first (sequence) @@ -130,11 +142,12 @@ name to be bound to the rest of SEQUENCE." (seq-elt sequence 0)) (defun seq-rest (sequence) - "Return a sequence of the elements of SEQUENCE except the first one." + "Return SEQUENCE with its first element removed." (seq-drop sequence 1)) (cl-defgeneric seq-do (function sequence) - "Apply FUNCTION to each element of SEQUENCE, presumably for side effects. + "Apply FUNCTION to each element of SEQUENCE. +Presumably, FUNCTION has useful side effects. Return SEQUENCE." (mapc function sequence)) @@ -159,6 +172,7 @@ the sequence, and its index within the sequence." "Return a shallow copy of SEQUENCE." (copy-sequence sequence)) +;;;###autoload (cl-defgeneric seq-subseq (sequence start &optional end) "Return the sequence of elements of SEQUENCE from START to END. END is exclusive. @@ -171,21 +185,25 @@ if positive or too small if negative)." ((or (stringp sequence) (vectorp sequence)) (substring sequence start end)) ((listp sequence) (let (len - (errtext (format "Bad bounding indices: %s, %s" start end))) + (orig-start start) + (orig-end 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)) + (error "Start index out of bounds: %s" orig-start)) (when (> start 0) (setq sequence (nthcdr (1- start) sequence)) - (or sequence (error "%s" errtext)) + (unless sequence + (error "Start index out of bounds: %s" orig-start)) (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)) + (let ((n (- end start))) + (when (or (< n 0) + (if len + (> end len) + (and (> n 0) (null (nthcdr (1- n) sequence))))) + (error "End index out of bounds: %s" orig-end)) + (seq--take n sequence)) (copy-sequence sequence)))) (t (error "Unsupported sequence: %s" sequence)))) @@ -215,8 +233,9 @@ the sequence, and its index within the sequence." (mapcar function sequence)) (cl-defgeneric seq-mapn (function sequence &rest sequences) - "Like `seq-map' but FUNCTION is mapped over all SEQUENCES. -The arity of FUNCTION must match the number of SEQUENCES, and the + "Return the result of applying FUNCTION to each element of SEQUENCEs. +Like `seq-map', but FUNCTION is mapped over all SEQUENCEs. +The arity of FUNCTION must match the number of SEQUENCEs, and the mapping stops on the shortest sequence. Return a list of the results. @@ -231,7 +250,7 @@ Return a list of the results. (nreverse result))) (cl-defgeneric seq-drop (sequence n) - "Remove the first N elements of SEQUENCE and return the result. + "Remove the first N elements of SEQUENCE and return the resulting sequence. The result is a sequence of the same type as SEQUENCE. If N is a negative integer or zero, SEQUENCE is returned." @@ -240,8 +259,9 @@ If N is a negative integer or zero, SEQUENCE is returned." (let ((length (seq-length sequence))) (seq-subseq sequence (min n length) length)))) +;;;###autoload (cl-defgeneric seq-take (sequence n) - "Take the first N elements of SEQUENCE and return the result. + "Return the sequence made of the first N elements of SEQUENCE. The result is a sequence of the same type as SEQUENCE. If N is a negative integer or zero, an empty sequence is @@ -250,14 +270,17 @@ returned." (cl-defgeneric seq-drop-while (pred sequence) "Remove the successive elements of SEQUENCE for which PRED returns non-nil. -PRED is a function of one argument. The result is a sequence of -the same type as SEQUENCE." +PRED is a function of one argument. The function keeps removing +elements from SEQUENCE until PRED returns nil for an element. +Value is a sequence of the same type as SEQUENCE." (seq-drop sequence (seq--count-successive pred sequence))) (cl-defgeneric seq-take-while (pred sequence) "Take the successive elements of SEQUENCE for which PRED returns non-nil. -PRED is a function of one argument. The result is a sequence of -the same type as SEQUENCE." +PRED is a function of one argument. The function keeps collecting +elements from SEQUENCE and adding them to the result until PRED +returns nil for an element. +Value is a sequence of the same type as SEQUENCE." (seq-take sequence (seq--count-successive pred sequence))) (cl-defgeneric seq-empty-p (sequence) @@ -265,7 +288,7 @@ the same type as SEQUENCE." (= 0 (seq-length sequence))) (cl-defgeneric seq-sort (pred sequence) - "Sort SEQUENCE using PRED as comparison function. + "Sort SEQUENCE using PRED as the sorting comparison function. 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)))) @@ -273,8 +296,9 @@ The result is a sequence of the same type as SEQUENCE." (cl-defmethod seq-sort (pred (list list)) (sort (seq-copy list) pred)) +;;;###autoload (defun seq-sort-by (function pred sequence) - "Sort SEQUENCE using PRED as a comparison function. + "Sort SEQUENCE transformed by FUNCTION using PRED as the comparison function. Elements of SEQUENCE are transformed by FUNCTION before being sorted. FUNCTION must be a function of one argument." (seq-sort (lambda (a b) @@ -297,9 +321,10 @@ sorted. FUNCTION must be a function of one argument." (cl-defgeneric seq-concatenate (type &rest sequences) "Concatenate SEQUENCES into a single sequence of type TYPE. -TYPE must be one of following symbols: vector, string or list. +TYPE must be one of following symbols: `vector', `string' or `list'. \n(fn TYPE SEQUENCE...)" + (setq sequences (mapcar #'seq-into-sequence sequences)) (pcase type ('vector (apply #'vconcat sequences)) ('string (apply #'concat sequences)) @@ -318,16 +343,17 @@ of sequence." (cl-defgeneric seq-into (sequence type) "Concatenate the elements of SEQUENCE into a sequence of type TYPE. -TYPE can be one of the following symbols: vector, string or -list." +TYPE can be one of the following symbols: `vector', `string' or +`list'." (pcase type (`vector (seq--into-vector sequence)) (`string (seq--into-string sequence)) (`list (seq--into-list sequence)) (_ (error "Not a sequence type name: %S" type)))) +;;;###autoload (cl-defgeneric seq-filter (pred sequence) - "Return a list of all elements for which (PRED element) is non-nil in SEQUENCE." + "Return a list of all the elements in SEQUENCE for which PRED returns non-nil." (let ((exclude (make-symbol "exclude"))) (delq exclude (seq-map (lambda (elt) (if (funcall pred elt) @@ -335,11 +361,27 @@ list." exclude)) sequence)))) +;;;###autoload (cl-defgeneric seq-remove (pred sequence) - "Return a list of all the elements for which (PRED element) is nil in SEQUENCE." + "Return a list of all the elements in SEQUENCE for which PRED returns nil." (seq-filter (lambda (elt) (not (funcall pred elt))) sequence)) +;;;###autoload +(cl-defgeneric seq-remove-at-position (sequence n) + "Return a copy of SEQUENCE with the element at index N removed. + +N is the (zero-based) index of the element that should not be in +the result. + +The result is a sequence of the same type as SEQUENCE." + (seq-concatenate + (let ((type (type-of sequence))) + (if (eq type 'cons) 'list type)) + (seq-subseq sequence 0 n) + (seq-subseq sequence (1+ n)))) + +;;;###autoload (cl-defgeneric seq-reduce (function sequence initial-value) "Reduce the function FUNCTION across SEQUENCE, starting with INITIAL-VALUE. @@ -358,17 +400,19 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." (setq acc (funcall function acc elt))) acc))) +;;;###autoload (cl-defgeneric seq-every-p (pred sequence) - "Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE." + "Return non-nil if PRED returns non-nil for all the elements of SEQUENCE." (catch 'seq--break (seq-doseq (elt sequence) (or (funcall pred elt) (throw 'seq--break nil))) t)) +;;;###autoload (cl-defgeneric seq-some (pred 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." + "Return non-nil if PRED returns non-nil for at least one element of SEQUENCE. +If the value is non-nil, it is the first non-nil value returned by PRED." (catch 'seq--break (seq-doseq (elt sequence) (let ((result (funcall pred elt))) @@ -376,13 +420,14 @@ If so, return the first non-nil value returned by PRED." (throw 'seq--break result)))) nil)) +;;;###autoload (cl-defgeneric seq-find (pred sequence &optional default) - "Return the first element for which (PRED element) is non-nil in SEQUENCE. -If no element is found, return DEFAULT. + "Return the first element in SEQUENCE for which PRED returns non-nil. +If no such element is found, return DEFAULT. Note that `seq-find' has an ambiguity if the found element is -identical to DEFAULT, as it cannot be known if an element was -found or not." +identical to DEFAULT, as in that case it is impossible to know +whether an element was found or not." (catch 'seq--break (seq-doseq (elt sequence) (when (funcall pred elt) @@ -390,17 +435,16 @@ found or not." default)) (cl-defgeneric seq-count (pred sequence) - "Return the number of elements for which (PRED element) is non-nil in SEQUENCE." + "Return the number of elements in SEQUENCE for which PRED returns non-nil." (let ((count 0)) (seq-doseq (elt sequence) (when (funcall pred elt) (setq count (+ 1 count)))) count)) -;; Can't use `with-suppressed-warnings' as that was added in 27.1. (cl-defgeneric seq-contains (sequence elt &optional testfn) - "Return the first element in SEQUENCE that is equal to ELT. -Equality is defined by TESTFN if non-nil or by `equal' if nil." + "Return the first element in SEQUENCE that is \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." (declare (obsolete seq-contains-p "27.1")) (seq-some (lambda (e) (when (funcall (or testfn #'equal) elt e) @@ -408,24 +452,27 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil." 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)) + "Return non-nil if SEQUENCE contains an element \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." + (catch 'seq--break + (seq-doseq (e sequence) + (let ((r (funcall (or testfn #'equal) e elt))) + (when r + (throw 'seq--break r)))) + nil)) (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements. -This does not depend on the order of the elements. -Equality is defined by TESTFN if non-nil or by `equal' if nil." +The order of the elements in the sequences is not important. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (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))) +;;;###autoload (cl-defgeneric seq-position (sequence elt &optional testfn) - "Return the index of the first element in SEQUENCE that is equal to ELT. -Equality is defined by TESTFN if non-nil or by `equal' if nil." + "Return the (zero-based) index of the first element in SEQUENCE \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." (let ((index 0)) (catch 'seq--break (seq-doseq (e sequence) @@ -434,25 +481,70 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil." (setq index (1+ index))) nil))) +;;;###autoload +(cl-defgeneric seq-positions (sequence elt &optional testfn) + "Return list of indices of SEQUENCE elements for which TESTFN returns non-nil. + +TESTFN is a two-argument function which is called with each element of +SEQUENCE as the first argument and ELT as the second. +TESTFN defaults to `equal'. + +The result is a list of (zero-based) indices." + (let ((result '())) + (seq-do-indexed + (lambda (e index) + (when (funcall (or testfn #'equal) e elt) + (push index result))) + sequence) + (nreverse result))) + +;;;###autoload (cl-defgeneric seq-uniq (sequence &optional testfn) "Return a list of the elements of SEQUENCE with duplicates removed. -TESTFN is used to compare elements, or `equal' if TESTFN is nil." +TESTFN is used to compare elements, and defaults to `equal'." (let ((result '())) (seq-doseq (elt sequence) (unless (seq-contains-p result elt testfn) (setq result (cons elt result)))) (nreverse result))) +(cl-defmethod seq-uniq ((sequence list) &optional testfn) + (let ((result nil)) + (if (not testfn) + ;; Fast path. If the list is long, use a hash table to speed + ;; things up even more. + (let ((l (length sequence))) + (if (> l 100) + (let ((hash (make-hash-table :test #'equal :size l))) + (while sequence + (unless (gethash (car sequence) hash) + (setf (gethash (car sequence) hash) t) + (push (car sequence) result)) + (setq sequence (cdr sequence)))) + ;; Short list. + (while sequence + (unless (member (car sequence) result) + (push (car sequence) result)) + (pop sequence)))) + ;; Slower path. + (while sequence + (unless (seq-find (lambda (elem) + (funcall testfn elem (car sequence))) + result) + (push (car sequence) result)) + (pop sequence))) + (nreverse result))) + (cl-defgeneric seq-mapcat (function sequence &optional type) - "Concatenate the result of applying FUNCTION to each element of SEQUENCE. -The result is a sequence of type TYPE, or a list if TYPE is nil." + "Concatenate the results of applying FUNCTION to each element of SEQUENCE. +The result is a sequence of type TYPE; TYPE defaults to `list'." (apply #'seq-concatenate (or type 'list) (seq-map function sequence))) (cl-defgeneric seq-partition (sequence n) "Return list of elements of SEQUENCE grouped into sub-sequences of length N. The last sequence may contain less than N elements. If N is a -negative integer or 0, nil is returned." +negative integer or 0, the function returns nil." (unless (< n 1) (let ((result '())) (while (not (seq-empty-p sequence)) @@ -460,20 +552,24 @@ negative integer or 0, nil is returned." (setq sequence (seq-drop sequence n))) (nreverse result)))) +;;;###autoload (cl-defgeneric seq-union (sequence1 sequence2 &optional testfn) - "Return a list of all elements that appear in either SEQUENCE1 or SEQUENCE2. -Equality is defined by TESTFN if non-nil or by `equal' if nil." + "Return a list of all the elements that appear in either SEQUENCE1 or SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (let* ((accum (lambda (acc elt) (if (seq-contains-p acc elt testfn) acc (cons elt acc)))) (result (seq-reduce accum sequence2 - (seq-reduce accum sequence1 '())))) + (seq-reduce accum sequence1 '())))) (nreverse result))) +;;;###autoload (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) - "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." + "Return a list of all the elements that appear in both SEQUENCE1 and SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) (cons elt acc) @@ -482,8 +578,9 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil." '())) (cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) - "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." + "Return list of all the elements that appear in SEQUENCE1 but not in SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) acc @@ -491,6 +588,7 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil." (seq-reverse sequence1) '())) +;;;###autoload (cl-defgeneric seq-group-by (function sequence) "Apply FUNCTION to each element of SEQUENCE. Separate the elements of SEQUENCE into an alist using the results as @@ -511,13 +609,14 @@ keys. Keys are compared using `equal'." SEQUENCE must be a sequence of numbers or markers." (apply #'min (seq-into sequence 'list))) +;;;###autoload (cl-defgeneric seq-max (sequence) "Return the largest element of SEQUENCE. SEQUENCE must be a sequence of numbers or markers." (apply #'max (seq-into sequence 'list))) (defun seq--count-successive (pred sequence) - "Return the number of successive elements for which (PRED element) is non-nil in SEQUENCE." + "Count successive elements in SEQUENCE for which PRED returns non-nil." (let ((n 0) (len (seq-length sequence))) (while (and (< n len) @@ -526,7 +625,7 @@ SEQUENCE must be a sequence of numbers or markers." n)) (defun seq--make-pcase-bindings (args) - "Return a list of bindings of the variables in ARGS to the elements of a sequence." + "Return list of bindings of the variables in ARGS to the elements of a sequence." (let ((bindings '()) (index 0) (rest-marker nil)) @@ -554,12 +653,13 @@ SEQUENCE must be a sequence of numbers or markers." ;; TODO: make public? (defun seq--elt-safe (sequence n) - "Return element of SEQUENCE at the index N. + "Return the element of SEQUENCE whose zero-based index is N. If no element is found, return nil." (ignore-errors (seq-elt sequence n))) +;;;###autoload (cl-defgeneric seq-random-elt (sequence) - "Return a random element from SEQUENCE. + "Return a randomly chosen element from SEQUENCE. Signal an error if SEQUENCE is empty." (if (seq-empty-p sequence) (error "Sequence cannot be empty") @@ -574,11 +674,7 @@ Signal an error if SEQUENCE is empty." (cl-defmethod seq-take ((list list) n) "Optimized implementation of `seq-take' for lists." - (let ((result '())) - (while (and list (> n 0)) - (setq n (1- n)) - (push (pop list) result)) - (nreverse result))) + (seq--take n list)) (cl-defmethod seq-drop-while (pred (list list)) "Optimized implementation of `seq-drop-while' for lists." @@ -614,12 +710,30 @@ Signal an error if SEQUENCE is empty." (font-lock-add-keywords 'emacs-lisp-mode '("\\<seq-doseq\\>" "\\<seq-let\\>"))) +(defun seq-split (sequence length) + "Split SEQUENCE into a list of sub-sequences of at most LENGTH elements. +All the sub-sequences will be LENGTH long, except the last one, +which may be shorter." + (when (< length 1) + (error "Sub-sequence length must be larger than zero")) + (let ((result nil) + (seq-length (length sequence)) + (start 0)) + (while (< start seq-length) + (push (seq-subseq sequence start + (setq start (min seq-length (+ start length)))) + result)) + (nreverse result))) + +(defun seq-keep (function sequence) + "Apply FUNCTION to SEQUENCE and return the list of all the non-nil results." + (delq nil (seq-map function sequence))) + (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)) ) ; end seq--when-emacs-25-p - (provide 'seq-25) ;;; seq-25.el ends here diff --git a/seq.el b/seq.el index 41db04b849..fa13815517 100644 --- a/seq.el +++ b/seq.el @@ -1,10 +1,10 @@ ;;; seq.el --- Sequence manipulation functions -*- lexical-binding: t -*- -;; Copyright (C) 2014-2020 Free Software Foundation, Inc. +;; Copyright (C) 2014-2023 Free Software Foundation, Inc. ;; Author: Nicolas Petton <nico...@petton.fr> ;; Keywords: sequences -;; Version: 2.23 +;; Version: 2.24 ;; Package: seq ;; Maintainer: emacs-de...@gnu.org @@ -37,6 +37,17 @@ ;; function as argument take the function as their first argument and ;; the sequence as their second argument. All other functions take ;; the sequence as their first argument. +;; +;; seq.el can be extended to support new type of sequences. Here are +;; the generic functions that must be implemented by new seq types: +;; - `seq-elt' +;; - `seq-length' +;; - `seq-do' +;; - `seqp' +;; - `seq-subseq' +;; - `seq-into-sequence' +;; - `seq-copy' +;; - `seq-into' ;;; Code: