Add core plist library
This commit is contained in:
parent
9d1e2c5bd9
commit
d8dbb90931
1 changed files with 84 additions and 0 deletions
84
core/autoload/plist.el
Normal file
84
core/autoload/plist.el
Normal file
|
@ -0,0 +1,84 @@
|
|||
;;; ../work/conf/doom-emacs/core/autoload/plist.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-plist-get (plist prop &optional nil-value)
|
||||
"Return PROP in PLIST, if it exists. Otherwise NIL-VALUE."
|
||||
(if-let (val (plist-member plist prop))
|
||||
(cadr val)
|
||||
nil-value))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-plist-merge (from-plist to-plist)
|
||||
"Destructively merge FROM-PLIST onto TO-PLIST"
|
||||
(while plist
|
||||
(plist-put! old-plist (pop plist) (pop plist))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-plist-delete-nil (plist)
|
||||
"Delete `nil' properties from a copy of PLIST."
|
||||
(let (p)
|
||||
(while plist
|
||||
(if (car plist)
|
||||
(setq p (plist-put p (car plist) (nth 1 plist))))
|
||||
(setq plist (cddr plist)))
|
||||
p))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-plist-delete (plist prop)
|
||||
"Delete PROP from a copy of PLIST."
|
||||
(let (p)
|
||||
(while plist
|
||||
(if (not (eq prop (car plist)))
|
||||
(setq p (plist-put p (car plist) (nth 1 plist))))
|
||||
(setq plist (cddr plist)))
|
||||
p))
|
||||
|
||||
|
||||
;;
|
||||
;;; Macros
|
||||
|
||||
;;;###autoload
|
||||
(cl-defmacro doplist! ((arglist plist &optional retval) &rest body)
|
||||
"Loop over a PLIST's (property value) pairs then return RETVAL.
|
||||
|
||||
Evaluate BODY with either ARGLIST bound to (cons PROP VAL) or, if ARGLIST is a
|
||||
list, the pair is destructured into (CAR . CDR)."
|
||||
(declare (indent defun))
|
||||
(let ((plist-var (make-symbol "plist")))
|
||||
`(let ((,plist-var ,plist))
|
||||
(while ,plist-var
|
||||
(let ,(if (listp arglist)
|
||||
`((,(pop arglist) (pop ,plist-var))
|
||||
(,(pop arglist) (pop ,plist-var)))
|
||||
`((,arglist (cons (pop ,plist-var)
|
||||
(pop ,plist-var)))))
|
||||
,@body)))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro plist-put! (plist prop value)
|
||||
"Set PROP to VALUE in PLIST in-place."
|
||||
(let ((plist-var (make-symbol "plist")))
|
||||
`(setq ,plist (plist-put ,plist ,prop ,value))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro plist-delete! (plist prop)
|
||||
"Delete PROP from PLIST in-place."
|
||||
`(setq ,plist (doom-plist-delete ,plist ,prop)))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro with-plist! (plist props &rest body)
|
||||
"With props bound from PLIST to PROPS, evaluate BODY.
|
||||
|
||||
PROPS is a list of symbols. Each one is converted to a keyword and then its
|
||||
value is looked up in the PLIST and bound to the symbol for the duration of
|
||||
BODY."
|
||||
(declare (indent 2))
|
||||
(let ((plist-sym (make-symbol "plist")))
|
||||
`(let* ((,plist-sym ,plist)
|
||||
,@(cl-loop for prop in props
|
||||
collect
|
||||
`(,prop
|
||||
(plist-get
|
||||
,plist-sym
|
||||
,(doom-keyword-intern (symbol-name prop))))))
|
||||
,@body)))
|
Loading…
Add table
Add a link
Reference in a new issue