alphapapa / alphapapa/emacs-package-dev-handbook
Replace `with-plist-vars`
- Linguagem predominante
- JavaScript
- Estrelas
- 1.2k
- Forks
- 46
- Métricas de merge de PRs
- Nenhum PR com merge em 30d
Descrição
First, thanks for this handbook. I haven't developed any emacs packages (yet), but even for my own init.el customizations this has been invaluable.
I was using the `with-plist-vars` macro and I liked it. However, I found that it had some significant shortcomings.
One is that it requires a raw plist and will not work with a variable which contains a plist.
For instance `(progn (setq plist '(:hi 1 :ho 2)) (with-plist-vars plist (+ hi ho))` does not work.
Equally problematic was the fact that it used variables with the same name as
the keys. These variables are likely to clobber other variables because they're
not prefixed by anything. Additionally, often times I want to try to get a value
from a key that I don't know is in the plist. Since there is no special notation
between a variable that refers to a key and any other variable I
have no way of doing this.
I would recommend adding this macro instead to your handbook:
```
(defmacro let-plist (plist &rest body)
"Let-bind dotted symbols to their value in PLIST and execute BODY.
Dotted symbol is any symbol starting with a .. Only those present
in BODY are let-bound and this search is done at compile time.
For instance, the following code
(let-plist plist
(if (and .title .body)
.body
.site))
essentially expands to
(let ((.title (plist-get plist :title))
(.body (plist-get plist :body))
(.site (plist-get plist :site)))
(if (and .title .body)
.body
.site))
"
(declare (indent defun))
(require 'let-alist)
(let ((plist-var (gensym)))
`(let*
((,plist-var ,(if (and (listp plist) (not (eq (car plist) 'quote)))
`(quote ,plist)
plist))
,@(cl-loop for (dotvar . var) in (let-alist--deep-dot-search body)
for key = (intern (concat ":" (symbol-name var)))
collect `(,dotvar (plist-get ,plist-var ,key))))
,@body)))
```
This macro addresses both these misgivings and is consistent with the `let-alist` macro already built-in to 26.1. It uses `let-alist--deep-dot-search-body` to get the variables which are prefixed by a `.`.
EDIT: fixed leak with `plist` var. Before the edit, if you passed in some expression which would evaluate to a plist, the expression would be evaluated one time for every unique dot variable. If the expression had side-effects or if it was computationally expensive, this could lead to unexpected results. Also I check to see if plist is an unquoted list and if it is I quote it. This is for convenience so that `(let-plist (:hi 1 :ho 2) ...)` will work even though the raw plist isn't quoted.
EDIT: Add `(require 'let-alist)`.
Guia de contribuição
Nenhum guia de contribuição indexado para este repositório
Avaliação
Esta issue ainda não foi avaliada.