diff options
| -rw-r--r-- | doc/lispref/sequences.texi | 14 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/seq.el | 15 | ||||
| -rw-r--r-- | lisp/emacs-lisp/shortdoc.el | 2 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/seq-tests.el | 21 |
5 files changed, 56 insertions, 0 deletions
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index c3f4cff3015..39230d0adc4 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi | |||
| @@ -577,6 +577,20 @@ starting from the first one for which @var{predicate} returns @code{nil}. | |||
| 577 | @end example | 577 | @end example |
| 578 | @end defun | 578 | @end defun |
| 579 | 579 | ||
| 580 | @defun seq-split sequence length | ||
| 581 | This function returns a list consisting of sub-sequences of | ||
| 582 | @var{sequence} of (at most) length @var{length}. (The final element | ||
| 583 | may be shorter than @var{length} if the length of @var{sequence} isn't | ||
| 584 | a multiple of @var{length}. | ||
| 585 | |||
| 586 | @example | ||
| 587 | @group | ||
| 588 | (seq-split [0 1 2 3 4] 2) | ||
| 589 | @result{} ([0 1] [2 3] [4]) | ||
| 590 | @end group | ||
| 591 | @end example | ||
| 592 | @end defun | ||
| 593 | |||
| 580 | @defun seq-do function sequence | 594 | @defun seq-do function sequence |
| 581 | This function applies @var{function} to each element of | 595 | This function applies @var{function} to each element of |
| 582 | @var{sequence} in turn (presumably for side effects), and returns | 596 | @var{sequence} in turn (presumably for side effects), and returns |
| @@ -2251,6 +2251,10 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el. | |||
| 2251 | * Lisp Changes in Emacs 29.1 | 2251 | * Lisp Changes in Emacs 29.1 |
| 2252 | 2252 | ||
| 2253 | +++ | 2253 | +++ |
| 2254 | ** New function 'seq-split'. | ||
| 2255 | This returns a list of sub-sequences of the specified sequence. | ||
| 2256 | |||
| 2257 | +++ | ||
| 2254 | ** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'. | 2258 | ** 'plist-get', 'plist-put' and 'plist-member' are no longer limited to 'eq'. |
| 2255 | These function now take an optional comparison predicate argument. | 2259 | These function now take an optional comparison predicate argument. |
| 2256 | 2260 | ||
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 947b64e8687..36c17f4cd5e 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el | |||
| @@ -632,5 +632,20 @@ Signal an error if SEQUENCE is empty." | |||
| 632 | ;; we automatically highlight macros. | 632 | ;; we automatically highlight macros. |
| 633 | (add-hook 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)) | 633 | (add-hook 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)) |
| 634 | 634 | ||
| 635 | (defun seq-split (sequence length) | ||
| 636 | "Split SEQUENCE into a list of sub-sequences of at most LENGTH. | ||
| 637 | All the sub-sequences will be of LENGTH, except the last one, | ||
| 638 | which may be shorter." | ||
| 639 | (when (< length 1) | ||
| 640 | (error "Sub-sequence length must be larger than zero")) | ||
| 641 | (let ((result nil) | ||
| 642 | (seq-length (length sequence)) | ||
| 643 | (start 0)) | ||
| 644 | (while (< start seq-length) | ||
| 645 | (push (seq-subseq sequence start | ||
| 646 | (setq start (min seq-length (+ start length)))) | ||
| 647 | result)) | ||
| 648 | (nreverse result))) | ||
| 649 | |||
| 635 | (provide 'seq) | 650 | (provide 'seq) |
| 636 | ;;; seq.el ends here | 651 | ;;; seq.el ends here |
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index c82aa3365cd..f53e783111c 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el | |||
| @@ -889,6 +889,8 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), | |||
| 889 | :eval (seq-subseq '(a b c d e) 2 4)) | 889 | :eval (seq-subseq '(a b c d e) 2 4)) |
| 890 | (seq-take | 890 | (seq-take |
| 891 | :eval (seq-take '(a b c d e) 3)) | 891 | :eval (seq-take '(a b c d e) 3)) |
| 892 | (seq-split | ||
| 893 | :eval (seq-split [0 1 2 3 5] 2)) | ||
| 892 | (seq-take-while | 894 | (seq-take-while |
| 893 | :eval (seq-take-while #'cl-evenp [2 4 9 6 5])) | 895 | :eval (seq-take-while #'cl-evenp [2 4 9 6 5])) |
| 894 | (seq-uniq | 896 | (seq-uniq |
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 9e5d59163f9..d979604910e 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el | |||
| @@ -511,5 +511,26 @@ Evaluate BODY for each created sequence. | |||
| 511 | (should (equal (seq-difference '(1 nil) '(2 nil)) | 511 | (should (equal (seq-difference '(1 nil) '(2 nil)) |
| 512 | '(1))))) | 512 | '(1))))) |
| 513 | 513 | ||
| 514 | (ert-deftest test-seq-split () | ||
| 515 | (let ((seq [0 1 2 3 4 5 6 7 8 9 10])) | ||
| 516 | (should (equal seq (car (seq-split seq 20)))) | ||
| 517 | (should (equal seq (car (seq-split seq 11)))) | ||
| 518 | (should (equal (seq-split seq 10) | ||
| 519 | '([0 1 2 3 4 5 6 7 8 9] [10]))) | ||
| 520 | (should (equal (seq-split seq 5) | ||
| 521 | '([0 1 2 3 4] [5 6 7 8 9] [10]))) | ||
| 522 | (should (equal (seq-split seq 1) | ||
| 523 | '([0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]))) | ||
| 524 | (should-error (seq-split seq 0)) | ||
| 525 | (should-error (seq-split seq -10))) | ||
| 526 | (let ((seq '(0 1 2 3 4 5 6 7 8 9))) | ||
| 527 | (should (equal (seq-split seq 5) | ||
| 528 | '((0 1 2 3 4) (5 6 7 8 9))))) | ||
| 529 | (let ((seq "0123456789")) | ||
| 530 | (should (equal (seq-split seq 2) | ||
| 531 | '("01" "23" "45" "67" "89"))) | ||
| 532 | (should (equal (seq-split seq 3) | ||
| 533 | '("012" "345" "678" "9"))))) | ||
| 534 | |||
| 514 | (provide 'seq-tests) | 535 | (provide 'seq-tests) |
| 515 | ;;; seq-tests.el ends here | 536 | ;;; seq-tests.el ends here |