我认为这在 Common Lisp 中是可能的(通过重载 setf
),但不确定 Emacs Lisp。
我想做的是:
(setf (local variable) value)
(local ...)
形式将调用我编写的一些代码并返回用于设置其值槽的符号。
编辑:从 gv.el 来看,建议 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 的方法
带有冗余替换的表达式的一部分。
编辑3:
好吧,除非我在范围或变量将被设置的值的评估序列中搞砸了一些东西,否则这似乎有效:
(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)))))
有 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)))))))
我是一名优秀的程序员,十分优秀!