Flet 函数为什么总是有Warning?

为了在退出的时候,自动杀掉进程,借用了子龙下面一段函数。

(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
  "Prevent annoying \"Active processes exist\" query when you quit Emacs."
  (flet ((process-list ())) ad-do-it))

虽然可以自动杀掉进程,但是启动emacs时,总是有警告: Warning (bytecomp): ‘flet’ is an obsolete macro (as of 24.3); use either ‘cl-flet’ or ‘cl-letf’. 无论是将flet改成cl-flet还是cl-letf,在有process的时候退出emacs就会出现删除进程的提示,这个函数到底应该改成什么才能生效并且无警告呢?

cl-flet 不行的原因是:cl-flet 建立的 binding 是局部的,而 flet 的是全局的。比如这个例子中:

(defun foo () (message "foo"))
     => foo

(flet ((message (&rest r) nil))
  (list (foo) (message "123")))
     => (nil nil)

(cl-flet ((message (&rest r) nil))
  (list (foo) (message "123")))
     => ("foo" nil)

可以发现 cl-flet 只能覆盖掉明确调用的 message,并不能覆盖掉 foo 里的 message

cl-letf 应该是可行的吧,下面的方法在我这边(Emacs 25)有效:

(define-advice save-buffers-kill-emacs (:around (orig-fun &rest r) no-query-kill-emacs)
  (cl-letf (((symbol-function 'process-list) 'ignore))
    (apply orig-fun r)))
1 个赞

Emacs 26 新加了个 confirm-kill-processes 选项,有的话,把它设成 nil 就行。

1 个赞

按照你的方法可以了,谢谢。