From c58f8dda2b2282302cf47ef3e7df6523bde606f5 Mon Sep 17 00:00:00 2001 From: Earl Hyatt Date: Sat, 14 Aug 2021 14:17:12 +0200 Subject: Add macro `seq-setq`. * doc/lispref/sequences.texi (seq-setq): Document this macro. * lisp/emacs-lisp/seq.el (seq-setq): New macro. * test/lisp/emacs-lisp/seq-tests.el (test-seq-setq): Test this macro (bug#50053). --- test/lisp/emacs-lisp/seq-tests.el | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test/lisp/emacs-lisp/seq-tests.el') diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 05c7fbe781e..44e855e2cfa 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -383,6 +383,30 @@ Evaluate BODY for each created sequence. (should (null b)) (should (null c))))) +(ert-deftest test-seq-setq () + (with-test-sequences (seq '(1 2 3 4)) + (let (a b c d e) + (seq-setq (a b c d e) seq) + (should (= a 1)) + (should (= b 2)) + (should (= c 3)) + (should (= d 4)) + (should (null e))) + (let (a b others) + (seq-setq (a b &rest others) seq) + (should (= a 1)) + (should (= b 2)) + (should (same-contents-p others (seq-drop seq 2))))) + (let ((a) + (seq '(1 (2 (3 (4)))))) + (seq-setq (_ (_ (_ (a)))) seq) + (should (= a 4))) + (let (seq a b c) + (seq-setq (a b c) seq) + (should (null a)) + (should (null b)) + (should (null c)))) + (ert-deftest test-seq-min-max () (with-test-sequences (seq '(4 5 3 2 0 4)) (should (= (seq-min seq) 0)) -- cgit v1.2.3 From a8a3fd8f8e27089ac46bf98e534529ff03f679a5 Mon Sep 17 00:00:00 2001 From: Earl Hyatt Date: Sat, 14 Aug 2021 14:17:55 +0200 Subject: Add macro `seq-setq`. * doc/lispref/sequences.texi (seq-setq): Document this macro. * test/lisp/emacs-lisp/seq-tests.el (test-seq-setq): Test this macro (bug#50053). --- doc/lispref/sequences.texi | 17 +++++++++++++++++ test/lisp/emacs-lisp/seq-tests.el | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'test/lisp/emacs-lisp/seq-tests.el') diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 20816ce8ca2..257f5d162ea 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -1128,6 +1128,23 @@ assigned to variables as if by @code{setq} instead of as in a @end example @end defmac +@defmac seq-setq var-sequence val-sequence +@cindex sequence destructuring + This macro works similarly to @code{seq-let}, except that values are +assigned to variables as if by @code{setq} instead of as in a +@code{let} binding. + +@example +@group +(let ((a nil) + (b nil)) + (seq-setq (_ a _ b) '(1 2 3 4)) + (list a b)) +@result{} (2 4) +@end group +@end example +@end defmac + @defun seq-random-elt sequence This function returns an element of @var{sequence} taken at random. diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 44e855e2cfa..5217921d3d7 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -407,6 +407,30 @@ Evaluate BODY for each created sequence. (should (null b)) (should (null c)))) +(ert-deftest test-seq-setq () + (with-test-sequences (seq '(1 2 3 4)) + (let (a b c d e) + (seq-setq (a b c d e) seq) + (should (= a 1)) + (should (= b 2)) + (should (= c 3)) + (should (= d 4)) + (should (null e))) + (let (a b others) + (seq-setq (a b &rest others) seq) + (should (= a 1)) + (should (= b 2)) + (should (same-contents-p others (seq-drop seq 2))))) + (let ((a) + (seq '(1 (2 (3 (4)))))) + (seq-setq (_ (_ (_ (a)))) seq) + (should (= a 4))) + (let (seq a b c) + (seq-setq (a b c) seq) + (should (null a)) + (should (null b)) + (should (null c)))) + (ert-deftest test-seq-min-max () (with-test-sequences (seq '(4 5 3 2 0 4)) (should (= (seq-min seq) 0)) -- cgit v1.2.3 From 3fd0cc85a58775e0a09efb88649bea9dd28c5491 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Sat, 14 Aug 2021 15:30:17 +0200 Subject: Revert "Add macro `seq-setq`." This reverts commit a8a3fd8f8e27089ac46bf98e534529ff03f679a5. The same patch was applied twice. Remove the second instance. --- doc/lispref/sequences.texi | 17 ----------------- test/lisp/emacs-lisp/seq-tests.el | 24 ------------------------ 2 files changed, 41 deletions(-) (limited to 'test/lisp/emacs-lisp/seq-tests.el') diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 257f5d162ea..20816ce8ca2 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -1128,23 +1128,6 @@ assigned to variables as if by @code{setq} instead of as in a @end example @end defmac -@defmac seq-setq var-sequence val-sequence -@cindex sequence destructuring - This macro works similarly to @code{seq-let}, except that values are -assigned to variables as if by @code{setq} instead of as in a -@code{let} binding. - -@example -@group -(let ((a nil) - (b nil)) - (seq-setq (_ a _ b) '(1 2 3 4)) - (list a b)) -@result{} (2 4) -@end group -@end example -@end defmac - @defun seq-random-elt sequence This function returns an element of @var{sequence} taken at random. diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 5217921d3d7..44e855e2cfa 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -407,30 +407,6 @@ Evaluate BODY for each created sequence. (should (null b)) (should (null c)))) -(ert-deftest test-seq-setq () - (with-test-sequences (seq '(1 2 3 4)) - (let (a b c d e) - (seq-setq (a b c d e) seq) - (should (= a 1)) - (should (= b 2)) - (should (= c 3)) - (should (= d 4)) - (should (null e))) - (let (a b others) - (seq-setq (a b &rest others) seq) - (should (= a 1)) - (should (= b 2)) - (should (same-contents-p others (seq-drop seq 2))))) - (let ((a) - (seq '(1 (2 (3 (4)))))) - (seq-setq (_ (_ (_ (a)))) seq) - (should (= a 4))) - (let (seq a b c) - (seq-setq (a b c) seq) - (should (null a)) - (should (null b)) - (should (null c)))) - (ert-deftest test-seq-min-max () (with-test-sequences (seq '(4 5 3 2 0 4)) (should (= (seq-min seq) 0)) -- cgit v1.2.3 From 0cf0a2b98671671bb7639a17639ef2552b772cbe Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Fri, 17 Sep 2021 10:35:13 +0200 Subject: Add new sequence function 'seq-union' * lisp/emacs-lisp/seq.el (seq-union): New function. * doc/lispref/sequences.texi (Sequence Functions): * lisp/emacs-lisp/shortdoc.el (sequence): Document above new function. * test/lisp/emacs-lisp/seq-tests.el (test-seq-union): New test. --- doc/lispref/sequences.texi | 16 ++++++++++++++++ etc/NEWS | 5 +++++ lisp/emacs-lisp/seq.el | 11 +++++++++++ lisp/emacs-lisp/shortdoc.el | 2 ++ test/lisp/emacs-lisp/seq-tests.el | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+) (limited to 'test/lisp/emacs-lisp/seq-tests.el') diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 20816ce8ca2..53d37199bf7 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -953,6 +953,22 @@ contain less elements than @var{n}. @var{n} must be an integer. If @end example @end defun +@defun seq-union sequence1 sequence2 &optional function +@cindex sequences, union of +@cindex union of sequences + This function returns a list of the elements that appear either in +@var{sequence1} or @var{sequence2}. If the optional argument +@var{function} is non-@code{nil}, it is a function of two arguments to +use to compare elements instead of the default @code{equal}. + +@example +@group +(seq-union [1 2 3] [3 5]) +@result{} (1 2 3 5) +@end group +@end example +@end defun + @defun seq-intersection sequence1 sequence2 &optional function @cindex sequences, intersection of @cindex intersection of sequences diff --git a/etc/NEWS b/etc/NEWS index eee6d2592bd..b1ad4dd1263 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3855,6 +3855,11 @@ This function is like 'require', but searches 'custom-theme-load-path' instead of 'load-path'. It can be used by Custom themes to load supporting Lisp files when 'require' is unsuitable. ++++ +** New function 'seq-union'. +This function takes two sequences and returns a list of all elements +that appear in either of them. + +++ ** New function 'syntax-class-to-char'. This does almost the opposite of 'string-to-syntax' -- it returns the diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index f0dc283f57d..b7dcde87f41 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -467,6 +467,17 @@ negative integer or 0, nil is returned." (setq sequence (seq-drop sequence n))) (nreverse result)))) +(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." + (let ((accum (lambda (acc elt) + (if (seq-contains-p acc elt testfn) + acc + (cons elt acc))))) + (seq-reverse + (seq-reduce accum sequence2 + (seq-reduce accum sequence1 '()))))) + ;;;###autoload (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index adee6be379d..3e0d5aef022 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -809,6 +809,8 @@ There can be any number of :example/:result elements." :eval (seq-remove #'numberp '(1 2 c d 5))) (seq-group-by :eval (seq-group-by #'cl-plusp '(-1 2 3 -4 -5 6))) + (seq-union + :eval (seq-union '(1 2 3) '(3 5))) (seq-difference :eval (seq-difference '(1 2 3) '(2 3 4))) (seq-intersection diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index 44e855e2cfa..bf79dd922bf 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -336,6 +336,38 @@ Evaluate BODY for each created sequence. (should (same-contents-p list vector)) (should (vectorp vector)))) +(ert-deftest test-seq-union () + (let ((v1 '(1 2 3)) + (v2 '(3 5))) + (should (same-contents-p (seq-union v1 v2) + '(1 2 3 5)))) + + (let ((v1 '(1 2 3 4 5 6)) + (v2 '(4 5 6 7 8 9))) + (should (same-contents-p (seq-union v1 v2) + '(1 2 3 4 5 6 7 8 9)))) + + (let ((v1 '(1 2 3 4 5 6)) + (v2 '(4 5 6 7 8 9))) + (should (same-contents-p (seq-union v1 v2) + '(1 2 3 4 5 6 7 8 9)))) + + (let ((v1 [1 2 3 4 5]) + (v2 [4 5 6 "a"])) + (should (same-contents-p (seq-union v1 v2) + '(1 2 3 4 5 6 "a")))) + + (let ((v1 '("a" "b" "c")) + (v2 '("f" "c" "e" "a"))) + (should (same-contents-p (seq-union v1 v2) + '("a" "b" "c" "f" "e")))) + + (let ((v1 '("a")) + (v2 '("a")) + (testfn #'eq)) + (should (same-contents-p (seq-union v1 v2 testfn) + '("a" "a"))))) + (ert-deftest test-seq-intersection () (let ((v1 [2 3 4 5]) (v2 [1 3 5 6 7])) -- cgit v1.2.3 From 8220df9355e105459e91623dd63f7a08a08cfe09 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Fri, 17 Sep 2021 14:06:18 +0200 Subject: ; * test/lisp/emacs-lisp/seq-tests.el: Remove duplicate test. --- test/lisp/emacs-lisp/seq-tests.el | 5 ----- 1 file changed, 5 deletions(-) (limited to 'test/lisp/emacs-lisp/seq-tests.el') diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el index bf79dd922bf..8dc0b93b5af 100644 --- a/test/lisp/emacs-lisp/seq-tests.el +++ b/test/lisp/emacs-lisp/seq-tests.el @@ -347,11 +347,6 @@ Evaluate BODY for each created sequence. (should (same-contents-p (seq-union v1 v2) '(1 2 3 4 5 6 7 8 9)))) - (let ((v1 '(1 2 3 4 5 6)) - (v2 '(4 5 6 7 8 9))) - (should (same-contents-p (seq-union v1 v2) - '(1 2 3 4 5 6 7 8 9)))) - (let ((v1 [1 2 3 4 5]) (v2 [4 5 6 "a"])) (should (same-contents-p (seq-union v1 v2) -- cgit v1.2.3