自动在退出Emacs时停止进程

3

我正在尝试使用命令httpd-stop停止simple-httpd服务器,当我输入C-x C-c命令(退出emacs的save-buffers-kill-terminal),因为我想摆脱每次输入C-x C-c时出现的“存在活动进程;是否杀死它们并强制退出?(是或否)”消息。

为了实现我的目标,我考虑编写一个钩子,例如:

(add-hook 'save-buffers-kill-terminal
                (lambda () (httpd-stop)
                    ))

但它没有起作用。当我输入C-x C-c时,我仍然收到消息“存在活动进程;杀死它们并退出?(是或否)”。

我该如何实现我的目标?

谢谢!

1个回答

4

没有名为save-buffers-kill-terminal的钩子。

虽然有一个同名函数,但并不是每个函数都有自己对应的钩子(advice机制可以实现这一点,但在这里您不需要它(编辑:或者可能需要;请参见下文))。

只有在代码中显式使用run-hooks或类似的方法(例如C-u C-h a run.*hook RET)来运行时,才会存在一个钩子。或者更具体地说,您可以使用任意变量来add-hook,但除非有东西运行它,否则它将永远不起作用作为钩子。

通常情况下,如果回调函数不需要与用户交互,则可以使用kill-emacs-hook,否则可以使用kill-emacs-query-functions。有关详细信息,请参阅每个变量的帮助。

编辑:

对于活动进程,需要使用不同的机制,因为这些查询发生在运行这些钩子之前。

如果您只想避免查询并允许进程被终止,可以使用set-process-query-on-exit-flag。这将设置一个每进程的标志,用于确定是否会发生此查询:

set-process-query-on-exit-flag is a built-in function in `process.c'.

(set-process-query-on-exit-flag PROCESS FLAG)

Specify if query is needed for PROCESS when Emacs is exited.
If the second argument FLAG is non-nil, Emacs will query the user before
exiting or killing a buffer if PROCESS is running.  This function
returns FLAG.

假设您有一些启动httpd的代码,您可能会在开始过程时安排这个过程,使用 (get-process NAME)(get-buffer-process BUFFER) 获取 PROCESS。我没有使用这个httpd库,所以我不知道您需要什么。

如果您一定要调用类似 httpd-stop 的优雅关闭函数,我认为您需要做一些自定义操作。

(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
  (when (httpd-is-running-p) ;; not a real predicate
    (httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)

您需要找到替代我的假设httpd-is-running-p的方法,以确定是否调用停止功能。
请注意,这将在任何其他查询之前运行,因此您可能会以这种方式停止httpd,但随后决定不杀死emacs(但无论如何都可能发生这种情况)。 编辑:或者,由于显然可以在httpd运行与否的情况下调用此停止函数,因此您可以使用以下内容(包括一个测试以查看是否定义了httpd-stop,否则调用它将是一个错误,并且我不确定如何加载库)。
(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
  (when (fboundp 'httpd-stop)
    (httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)

谢谢您的回复,我已经尝试了以下代码:(add-hook 'kill-emacs-hook (lambda () (httpd-stop) ))但是它没有起作用,我该如何在按下C-x C-c时自动运行httpd-stop呢? - tonix
啊,有点棘手。实际上,活动进程查询发生在这两个钩子之前。但我看到有一个机制可以解决这个问题。我会更新答案的。 - phils
我已经将其更改为:(if t httpd-stop)))因为 httpd-stop 函数在服务器已经停止的情况下什么也不做,所以它会每次运行 httpd-stop。 我可以这样做,是吧?我想我可以。 - tonix
当然可以,但是你评论中的代码有错误/不平衡的括号,在任何情况下,具有条件“t”的ifwhen是相当无意义的,因此只需单独调用(httpd-stop)即可。请注意,如果这个函数没有被自动加载,你需要确保库已经被加载了,否则可以使用(when (fboundp 'httpd-stop) (httpd-stop)),这样它仅在函数被定义时才会调用该函数。 - phils
输入以下命令以检查函数是否已定义:C-h f fboundp RET。对于任何(已加载或自动加载的)elisp函数都适用相同的方法。 - phils
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接