Skip to content

Commit e287da5

Browse files
alphapapamonnier
authored andcommitted
* 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.
1 parent b641c17 commit e287da5

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

etc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ supplied error message.
115115
*** New connection method "media", which allows accessing media devices
116116
like cell phones, tablets or cameras.
117117

118+
** map.el
119+
120+
*** Pcase 'map' pattern added keyword symbols abbreviation.
121+
A pattern like '(map :sym)' binds the map's value for ':sym' to 'sym',
122+
equivalent to '(map (:sym sym))'.
123+
118124

119125
* New Modes and Packages in Emacs 28.1
120126

lisp/emacs-lisp/map.el

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
;; Author: Nicolas Petton <[email protected]>
66
;; Keywords: convenience, map, hash-table, alist, array
7-
;; Version: 2.0
7+
;; Version: 2.1
88
;; Package-Requires: ((emacs "25"))
99
;; Package: map
1010

@@ -56,8 +56,10 @@ evaluated and searched for in the map. The match fails if for any KEY
5656
found in the map, the corresponding PAT doesn't match the value
5757
associated to the KEY.
5858
59-
Each element can also be a SYMBOL, which is an abbreviation of a (KEY
60-
PAT) tuple of the form (\\='SYMBOL SYMBOL).
59+
Each element can also be a SYMBOL, which is an abbreviation of
60+
a (KEY PAT) tuple of the form (\\='SYMBOL SYMBOL). When SYMBOL
61+
is a keyword, it is an abbreviation of the form (:SYMBOL SYMBOL),
62+
useful for binding plist values.
6163
6264
Keys in ARGS not found in the map are ignored, and the match doesn't
6365
fail."
@@ -486,9 +488,12 @@ Example:
486488
(defun map--make-pcase-bindings (args)
487489
"Return a list of pcase bindings from ARGS to the elements of a map."
488490
(seq-map (lambda (elt)
489-
(if (consp elt)
490-
`(app (pcase--flip map-elt ,(car elt)) ,(cadr elt))
491-
`(app (pcase--flip map-elt ',elt) ,elt)))
491+
(cond ((consp elt)
492+
`(app (pcase--flip map-elt ,(car elt)) ,(cadr elt)))
493+
((keywordp elt)
494+
(let ((var (intern (substring (symbol-name elt) 1))))
495+
`(app (pcase--flip map-elt ,elt) ,var)))
496+
(t `(app (pcase--flip map-elt ',elt) ,elt))))
492497
args))
493498

494499
(defun map--make-pcase-patterns (args)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,5 +376,11 @@ Evaluate BODY for each created map.
376376
'((1 . 1) (2 . 5) (3 . 0)))
377377
'((3 . 0) (2 . 9) (1 . 6)))))
378378

379+
(ert-deftest test-map-plist-pcase ()
380+
(let ((plist '(:one 1 :two 2)))
381+
(should (equal (pcase-let (((map :one (:two two)) plist))
382+
(list one two))
383+
'(1 2)))))
384+
379385
(provide 'map-tests)
380386
;;; map-tests.el ends here

0 commit comments

Comments
 (0)