You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Elisp中如何在被cl-letf覆盖的函数内调用原函数?

提问:Elisp中用cl-letf覆盖函数后,如何在自定义实现内调用原函数

在Elisp中,cl-letf可用于覆盖函数实现。我现在需要在被覆盖的函数内部调用原函数,具体场景如下:
我想要禁用ediff的「Do you really want to quit?」退出确认提示,但保留ediff的其他询问弹窗,目前的实现代码如下:

(defun my-ediff-disable-quit-question (orig-fun &rest args)
  (cl-letf (((symbol-function 'y-or-n-p)
             (lambda (prompt) (if (string-prefix-p "Quit this Ediff session" prompt)
                                   t
                                 (<call-original-y-or-n-p> prompt)))))
    (apply orig-fun args)))

(advice-add 'ediff-quit :around #'my-ediff-disable-quit-question)

以上代码中我覆盖了y-or-n-p函数,会先检查提示内容是否为退出会话的提示,如果是就直接返回t,否则需要调用原始的y-or-n-p执行原有逻辑。


回答

你只需要在执行cl-letf覆盖函数之前,先将y-or-n-p的原始实现存储到临时变量中,需要调用原逻辑时直接调用该临时变量即可,修改后的可用代码如下:

(defun my-ediff-disable-quit-question (orig-fun &rest args)
  ;; 提前保存原始的y-or-n-p函数实现
  (let ((original-y-or-n-p (symbol-function 'y-or-n-p)))
    (cl-letf (((symbol-function 'y-or-n-p)
               (lambda (prompt)
                 (if (string-prefix-p "Quit this Ediff session" prompt)
                     ;; 匹配到退出提示直接返回确认
                     t
                   ;; 其他场景调用原始y-or-n-p逻辑
                   (funcall original-y-or-n-p prompt)))))
      (apply orig-fun args))))

(advice-add 'ediff-quit :around #'my-ediff-disable-quit-question)

实现原理

symbol-function可以获取指定符号当前绑定的函数对象,我们在修改y-or-n-p的函数指向之前先把原始实现缓存到变量original-y-or-n-p中,后续调用时通过funcall执行该缓存的函数对象,不会触发我们新定义的覆盖逻辑,即可完美实现需求。

内容的提问来源于stack exchange,提问作者geza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 03:06:03