Add gv-define-expander for plist-get
It is necessary to make plist-get as a generalized variable, and this definition allows user to use setf and other useful functions on plist-get. * lisp/emacs-lisp/gv.el: Add gv-define-expander for plist-get * lisp/emacs-lisp/gv-tests.el: Add new tests for plist-get
This commit is contained in:
parent
4064d07445
commit
66509f2ead
2 changed files with 51 additions and 0 deletions
|
@ -417,6 +417,17 @@ The return value is the last VAL in the list.
|
|||
`(delq ,p ,getter))))))
|
||||
,v))))))))))
|
||||
|
||||
(gv-define-expander plist-get
|
||||
(lambda (do plist prop)
|
||||
(macroexp-let2 macroexp-copyable-p key prop
|
||||
(gv-letplace (getter setter) plist
|
||||
(macroexp-let2 nil p `(cdr (plist-member ,getter ,key))
|
||||
(funcall do
|
||||
`(car ,p)
|
||||
(lambda (val)
|
||||
`(if ,p
|
||||
(setcar ,p ,val)
|
||||
,(funcall setter `(cons ,key (cons ,val ,getter)))))))))))
|
||||
|
||||
;;; Some occasionally handy extensions.
|
||||
|
||||
|
|
|
@ -156,6 +156,46 @@ its getter (Bug#41853)."
|
|||
(eval-buffer)))
|
||||
(should (equal (get 'gv-setter-edebug 'gv-setter-edebug-prop) '(123))))
|
||||
|
||||
(ert-deftest gv-plist-get ()
|
||||
(require 'cl-lib)
|
||||
|
||||
;; Simple setf usage for plist-get.
|
||||
(should (equal (let ((target '(:a "a" :b "b" :c "c")))
|
||||
(setf (plist-get target :b) "modify")
|
||||
target)
|
||||
'(:a "a" :b "modify" :c "c")))
|
||||
|
||||
;; Other function (cl-rotatef) usage for plist-get.
|
||||
(should (equal (let ((target '(:a "a" :b "b" :c "c")))
|
||||
(cl-rotatef (plist-get target :b) (plist-get target :c))
|
||||
target)
|
||||
'(:a "a" :b "c" :c "b")))
|
||||
|
||||
;; Add new key value pair at top of list if setf for missing key.
|
||||
(should (equal (let ((target '(:a "a" :b "b" :c "c")))
|
||||
(setf (plist-get target :d) "modify")
|
||||
target)
|
||||
'(:d "modify" :a "a" :b "b" :c "c")))
|
||||
|
||||
;; Rotate with missing value.
|
||||
;; The value corresponding to the missing key is assumed to be nil.
|
||||
(should (equal (let ((target '(:a "a" :b "b" :c "c")))
|
||||
(cl-rotatef (plist-get target :b) (plist-get target :d))
|
||||
target)
|
||||
'(:d "b" :a "a" :b nil :c "c")))
|
||||
|
||||
;; Simple setf usage for plist-get. (symbol plist)
|
||||
(should (equal (let ((target '(a "a" b "b" c "c")))
|
||||
(setf (plist-get target 'b) "modify")
|
||||
target)
|
||||
'(a "a" b "modify" c "c")))
|
||||
|
||||
;; Other function (cl-rotatef) usage for plist-get. (symbol plist)
|
||||
(should (equal (let ((target '(a "a" b "b" c "c")))
|
||||
(cl-rotatef (plist-get target 'b) (plist-get target 'c))
|
||||
target)
|
||||
'(a "a" b "c" c "b"))))
|
||||
|
||||
;; `ert-deftest' messes up macroexpansion when the test file itself is
|
||||
;; compiled (see Bug #24402).
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue