all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Kangas <stefankangas@gmail.com>
To: Sean Whitton <spwhitton@spwhitton.name>, emacs-devel@gnu.org
Cc: debian-emacsen@lists.debian.org
Subject: Re: seq.el: requesting an update to the version in GNU ELPA
Date: Sat, 29 Aug 2020 07:52:39 -0700	[thread overview]
Message-ID: <CADwFkm=f9rd+OfhjEtoUEErq+SV0PvpDGD2r+J2TWz+33uCfNQ@mail.gmail.com> (raw)
In-Reply-To: <CADwFkmmVXqjp-4AUW=v7MMWrtUivg8HC77e32-uPbE7XSXBQsA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 586 bytes --]

Stefan Kangas <stefankangas@gmail.com> writes:

> I have bumped the version of seq.el to 2.22 on the Emacs master branch.
>
> IIUC, the new version will be automatically picked up by the GNU ELPA
> scripts and available for installation within 24-48 hours.

It turns out that seq.el is a special case where we have some
compatibility code for Emacs 24, so it needs manual intervention.

The attached patch compiles without warnings on Emacs 26 and 27.
Unfortunately, I don't have Emacs 25 or 24 available for testing.
Could someone please help check that it's okay before I install it?

[-- Attachment #2: 0001-Sync-seq.el-with-Emacs-master-and-bump-version-to-2..patch --]
[-- Type: text/x-diff, Size: 13340 bytes --]

From aa6adc711e990cf1ddeee01c4ffd8a0b37683d11 Mon Sep 17 00:00:00 2001
From: Stefan Kangas <stefankangas@gmail.com>
Date: Sat, 29 Aug 2020 15:55:51 +0200
Subject: [PATCH] ; Sync seq.el with Emacs master and bump version to 2.22

---
 packages/seq/seq-25.el | 189 ++++++++++++++++++++++++++++-------------
 packages/seq/seq.el    |   2 +-
 2 files changed, 131 insertions(+), 60 deletions(-)

diff --git a/packages/seq/seq-25.el b/packages/seq/seq-25.el
index d26bde6ec..d3f827792 100644
--- a/packages/seq/seq-25.el
+++ b/packages/seq/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))))
 
 \f
 (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)))))
+\f
+
 ;;; 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))
-
 \f
+
 (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/packages/seq/seq.el b/packages/seq/seq.el
index 83d43929a..2aa612851 100644
--- a/packages/seq/seq.el
+++ b/packages/seq/seq.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: sequences
-;; Version: 2.20
+;; Version: 2.22
 ;; Package: seq
 
 ;; Maintainer: emacs-devel@gnu.org
-- 
2.28.0


  reply	other threads:[~2020-08-29 14:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-28 21:54 seq.el: requesting an update to the version in GNU ELPA Sean Whitton
2020-08-28 22:56 ` Stefan Kangas
2020-08-29 14:52   ` Stefan Kangas [this message]
2020-09-04 10:46     ` Lev Lamberov
     [not found]       ` <87wo1k0yxd.fsf@localhost>
2020-09-04 11:57         ` Bug#969103: " Stefan Kangas
2020-09-06  0:08           ` [Pkg-emacsen-addons] " Sean Whitton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CADwFkm=f9rd+OfhjEtoUEErq+SV0PvpDGD2r+J2TWz+33uCfNQ@mail.gmail.com' \
    --to=stefankangas@gmail.com \
    --cc=debian-emacsen@lists.debian.org \
    --cc=emacs-devel@gnu.org \
    --cc=spwhitton@spwhitton.name \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.