Как изящно выйти из 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
Как только он настроен таким образом, тогда:
- нажмите запятую (,), чтобы вызвать минибуфер
- наберите 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; любой другой способ уничтожения буфера процесса в лучшем случае груб, если не опасен для детей и щенков.