Dans les versions relativement actuelles d’Emacs (par exemple, dans ma copie d’Emacs 24.2, mais pas dans la distribution d’Emacs 22.1 sous OS X), vous pouvez écrire du code Elisp qui enverra une commande à emacsclient lui indiquant de quitter avec un statut d’exit d’erreur.
C'est plus facile que ça en a l'air.
Il existe une variable locale du tampon server-buffer-clients
, avec les clients attachés au tampon. Et la fonction server-send-string
peut être utilisée pour communiquer des commandes suivant le server-process-filter
protocole.
Par exemple:
(server-send-string (car server-buffer-clients) "-error die")
provoque (un des) emacsclient (s) associé (s) au tampon à émettre immédiatement le texte
*ERROR*: die
puis quittez avec le code de sortie 1.
Donc, il est assez facile de définir une fonction interactive que vous pourriez appeler depuis emacs pour tuer les clients emacs:
(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")))
Avec ce qui précède dans votre .emacs
fichier (et une version suffisamment récente d’Emacs), vous pouvez M-x tell-emacsclients-for-buffer-to-die
faire appel pour que les clients emacs soient fermés avec le statut d’erreur. (Et bien sûr, vous pouvez lier cette fonction à une autre séquence de touches appropriée.)
note de bas de page
Idéalement, on couplerait ensuite la fonction ci-dessus avec un crochet server-kill-buffer
pour atteindre le nombre d'objectifs (2.) de la question d'origine. (Autrement dit, tuer le tampon sans l'enregistrer via C-x #
devrait déclencher les mêmes erreurs que emacsclient.)
Cependant, mes tentatives pour l'ajouter à kill-buffer-hook
ont échoué, car la server-kill-buffer
fonction est placée au premier plan de la kill-buffer-hook
liste une fois les server-visit-hook
points d'ancrage exécutés. La server-kill-buffer
fonction par défaut est donc exécutée en premier. (On pourrait réparer la kill-buffer-hook
suite, mais je ne sais pas encore où mettre le code pour le faire dans le flux de contrôle Elisp.)
Mise à jour: d'accord, voici un moyen vraiment déconcertant d'accomplir ce qui précède:
(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)
Mise à jour 2: variante légèrement plus robuste:
(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)