]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/emacs-lisp/map.el: Add keyword-only pattern abbreviation
authorAdam Porter <adam@alphapapa.net>
Sun, 2 Feb 2020 16:17:20 +0000 (10:17 -0600)
committerStefan Monnier <monnier@iro.umontreal.ca>
Tue, 4 Feb 2020 17:30:31 +0000 (12:30 -0500)
* lisp/emacs-lisp/map.el: Update version to 2.1.
((pcase-defmacro map)): Update docstring.
(map--make-pcase-bindings): Match keyword pattern.

* test/lisp/emacs-lisp/map-tests.el (test-map-plist-pcase): Add test.

etc/NEWS
lisp/emacs-lisp/map.el
test/lisp/emacs-lisp/map-tests.el

index de8e20e2de40d6263cfd8aaa2ed80692b53378db..093b54bdd4606a5d19bff4ba4e3f6d6f7980ac3c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -115,6 +115,12 @@ supplied error message.
 *** New connection method "media", which allows accessing media devices
 like cell phones, tablets or cameras.
 
+** map.el
+
+*** Pcase 'map' pattern added keyword symbols abbreviation.
+A pattern like '(map :sym)' binds the map's value for ':sym' to 'sym',
+equivalent to '(map (:sym sym))'.
+
 \f
 * New Modes and Packages in Emacs 28.1
 
index 67f5b3cf24e00fc27b9148906f90dabb2cdd55e0..9c23344baca25b62c38ddf8fc17bc5865b90d5ae 100644 (file)
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: convenience, map, hash-table, alist, array
-;; Version: 2.0
+;; Version: 2.1
 ;; Package-Requires: ((emacs "25"))
 ;; Package: map
 
@@ -56,8 +56,10 @@ evaluated and searched for in the map.  The match fails if for any KEY
 found in the map, the corresponding PAT doesn't match the value
 associated to the KEY.
 
-Each element can also be a SYMBOL, which is an abbreviation of a (KEY
-PAT) tuple of the form (\\='SYMBOL SYMBOL).
+Each element can also be a SYMBOL, which is an abbreviation of
+a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL).  When SYMBOL
+is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
+useful for binding plist values.
 
 Keys in ARGS not found in the map are ignored, and the match doesn't
 fail."
@@ -486,9 +488,12 @@ Example:
 (defun map--make-pcase-bindings (args)
   "Return a list of pcase bindings from ARGS to the elements of a map."
   (seq-map (lambda (elt)
-             (if (consp elt)
-                 `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))
-               `(app (pcase--flip map-elt ',elt) ,elt)))
+             (cond ((consp elt)
+                    `(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
+                   ((keywordp elt)
+                    (let ((var (intern (substring (symbol-name elt) 1))))
+                      `(app (pcase--flip map-elt ,elt) ,var)))
+                   (t `(app (pcase--flip map-elt ',elt) ,elt))))
            args))
 
 (defun map--make-pcase-patterns (args)
index 06fd55faad3f7d8ebea61bcc2e1e781839f07704..3ffef177711fb68759798c875d785cf315b63f4e 100644 (file)
@@ -376,5 +376,11 @@ Evaluate BODY for each created map.
                                  '((1 . 1) (2 . 5) (3 . 0)))
                  '((3 . 0) (2 . 9) (1 . 6)))))
 
+(ert-deftest test-map-plist-pcase ()
+  (let ((plist '(:one 1 :two 2)))
+    (should (equal (pcase-let (((map :one (:two two)) plist))
+                     (list one two))
+                   '(1 2)))))
+
 (provide 'map-tests)
 ;;; map-tests.el ends here