如何优雅退出SLIME和Emacs?

发布于 2024-08-22 23:58:00 字数 984 浏览 13 评论 0原文

我有一个关于当我退出 Emacs 时如何“优雅地退出 SLIME”的问题。以下是我的配置文件的相关部分:

;; SLIME configuration

(setq inferior-lisp-program "/usr/local/bin/sbcl")
(add-to-list 'load-path "~/Scripts/slime/")
(require 'slime)
(slime-setup)

;; configure SLIME to gracefully quit when emacs
;; terminates

(defun slime-smart-quit ()
  (interactive)
  (when (slime-connected-p)
    (if (equal (slime-machine-instance) "Gregory-Gelfonds-MacBook-Pro.local")
 (slime-quit-lisp)
      (slime-disconnect)))
  (slime-kill-all-buffers))

(add-hook 'kill-emacs-hook 'slime-smart-quit)

据我所知,每当我退出 Emacs 时,这都会自动终止 SLIME 及其关联进程。但是,每次退出时,我仍然会收到提示:

Proc       Status   Buffer  Command
----       ------   ------  -------
SLIME Lisp    open      *cl-connection* (network stream connection to 127.0.0.1)
inferior-lisp run      *inferior-lisp* /usr/local/bin/sbcl


Active processes exist; kill them and exit anyway? (yes or no) 

有人可以深入了解我的配置中缺少的内容吗?

提前致谢。

I have a question regarding how to "gracefully exit SLIME", when I quit Emacs. Here is the relevant portion of my config file:

;; SLIME configuration

(setq inferior-lisp-program "/usr/local/bin/sbcl")
(add-to-list 'load-path "~/Scripts/slime/")
(require 'slime)
(slime-setup)

;; configure SLIME to gracefully quit when emacs
;; terminates

(defun slime-smart-quit ()
  (interactive)
  (when (slime-connected-p)
    (if (equal (slime-machine-instance) "Gregory-Gelfonds-MacBook-Pro.local")
 (slime-quit-lisp)
      (slime-disconnect)))
  (slime-kill-all-buffers))

(add-hook 'kill-emacs-hook 'slime-smart-quit)

To my knowledge this should automatically kill SLIME and it's associated processes whenever I exit Emacs. However, every time I exit, I still get the prompt:

Proc       Status   Buffer  Command
----       ------   ------  -------
SLIME Lisp    open      *cl-connection* (network stream connection to 127.0.0.1)
inferior-lisp run      *inferior-lisp* /usr/local/bin/sbcl


Active processes exist; kill them and exit anyway? (yes or no) 

Can someone shed some insight as to what I'm missing from my config?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

冷夜 2024-08-29 23:58:00

我知道这并不完全是您所要求的,但这也许对像我这样的其他菜鸟有帮助。

您可以执行 SLIME 命令来退出,这样您就剩下了一个漂亮、干净的 emacs。

在 SLIME 缓冲区中,输入 ,(逗号)。您被放置在迷你缓冲区中,SLIME 会询问要执行哪个命令。输入 sayoonara 并按 Enter。您应该看到 SLIME 退出,迷你缓冲区提到“连接已关闭”。并且您被放置在 *scratch* 缓冲区中。

我想知道是否有某种方法可以简单地从 .emacs 调用这个“sayoonara”命令,而不是手动取消所有内容。

I know it's not exactly what you asked for, but maybe this will be helpful to other noobs like me.

You can execute a SLIME command to exit, so you'll have a nice, clean emacs left over.

In a SLIME buffer, type in , (comma). You're placed in the minibuffer and SLIME asks which command to execute. Type in sayoonara and hit Enter. You should see SLIME exiting, the minibuffer mentions that "Connection closed." and you're placed in the *scratch* buffer.

I wonder if there's some way to simply invoke this "sayoonara" command from your .emacs, as opposed to manually unwiring everything.

扛刀软妹 2024-08-29 23:58:00

根据手册页,“一旦 save-buffers-kill-emacs 完成所有文件保存和确认,它就会调用 Kill-emacs 来运行此挂钩中的函数。”因此,对活动进程的检查是在调用钩子之前完成的。

一个可行的解决方案是创建您自己的kill-emacs命令,例如

(defun kill-emacs-slime ()
  (interactive)
  (when (slime-connected-p)
    (if (equal (slime-machine-instance) "Gregory-Gelfonds-MacBook-Pro.local")
        (slime-quit-lisp)
      (slime-disconnect)))
  (slime-kill-all-buffers)
  (save-buffers-kill-emacs))

然后将其绑定到您的退出键

(global-set-key (kbd "C-x C-c") 'kill-emacs-slime)

(我假设您的函数正确退出SLIME并关闭其缓冲区,我还没有测试它)。

According to the manual page on this, "once save-buffers-kill-emacs is finished with all file saving and confirmation, it calls kill-emacs which runs the functions in this hook." So the check for active processes is done before the hook is called.

A working solution would be to make your own kill-emacs command, for example

(defun kill-emacs-slime ()
  (interactive)
  (when (slime-connected-p)
    (if (equal (slime-machine-instance) "Gregory-Gelfonds-MacBook-Pro.local")
        (slime-quit-lisp)
      (slime-disconnect)))
  (slime-kill-all-buffers)
  (save-buffers-kill-emacs))

And then bind this to your quit key

(global-set-key (kbd "C-x C-c") 'kill-emacs-slime)

(I am assuming your function correctly quit SLIME and closes its buffers, I haven't tested it).

昔日梦未散 2024-08-29 23:58:00

问题是在 kill-emacs-hooks 有机会完成其工作之前,将激活对活动进程的检查(以及确认终止的查询)。

一个非常笨拙的解决方案:

(defadvice save-buffers-kill-terminal (before slime-quit activate)
  (slime-smart-quit)
  (sleep-for 1))

函数 slime-quit-lisp 是异步的;返回后需要时间才能完成,因此需要睡眠。

The problem is the check for active processes (and the query for confirmation to kill) would be activated before kill-emacs-hooks had a chance to do its job.

A very kludgy solution:

(defadvice save-buffers-kill-terminal (before slime-quit activate)
  (slime-smart-quit)
  (sleep-for 1))

The function slime-quit-lisp is asynchronous; it needs time to finish after returning, hence the sleep-for.

只想待在家 2024-08-29 23:58:00

调试问题的一种方法是调试函数。

将光标置于 'slime-smart-quit 例程中并输入 Mx edebug-defun。然后像平常一样退出 Emacs。然后 Emacs lisp 调试器应该会提示您 edebug< /a>.这是一个非常容易使用的调试器(输入 ? 以获得帮助)。

单步调试代码,看看它在哪里没有达到您期望的效果。

使用 q 退出调试器,然后进行更改,然后再次使用 Mx edebug-defun 调试新版本。

重复直到您成功,或者获得有关该问题的更多信息。

One way to debug the problem is to debug the function.

Place your cursor inside the 'slime-smart-quit routine and type M-x edebug-defun. Then exit Emacs as you normally would. You should then be prompted by the Emacs lisp debugger edebug. It's a pretty easy debugger to use (type ? for help).

Step through the code and see where it doesn't do what you expect it to do.

Use q to quit out of the debugger, then make changes, and M-x edebug-defun again to debug the new version.

Repeat until you find success, or have a little more information for the question.

星光不落少年眉 2024-08-29 23:58:00

@Alex - 我发现你的方法是退出 SLIME 最干净的方法。但是,需要以这种方式编辑配置文件才能使用它。

(require 'slime-autoloads)
(slime-setup '(slime-fancy)) ; load contrib packages

一旦以这种方式设置,然后:

  1. 逗号(,)调出迷你缓冲区
  2. 类型退出sayoonara干净退出。

PS:启动时检查 SLIME 配置 - http://common -lisp.net/project/slime/doc/html/Loading-Contribs.html

@Alex - I found your method to be the cleanest way to quit SLIME. However the config file needs to be edited in this fashion for it to be used.

(require 'slime-autoloads)
(slime-setup '(slime-fancy)) ; load contrib packages

Once it's setup this way then:

  1. press comma (,) to bring up the minibuffer
  2. type quit or sayoonara to cleanly exit.

PS: Check this for SLIME config at startup - http://common-lisp.net/project/slime/doc/html/Loading-Contribs.html

那小子欠揍 2024-08-29 23:58:00

我觉得每次关闭 Emacs 时都必须同意杀死所有进程很烦人,所以我想出了这个函数,

(defun emacs-forget-buffer-process ()
  "Emacs will not query about this process when killing."
  (let ((p (get-buffer-process (current-buffer))))
    (when p
      (set-process-query-on-exit-flag p nil))))

它可以让进程在 Emacs 关闭时静静地死亡。像这样使用它,

(add-hook 'slime-inferior-process-start-hook #'emacs-forget-buffer-process)
(add-hook 'slime-repl-mode-hook #'emacs-forget-buffer-process)

我将它用于我拥有的所有类似 repl 的缓冲区,其中包括 Octave、Python、Scheme、Shell 和 Haskell 的 ghci。到目前为止,当这些 repl 被默默地杀死时,没有发生任何不好的事情,所以我认为这个解决方案还不错,尽管可能不太优雅。

I find it annoying to have to agree to kill all processes every time I close the Emacs so I come up with this function

(defun emacs-forget-buffer-process ()
  "Emacs will not query about this process when killing."
  (let ((p (get-buffer-process (current-buffer))))
    (when p
      (set-process-query-on-exit-flag p nil))))

which makes process die silently when Emacs is closed. Use it like this

(add-hook 'slime-inferior-process-start-hook #'emacs-forget-buffer-process)
(add-hook 'slime-repl-mode-hook #'emacs-forget-buffer-process)

I use it for all repl-like buffers that I have, which includes octave, python, scheme, shell and haskell's ghci. So far nothing bad happened when these repls get killed silently so I assume this solution isn't bad though may not be graceful.

陌上青苔 2024-08-29 23:58:00

这是我使用的更通用的解决方案。
它不仅适用于 SLIME,还适用于其他东西,例如 python、terminal、lisp 等。

(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))

This is a more general solution that I use.
It works not just for SLIME, but for other stuff, e.g. python, terminal, lisp etc.

(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))
陪我终i 2024-08-29 23:58:00

这花了我很长时间。如果您打开了两个窗口,请切换到 slime 窗口并按 cx 0 来终止该窗口。然后就可以通过cx cc正常杀死emacs窗口了。

This took me forever. If you have two windows opened up, switch to the slime window and hit c-x 0 to kill that window. Then you can kill the emacs window normally through c-x c-c.

爱殇璃 2024-08-29 23:58:00

我认为这是一个更好的解决方案,专门忽略 SLIME 缓冲区。如果用户中止 Kill-emacs 命令,它实际上不会终止进程,也不需要等待 slime 异步正常退出。

(defun process-ignore-on-exit (regexp)
  (cl-loop for proc in (process-list)
           when (s-matches-p regexp (process-name proc))
           do
           (progn (message "disabling query-on-exit for '%s'" proc)
                  (set-process-query-on-exit-flag proc nil))))

(defun slime-ignore-processes-on-exit (&rest r)
  (process-ignore-on-exit "SLIME"))

(advice-add #'save-some-buffers :before #'slime-ignore-processes-on-exit)

Here's what I feel is a better solution that specifically ignores only SLIME buffers. It doesn't actually kill the processes if the user aborts the kill-emacs command, nor does it require waiting for slime to asynchronously exit gracefully.

(defun process-ignore-on-exit (regexp)
  (cl-loop for proc in (process-list)
           when (s-matches-p regexp (process-name proc))
           do
           (progn (message "disabling query-on-exit for '%s'" proc)
                  (set-process-query-on-exit-flag proc nil))))

(defun slime-ignore-processes-on-exit (&rest r)
  (process-ignore-on-exit "SLIME"))

(advice-add #'save-some-buffers :before #'slime-ignore-processes-on-exit)
君勿笑 2024-08-29 23:58:00

不,不,不。 https://stackoverflow.com/a/10780124/539797 ;任何其他杀死进程缓冲区的方法即使对儿童和小狗来说不是很危险,至少也是粗鲁的。

No, no, no. https://stackoverflow.com/a/10780124/539797 ; any other way of killing a process buffer is at best rude, if not plain dangerous to children and puppies.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文