Comment enregistrer automatiquement les tampons lorsque Emacs perd le focus?

26

Récemment, un utilisateur de Sublime Text a essayé Emacs pendant un certain temps, et il souhaitait obtenir le même comportement d'enregistrement automatique dans Emacs.

Fondamentalement, il voulait que tous les tampons soient enregistrés chaque fois que le cadre perdait le focus (vraiment enregistré, pas seulement sauvegardé). Cela inclut lors du basculement de Windows vers une application complètement différente.

Je n'ai trouvé aucun événement déclenché lors du passage à une autre application. Existe-t-il un tel événement ou existe-t-il un autre moyen d'obtenir le même comportement?

Notez qu'une solution basée sur le temps n'était pas satisfaisante, tout comme le comportement de sauvegarde automatique par défaut. Il voulait spécifiquement que les tampons soient enregistrés (comme dans save-buffer) pour tous les fichiers.

b4hand
la source

Réponses:

29

Malheureusement, ce comportement exact n'est pas possible dans Emacs <= 24.3, mais vous pouvez économiser sur le changement de fenêtre / tampon en utilisant defadvice(comme détaillé sur le 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)))

Dans Emacs 24.4, vous pourrez également économiser sur la perte de focus du cadre grâce aux nouveaux hooks de focus : (add-hook 'focus-out-hook 'save-buffer)(pour enregistrer le tampon actif) ou (add-hook 'focus-out-hook (lambda () (save-some-buffers t)))(pour enregistrer tous les tampons ouverts).

shosti
la source
1
Pourriez-vous développer un peu la defadviceversion, au cas où l'article de blog tomberait ou quelque chose? Merci!
Tikhon Jelvis du
Malheureusement, cette solution sur enregistre le tampon actuellement visible, pas tous les tampons.
b4hand
1
@ b4hand: Désolé, je ne savais pas que c'était ce que vous vouliez. Réponse mise à jour.
shosti
1
@shosti Au fait, merci d'avoir trouvé ce lien vers le blog de bbatsov pour moi. J'avais déjà trouvé cette solution auparavant, mais je ne pouvais pas la retrouver. J'allais inclure cela comme l'une des solutions non fonctionnelles dans ma question.
b4hand
2
J'aime le faire de cette façon pour éviter de jeter le mini-tampon (pardonnez le formatage): (add-hook 'focus-out-hook (lambda () (flet ((message (format &rest args) nil)) (save-some-buffers t))))
Andreas
6

Il y en a focus-autosave-modemaintenant. Il est disponible via MELPA. Pourquoi ne pas lui donner une chance de faire le piratage pour vous?

Mark Karpov
la source
Salut, comment ça marche? Je l'ai installé mais cela ne semble pas fonctionner.
Asme Just
@AsmeJust, je ne l'utilise pas pour le moment, essayez de demander sur son tracker de problème ici: github.com/vifon/focus-autosave-mode.el/issues
Mark Karpov
Utilisez-vous actuellement une alternative ou quelque chose comme ça?
Asme Just
Non, je n'utilise rien de tel pour le moment.
Mark Karpov
Mais vous utilisez toujours Emacs, non?
Asme Just
3
(add-to-list 'focus-out-hook (lambda () (save-some-buffers t nil)))

Cela enregistrera tous les tampons non enregistrés visitant le fichier, sur emacs 24.4

Łukasz Gruner
la source
2
Ne pas utiliser add-to-listsur un crochet, utilisez add-hook. La réponse de shosti contient déjà la forme correcte de cet extrait.
Gilles 'SO- arrête d'être méchant'
1

Pour les vagabonds qui butent dessus, j'utilise ce formulaire:

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

L'utilisation de cl-letfempêche les (No files need saving)messages gênants d'obstruer votre zone d'écho.

PythonNut
la source