Jak automatycznie zapisywać bufory, gdy Emacs straci ostrość?

26

Ostatnio miałem przez pewien czas użytkownika Sublime Text wypróbowującego Emacsa i był zainteresowany uzyskaniem tego samego zachowania automatycznego zapisywania w Emacsie.

Zasadniczo chciał, aby wszystkie bufory były zapisywane za każdym razem, gdy ramka traciła ostrość (naprawdę zapisywana, a nie tylko archiwizowana). Dotyczy to także przełączania okien na zupełnie inną aplikację.

Nie mogłem znaleźć żadnego zdarzenia, które zostało wywołane podczas przełączania do innej aplikacji. Czy istnieje takie wydarzenie lub istnieje inny sposób na osiągnięcie tego samego zachowania?

Uwaga: rozwiązanie oparte na czasie nie było zadowalające, podobnie jak domyślne zachowanie automatycznego tworzenia kopii zapasowych. W szczególności chciał, aby bufory były zapisywane (jak w save-buffer) dla wszystkich plików.

b4hand
źródło

Odpowiedzi:

29

Niestety, to dokładne zachowanie nie jest możliwe w Emacsie <= 24,3, ale możesz zapisać zmiany okna / bufora, używając defadvice(jak opisano na blogu bbatsova ):

(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)))

W Emacsie 24.4 będziesz także mógł oszczędzać na utracie ostrości ramki dzięki nowym hakom ostrości : (add-hook 'focus-out-hook 'save-buffer)(aby zapisać aktywny bufor) lub (add-hook 'focus-out-hook (lambda () (save-some-buffers t)))(aby zapisać wszystkie otwarte bufory).

shosti
źródło
1
Czy mógłbyś rozwinąć nieco defadvicewersję, na wypadek gdyby post bloga się nie powiódł? Dzięki!
Tikhon Jelvis,
Niestety, to rozwiązanie oszczędza aktualnie widoczny bufor, nie wszystkie bufory.
b4hand
1
@ b4hand: Przepraszamy, nie zdawałem sobie sprawy, że tego właśnie chciałeś. Odpowiedź zaktualizowana.
shosti
1
@shosti Przy okazji, dziękuję za znalezienie dla mnie linku do bloga bbatsov. Właściwie już wcześniej znalazłem to rozwiązanie, ale nie mogłem go znaleźć ponownie. Zamierzałem uwzględnić to jako jedno z niedziałających rozwiązań w moim pytaniu.
b4hand
2
Lubię to robić w ten sposób, aby uniknąć wyrzucenia minibufora (wybacz formatowanie): (add-hook 'focus-out-hook (lambda () (flet ((message (format &rest args) nil)) (save-some-buffers t))))
Andreas
6

Jest focus-autosave-modeteraz Jest dostępny za pośrednictwem MELPA. Dlaczego nie dać ci szansy na włamanie się do ciebie?

Mark Karpov
źródło
Cześć, jak to działa? Zainstalowałem go, ale wydaje się, że nie działa.
Asme Just
@AsmeJust, nie używam teraz, spróbuj zapytać na swoim trackerze
Mark Karpov
Czy używasz obecnie alternatywy czy czegoś takiego?
Asme, tylko
Nie, obecnie nie używam czegoś takiego.
Mark Karpov
Ale nadal używasz Emacsa, prawda?
Asme, tylko
3
(add-to-list 'focus-out-hook (lambda () (save-some-buffers t nil)))

Spowoduje to zapisanie wszystkich niezapisanych buforów odwiedzających plik na emacsie 24.4

Łukasz Gruner
źródło
2
Nie używaj add-to-listna haku, używaj add-hook. Odpowiedź shosti zawiera już poprawną formę tego fragmentu.
Gilles „SO- przestań być zły”
1

Dla wędrowców, którzy się na to natkną, używam tego formularza:

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

Użycie cl-letfirytujących (No files need saving)komunikatów zapobiega zatykaniu obszaru echa.

PythonNut
źródło