Elisp重命名宏

时间:2013-04-08 07:15:51

标签: emacs macros elisp

如何重命名elisp宏?为了更准确,我希望make defun成为cl-defun的同义词。 我不关心时间或内存开销。

3 个答案:

答案 0 :(得分:4)

摘要

我认为你不能这样做 - 至少不容易。

cl-defun扩展为defun后,如果您执行明显的defun,则在使用(defalias 'defun 'cl-defun)时将获得无限的宏扩展循环。

这是一种方式......

所以你需要做的是

  1. 保存原始defun(fset 'defun-original (symbol-function 'defun))

  2. cl-defun中复制cl-macs.el的定义,将defun替换为defun-original

  3. 使用defun cl-defundefalias替换为(defalias 'defun 'cl-defun)

  4. 现在,至少,如果情况恶化,您可以使用(fset 'defun (symbol-function 'defun-original))恢复原始行为。

    ...但你不想要它

    但是,我认为你并不是想要这样做。

    如果您想使用Common Lisp,use it。试图假装你可以把Elisp变成CL会让你感到悲伤。 15年前我试图在那条路上旅行 - 那里没有乐趣。它现在应该更容易,至少存在词汇绑定,但我仍然认为这不值得付出努力。

    如果你想扩展Emacs,那么使用cl-defun就更没意义了:你的扩展对其他人来说是无用的,你甚至无法寻求帮助,因为很少有人会打扰这种微不足道的基本功能发生了根本性的变化。

答案 1 :(得分:2)

通常,您可以使用(defalias 'foo 'cl-defun)非常简单地创建同义词。 但是,对cl-defun的调用的扩展使用了defun,所以如果你做(defalias 'defun 'cl-defun),你将进入无限循环。

您可以通过将defun替换为执行defun执行操作或执行cl-defun操作的宏来获取您想要的内容,具体取决于cal是否使用cl-defun功能与否。例如。使用advice-add(在Emacs的主干中;您可以在较旧的Emacsen中使用defadvice来获得模拟结果)它可能看起来像下面未经测试的代码:

(defun my-defun-dispatch (doit name args &rest body)
  (let ((needs-cl nil))
    (dolist (arg args)
      (unless (and (symbolp arg)
                   (or (not (eq ?& (aref (symbol-name arg) 0)))
                       (memq arg '(&optional &rest))))
        (setq needs-cl t)))
    (if needs-cl
        `(cl-defun ,name ,args ,@body)
      (funcall doit name args body))))
(advice-add :around 'defun 'my-defun-dispatch)

答案 2 :(得分:1)

有什么特别的原因吗?

也许这样做是安全的,我确信这是可能的,但我非常怀疑你应该在首先,如果你不能弄清楚如何去做。我并不是说任何一种侮辱;我只是怀疑像这样的根本性改变很容易引起问题,因此在尝试之前你应该首先对elisp有一个坚实的处理。

我意识到这有点不回答,但我认为值得一说。

FYI cl-defun是根据defun定义的。