Come posso chiudere automaticamente i buffer quando il file sottostante viene eliminato?


9

Lascio Emacs in esecuzione tutto il giorno e spesso eseguirò molte manipolazioni del file system su file aperti nei buffer di Emacs. Ad esempio, potrei passare a un ramo diverso in Git che ha una struttura di directory molto diversa.

Sfortunatamente questo mi lascia con un mucchio di buffer aperti che Emacs ora registra come buffer "modificati" facendo riferimento a "nuovi" file. A meno che non stia attento a chiuderli manualmente ogni volta che lo faccio, è facile salvare in modo riflessivo quei buffer che si traducono in file falsi, probabilmente duplicati nel mio progetto. Non riesco nemmeno a chiudere emacs senza rispondere alla domanda "salva questo buffer" per ognuno.

C'è un modo per chiudere automaticamente i buffer non modificati quando il file sottostante scompare? Simile nello spirito a un global-auto-revert-modeche gestisce anche quando un file viene rimosso completamente?


Consulta il manuale Emacs sezione 38.20 Notifiche sulle modifiche ai file
izkon,

Risposte:


6

Penso che qualcosa di simile potrebbe funzionare:

(defun buffer-backed-by-file-p (buffer)
  (let ((backing-file (buffer-file-name buffer)))
    (if (buffer-modified-p buffer)
        t
      (if backing-file
          (file-exists-p (buffer-file-name buffer))
        t))))

(mapc 'kill-buffer (-remove 'buffer-backed-by-file-p (buffer-list)))

La buffer-backed-by-file-pfunzione controlla se il file è supportato da un file; in caso contrario, restituisce true, altrimenti restituisce se esiste il file di backup. Prendiamo quindi l'elenco dei buffer, filtrando tutto tranne quelli che dovrebbero avere un file di backup, ma il file non esiste e quindi li uccidiamo.

Richiede dash.el per -remove, perché ero troppo pigro per trovare un built-in per ottenere la stessa cosa.

Spero che sia di aiuto!


Devi comunque eseguire quel mapccomando ogni volta che vuoi eliminare i buffer non supportati da file, vero? Quindi non è completamente automatico. Per una completa automazione dovresti assicurarti che venga mapceseguito ripetutamente da solo o utilizzare qualcosa di simile inotifyper eseguirlo quando un file viene effettivamente eliminato.
Iizkon,

Sì, è necessario eseguirlo periodicamente o in risposta a inotificare eventi o simili. Io stesso, lo eseguivo periodicamente, ogni minuto o giù di lì. Non perfetto, ma abbastanza buono per la maggior parte dei casi. (run-with-timer 60 60 (lambda () (mapc 'kill-buffer (-remove 'buffer-backed-by-file-p (buffer-list)))))è quello che userei come prima approssimazione.
Algernon,

1
Implementato questo, e ha funzionato alla grande. Ho usato questa piccola funzione wrapper per chiamarla, nel caso in cui qualcuno abbia bisogno di qualcosa di simile: `(defun kill-rimosso-buffers () (interattivo) (let ((to-kill (-remove 'buffer-backed-by-file-p (buffer-list))))) (mapc 'kill-buffer to-kill) (messaggio "Killed% s buffers" (length to-kill))))) `Mi dispiace non riuscire a formattarlo correttamente nella casella dei commenti .
levand,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.