SLIMEを完全に終了させよう。

Emacs上でSLIMEを起動するのはかんたん。M-x slime と命令するだけでOKだ。
けど終了させるときはどうだろう。
まず、Emacsじたいの終了は最悪の結末をもたらす。これまで何度か起こっているように、lisp-runプロセスがEmacsという親プロセスを無くして暴走、CPUパワーを食いまくるということになってしまう。これをいちいちkillするのは何とも馬鹿らしい。
じゃあlispを消せば良いじゃん。うん、じゃあやってみる。

CL-USER> (bye)
; Evaluation aborted

====================
Lisp connection closed unexpectedly: exited abnormally with code 256

…なるほど。inferior lisp program は殺せても、Emacs上でのバッファは消えない。おまけにSLIMEから見るとinferior lisp program は勝手に終了したことになっている。つまりこれは正統な終了のさせ方ではない、と。


で、正解は、REPL上でカンマ→quit とすること。またはM-x slime-quit-lisp。このSLIME組み込み関数は、lisp-runを正常に終了させて*inferior-lisp*バッファも閉じる。


ところが、これでも残るものがある。SLIMEより起動された幾つかのバッファだ。このバッファ、slime専用のものは"*slime-"から始まっている*1ので、それらを選択的に閉じればよい。
自分で作ることも可能だろうけど、既に作られていたので紹介。

(defun slime-kill-all-buffers ()
  "Kill all the slime related buffers. This is only used by the
  repl command sayoonara."
  (dolist (buf (buffer-list))
    (when (or (string= (buffer-name buf) slime-event-buffer-name)
              (string-match "^\\*inferior-lisp*" (buffer-name buf))
              (string-match
                  "^\\*slime-repl\\[[0-9]+\\]\\*$" (buffer-name buf))
              (string-match "^\\*sldb .*\\*$" (buffer-name buf)))
      (kill-buffer buf))))

ソース : http://common-lisp.net/pipermail/clotho-cvs/2004-July.txt
バージョン管理のログらしきものから更新部を抜き出したものなので、実は全然嘘かもしれない。
そもそも、string-matchに「はじめが"*slime-"」という条件が無いように見えるんですが。私の早とちりですか。まあいいや。


さらに、このslime-kill-all-buffers関数を使用して、SLIMEの便利な終了処理を作った人もいる。

(defun slime-smart-quit ()
  (interactive)
  (when (slime-connected-p)
    (if (equal (slime-machine-instance) "my.workstation")
      (slime-quit-lisp)
      (slime-disconnect)))
  (slime-kill-all-buffers)) 

ソース:Google グループ
これは(まだ確かめていないけど)便利(だと思う)。
さらに、これをEmacs終了時に呼び出すようにすれば、SLIMEを起動した状態でEmacsを閉じてももう平気。

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

ソースは上に同じ。
これは~/.emacsに書く内容。


ってな感じのことを調べてました。あれ?
setfの実装を考えようとしていたはずが…いつの間に。ふしぎだわ。

*1:*Messages*なども起動されるけれど、それらは他のプログラムでも使っている可能性がある