如何重命名elisp宏?为了更准确,我希望make defun
成为cl-defun
的同义词。
我不关心时间或内存开销。
答案 0 :(得分:4)
我认为你不能这样做 - 至少不容易。
自cl-defun
扩展为defun
后,如果您执行明显的defun
,则在使用(defalias 'defun 'cl-defun)
时将获得无限的宏扩展循环。
所以你需要做的是
保存原始defun
:(fset 'defun-original (symbol-function 'defun))
。
在cl-defun
中复制cl-macs.el
的定义,将defun
替换为defun-original
。
使用defun
cl-defun
将defalias
替换为(defalias 'defun 'cl-defun)
。
现在,至少,如果情况恶化,您可以使用(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
定义的。