为setf添加新的变量指示符?

时间:2012-11-16 12:41:36

标签: emacs lisp elisp advising-functions

我认为这可以在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部分多余的替代。

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)))))

1 个答案:

答案 0 :(得分:1)

gv-define-expandergv-define-settergv-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)))))))