In relativ aktuellen Versionen von Emacs (z. B. in meiner Kopie von Emacs 24.2, nicht jedoch in der Verteilung von OS X von Emacs 22.1 von OS X) können Sie Elisp-Code schreiben, der einen Befehl an den Emacsclient sendet und ihn mit einem Exit-Status zum Beenden auffordert.
Das ist einfacher als es sich anhört.
Es gibt eine lokale Puffervariable server-buffer-clients
mit den Clients, die an den Puffer angehängt sind. Mit der Funktion server-send-string
können Befehle nach dem server-process-filter
Protokoll übertragen werden.
Zum Beispiel:
(server-send-string (car server-buffer-clients) "-error die")
bewirkt, dass (einer der mit dem Puffer verknüpften) Emacsclient den Text sofort ausgibt
*ERROR*: die
und dann mit Exitcode 1 beenden.
Es ist also ziemlich einfach, eine interaktive Funktion zu definieren, die Sie von emacs selbst aufrufen können, um die emacsclients auszuschalten:
(defun tell-emacsclients-for-buffer-to-die () "Sends error exit command to every client for the current buffer." (interactive) (dolist (proc server-buffer-clients) (server-send-string proc "-error die")))
Mit dem oben genannten in Ihrer .emacs
Datei (und einer ausreichend aktuellen Version von Emacs) können Sie aufrufen M-x tell-emacsclients-for-buffer-to-die
, um die Emacsclients mit Fehlerstatus zu beenden. (Natürlich können Sie diese Funktion auch an eine geeignete alternative Tastenfolge binden.)
Fußnote
Idealerweise würde man dann die obige Funktion mit einem Haken an der server-kill-buffer
Funktion koppeln, um die Zielnummer (2.) in der ursprünglichen Frage zu erreichen. (Das heißt, C-x #
wenn Sie den Puffer töten, ohne ihn zu speichern, wird derselbe Fehler ausgegeben, der von emacsclient ausgeführt wird.)
Meine Versuche, dies zu dem zu addieren, kill-buffer-hook
sind jedoch fehlgeschlagen, da die server-kill-buffer
Funktion kill-buffer-hook
nach dem server-visit-hook
Ausführen der Hooks an die Spitze der Liste gesetzt wird und die Standardfunktion daher server-kill-buffer
zuerst ausgeführt wird. (Man könnte das kill-buffer-hook
später reparieren, aber ich bin mir noch nicht sicher, wo der Code dafür in den Elisp-Kontrollfluss eingefügt werden soll.)
Update: Okay, hier ist eine wirklich hackige Methode, um das Obige zu erreichen:
(defun kill-buffer-with-special-emacsclient-handling () (interactive) (add-hook 'kill-buffer-hook 'tell-emacsclients-for-buffer-to-die nil t) (kill-buffer)) (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling)
Update 2: Etwas robustere Variante:
(defun kill-buffer-with-special-emacsclient-handling () "Wrapper around kill-buffer that ensures tell-emacsclients-for-buffer-to-die is on the hooks" (interactive) (add-hook 'kill-buffer-hook 'tell-emacsclients-for-buffer-to-die nil t) (kill-buffer)) ;; (global-set-key (kbd "C-x k") 'kill-buffer) (defun install-emacsclient-wrapped-kill-buffer () "Installs wrapped kill-buffer with special emacsclient handling. Best not to install it unconditionally because the server is not necessarily running." (interactive) (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling)) (add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer)