* 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.
This commit is contained in:
Adam Porter 2020-02-02 10:17:20 -06:00 committed by Stefan Monnier
parent b641c178ce
commit e287da5a81
3 changed files with 23 additions and 6 deletions

View file

@ -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

View 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)

View 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