summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Porter <adam@alphapapa.net>2020-02-02 10:17:20 -0600
committerStefan Monnier <monnier@iro.umontreal.ca>2020-02-04 12:30:31 -0500
commite287da5a8154d83a97107b64915ccc17e3a086b8 (patch)
tree37f52e272e0d697165a3ffea60b15ade79d8a65e
parentb641c178ce3d022a9fca1d44ecb60f3878a989bd (diff)
downloademacs-e287da5a8154d83a97107b64915ccc17e3a086b8.tar.gz
* lisp/emacs-lisp/map.el: Add keyword-only pattern abbreviation
* 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.
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/emacs-lisp/map.el17
-rw-r--r--test/lisp/emacs-lisp/map-tests.el6
3 files changed, 23 insertions, 6 deletions
diff --git a/etc/NEWS b/etc/NEWS
index de8e20e2de4..093b54bdd46 100644
--- 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))'.
+
* New Modes and Packages in Emacs 28.1
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index 67f5b3cf24e..9c23344baca 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -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)
diff --git a/test/lisp/emacs-lisp/map-tests.el b/test/lisp/emacs-lisp/map-tests.el
index 06fd55faad3..3ffef177711 100644
--- a/test/lisp/emacs-lisp/map-tests.el
+++ b/test/lisp/emacs-lisp/map-tests.el
@@ -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