Как изящно выйти из 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) 

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

Заранее спасибо.

10 ответов

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

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

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

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

Согласно странице руководства по этому вопросу, "как только 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 и закрыла свои буферы, я не проверял это).

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

Очень грязное решение:

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

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

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

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

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

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

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

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

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

Как только он настроен таким образом, тогда:

  1. нажмите запятую (,), чтобы вызвать минибуфер
  2. наберите quit или sayoonara для чистого выхода.

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

Меня раздражает необходимость соглашаться убивать все процессы каждый раз, когда я закрываю 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)

Я использую его для всех репло-подобных буферов, которые у меня есть, включая октаву, питон, схему, оболочку и ghci для haskell. Пока что ничего плохого не произошло, когда эти реплеры были убиты молча, поэтому я полагаю, что это решение не плохое, хотя и не изящное.

Вот что я считаю лучшим решением, которое специально игнорирует только SLIMEбуферы. На самом деле это не убивает процессы, если пользователь прерывает kill-emacsкоманда, а также не требует ожидания асинхронного завершения работы слизи.

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

Это заняло у меня вечность. Если у вас открыто два окна, переключитесь на окно слизи и нажмите cx 0, чтобы закрыть это окно. Затем вы можете нормально закрыть окно emacs через cx cc.

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

Нет нет нет. /questions/16656769/zastavte-emacs-perestat-sprashivat-aktivnyie-protsessyi-suschestvuyut-ubit-ih-i-vyijti-v-lyubom-sluchae/16656777#16656777; любой другой способ уничтожения буфера процесса в лучшем случае груб, если не опасен для детей и щенков.

Другие вопросы по тегам