advice – Cómo matar automáticamente un búfer de shell cuando finaliza el proceso de shell

Pregunta:

En shell-mode cuando sale del proceso de shell (por ejemplo, escribiendo exit ), el búfer aún permanece (con el mensaje "Process shell <1> terminado").

¿Cómo puedo matar automáticamente el búfer de shell cuando finaliza el proceso de shell?

(1) ¿Hay un paquete disponible para esto?

(2) ¿Cómo escribo el consejo de función correcto para él? Al notar que se llama a 'shell-write-history-on-exit al salir, intenté:

(defun leo-kill-shell-buffer-on-exit ()
  (kill-buffer))

(advice-add 'shell-write-history-on-exit :after #'leo-kill-shell-buffer-on-exit)

pero nada pasa. ¿Qué va mal?

Respuesta:

Utilice un centinela de procesos cuando desee reaccionar a un proceso que sale. p.ej:

Consulte los (elisp)Sentinels Ch i g (elisp)Sentinels

En este caso, shell solo llama shell-mode cuando (y después) de iniciar el proceso inferior, por lo que podemos usar shell-mode-hook para agregar el centinela.

Como señala @Tobias en los comentarios, set-process-sentinel aplastará a cualquier centinela existente para ese proceso. shell siempre tendrá un centinela (exactamente lo que es puede variar), y podemos llamarlo primero.

(defun my-shell-mode-hook ()
  "Custom `shell-mode' behaviours."
  ;; Kill the buffer when the shell process exits.
  (let* ((proc (get-buffer-process (current-buffer)))
         (sentinel (process-sentinel proc)))
    (set-process-sentinel
     proc
     `(lambda (process signal)
        ;; Call the original process sentinel first.
        (funcall #',sentinel process signal)
        ;; Kill the buffer on an exit signal.
        (and (memq (process-status process) '(exit signal))
             (buffer-live-p (process-buffer process))
             (kill-buffer (process-buffer process)))))))

(add-hook 'shell-mode-hook 'my-shell-mode-hook)

Alternativamente, @Tobias ha proporcionado una alternativa usando advice-add :

(defun add-process-sentinel (sentinel &optional process)
  "Add SENTINEL to PROCESS.
PROCESS defaults to the process of the current buffer.
Use this function with care.
If there is already a process sentinel SENTINEL is used as after-advice.
That can fail if the process sentinel is reset by some other function."
  (unless process
    (setq process (get-buffer-process (current-buffer))))
  (let ((old (process-sentinel process)))
    (cond
     ((symbolp old)
      (advice-add old :after sentinel))
     ((null old)
      (set-process-sentinel process sentinel))
     (t (warn "Cannot set sentinel %S for process %S." sentinel process)))))

(defun my-shell-mode-hook ()
  "Custom `shell-mode' behaviours."
  ;; Kill the buffer when the shell process exits.
  (add-process-sentinel
   (lambda (process signal)
     (and (memq (process-status process) '(exit signal))
          (buffer-live-p (process-buffer process))
          (kill-buffer (process-buffer process))))))

(add-hook 'shell-mode-hook 'my-shell-mode-hook)

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top

web tasarım