¿Cómo guardar automáticamente los búferes cuando Emacs pierde el foco?

26

Recientemente, un usuario de Sublime Text probó Emacs por un tiempo, y estaba interesado en obtener el mismo comportamiento de guardado automático en Emacs.

Básicamente, quería que todos los buffers se guardaran cada vez que el marco perdiera el foco (realmente guardado, no solo respaldado). Esto incluye el cambio de ventanas a una aplicación completamente diferente.

No pude encontrar ningún evento que se activara al cambiar a una aplicación diferente. ¿Existe tal evento o hay otra forma de lograr el mismo comportamiento?

Tenga en cuenta que una solución basada en el tiempo no fue satisfactoria, y tampoco lo fue el comportamiento predeterminado de la copia de seguridad automática. Él específicamente quería que los buffers se guardaran (como en save-buffer) para todos los archivos.

b4hand
fuente

Respuestas:

29

Desafortunadamente, este comportamiento exacto no es posible en Emacs <= 24.3, pero puede guardar en el cambio de ventana / buffer usando defadvice(como se detalla en el blog de bbatsov ):

(defadvice switch-to-buffer (before save-buffer-now activate)
  (when (and buffer-file-name (buffer-modified-p)) (save-buffer)))
(defadvice other-window (before other-window-now activate)
  (when (and buffer-file-name (buffer-modified-p)) (save-buffer)))

En Emacs 24.4, también podrá ahorrar en la pérdida de enfoque del cuadro gracias a los nuevos ganchos de enfoque : (add-hook 'focus-out-hook 'save-buffer)(para guardar el búfer activo) o (add-hook 'focus-out-hook (lambda () (save-some-buffers t)))(para guardar todos los búferes abiertos).

shosti
fuente
1
¿Podría ampliar un poco la defadviceversión, en caso de que la publicación del blog no funcione o algo así? ¡Gracias!
Tikhon Jelvis
Desafortunadamente, esa solución guarda el búfer visible actualmente, no todos los búferes.
b4hand
1
@ b4hand: Lo siento, no me di cuenta de que eso era lo que querías. Respuesta actualizada
shosti
1
@shosti Por cierto, gracias por encontrar ese enlace al blog de bbatsov para mí. En realidad había encontrado esa solución antes, pero no pude encontrarla de nuevo. Iba a incluir eso como una de las soluciones que no funcionan en mi pregunta.
b4hand
2
Me gusta hacerlo de esta manera para evitar destrozar el minibúfer (perdón por el formato): (add-hook 'focus-out-hook (lambda () (flet ((message (format &rest args) nil)) (save-some-buffers t))))
Andreas
6

Hay focus-autosave-modeahora. Está disponible a través de MELPA. ¿Por qué no le das la oportunidad de hackear por ti?

Mark Karpov
fuente
Hola como funciona Lo he instalado pero parece que no funciona.
Asme Just
@AsmeJust, no lo uso en este momento, intente preguntar sobre su rastreador de problemas aquí: github.com/vifon/focus-autosave-mode.el/issues
Mark Karpov
¿Utiliza actualmente una alternativa o algo así?
Asme Just
No, no uso nada como eso ahora.
Mark Karpov
Pero todavía usas Emacs, ¿verdad?
Asme Just
3
(add-to-list 'focus-out-hook (lambda () (save-some-buffers t nil)))

Esto guardará todos los buffers no guardados visitando el archivo, en emacs 24.4

Łukasz Gruner
fuente
2
No use add-to-listen un gancho, use add-hook. La respuesta de shosti ya contiene la forma correcta de este fragmento.
Gilles 'SO- deja de ser malvado'
1

Para los vagabundos que tropiezan con esto, uso este formulario:

(eval-when-compile (require 'cl-lib))
;; [...]
(add-hook 'focus-out-hook
  (lambda ()
    (cl-letf (((symbol-function 'message) #'format))
      (save-some-buffers t))))

El uso de cl-letfevita que los (No files need saving)mensajes molestos obstruyan su área de eco.

PythonNut
fuente