我认为这可以在Common Lisp中实现(通过重载setf
),但不确定Emacs Lisp。
我想做的事情是:
(setf (local variable) value)
表单(local ...)
将调用我编写的一些代码并返回用于设置其值槽的符号。
gv-get
会做这个工作,但也许有一个更好的程序呢?
EDIT2:尝试了Stefan的建议,接近但不好:(
(gv-define-setter local (value varname &optional buffer)
`(with-current-buffer (or ,buffer (current-buffer))
(setq ,varname ,value)))
扩展为:
(let* ((v bar))
(with-current-buffer (or nil (current-buffer))
(setq v 42)))
显然,不是我想要的。我试图通过上面提到的建议和gv-define-expander
来做这件事,但是引用的内容太多了,我无法找到一种方法来松开表达式的let
部分多余的替代。
EDIT3:
好的,除非我在范围或者变量将被设置的值的评估序列中严重搞砸了,否则这似乎有效:
(gv-define-expander local
(lambda (do &rest args)
(let ((varname (first args))
(buffer (or (second args) '(current-buffer)))
(value (funcall do nil #'identity)))
`(with-current-buffer ,buffer
(setq ,varname ,value)))))
答案 0 :(得分:1)
有gv-define-expander
,gv-define-setter
和gv-define-simple-setter
(为了增加使用的简单性)。
您可能想尝试100%保证未经测试的代码(请注意我如何将with-current-buffer+setq
传递给do
而不是使用伪参数调用do
,这样这件事就有机会与push
)一起使用时。
(gv-define-expander local
(lambda (do &rest varname &optional buffer)
(macroexp-let2 nil b buffer
(funcall do `(buffer-local-value ',varname ,b)
(lambda (value)
`(with-current-buffer ,b
(setq ,varname ,value)))))))