Как изящно выйти из SLIME и Emacs?

У меня вопрос о том, как "изящно выйти из SLIME", когда я ухожу из Emacs. Вот соответствующая часть моего файла конфигурации:

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

Насколько я знаю, это должно автоматически убивать SLIME и связанные с ним процессы всякий раз, когда я выхожу из Emacs. Тем не менее, каждый раз, когда я выхожу, я все еще получаю приглашение:

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) 

Может кто-то пролить некоторое представление о том, чего не хватает в моей конфигурации?

Спасибо заранее.

Ответ 1

Я знаю, что это не то, о чем вы просили, но, возможно, это будет полезно для других нубов вроде меня.

Вы можете выполнить команду SLIME для выхода, так что у вас будет хороший, чистый emacs.

В буфере SLIME введите , (запятая). Вы помещены в минибуфер, а SLIME запрашивает, какую команду выполнить. Введите sayoonara и нажмите Enter. Вы должны увидеть выход SLIME, минибуфер упоминает, что "Соединение закрыто". и вы помещены в буфер * scratch *.

Интересно, есть ли способ просто вызвать эту команду "sayoonara" из вашего .emacs, в отличие от ручного удаления всего.

Ответ 2

В соответствии с справочной страницей в этом, "после того, как 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))

И затем привяжите это к вашей клавише quit

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

(Я предполагаю, что ваша функция корректно закрывает SLIME и закрывает свои буферы, я ее не тестировал).

Ответ 3

Проблема в том, что проверка активных процессов (и запрос на подтверждение для убийства) будет активирована до того, как kill-emacs-hooks сможет выполнить свою работу.

Очень простое решение:

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

Функция slime-quit-lisp является асинхронной; ему нужно время, чтобы закончить после возвращения, следовательно sleep-for.

Ответ 4

Один из способов отладки проблемы - отладка функции.

Поместите курсор внутри процедуры 'slime-smart-quit и введите M-x edebug-defun. Затем выйдите из Emacs, как обычно. Затем вам будет предложено отладчик Emacs lisp edebug. Это довольно простой отладчик для использования (введите ? для справки).

Пройдите код и посмотрите, где он не делает то, что вы ожидаете от него.

Используйте q для выхода из отладчика, затем внесите изменения и M-x edebug-defun снова, чтобы отладить новую версию.

Повторяйте до тех пор, пока не найдете успех или не получите больше информации для вопроса.

Ответ 5

@Alex - я нашел ваш метод самым чистым способом выйти из SLIME. Однако файл конфигурации должен быть отредактирован таким образом, чтобы он использовался.

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

Как только он настроится таким образом, выполните следующие действия:

  • нажмите запятая (,), чтобы открыть минибуфер
  • введите quit или sayoonara, чтобы выйти.

PS: проверьте это для конфигурации SLIME при запуске - http://common-lisp.net/project/slime/doc/html/Loading-Contribs.html

Ответ 6

Я нахожу, что досадно, что приходится соглашаться убивать все процессы каждый раз, когда я закрываю 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-like буферов, которые у меня есть, включая октаву, питон, схему, оболочку и haskell ghci. Пока ничего плохого не произошло, когда эти реплики были убиты молча, поэтому я предполагаю, что это решение неплохое, хотя может и не быть изящным.

Ответ 7

Это более общее решение, которое я использую. Он работает не только для 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))

Ответ 8

Это заняло у меня навсегда. Если у вас есть два открытых окна, переключитесь на окно слизи и нажмите c-x 0, чтобы убить это окно. Тогда вы можете нормально убить окно emacs через c-x c-c.

Ответ 9

Нет, нет, нет. fooobar.com/info/184319/...; любой другой способ убить буфер процесса в лучшем случае груб, если не просто опасен для детей и щенков.