Come collegarsi allo stato modificato del buffer?


8

Come nella variabile incorporata mode-line-modifiedche visualizza un asterisco nella riga della modalità se il buffer viene modificato.

In particolare, desidero hl-line-modedisattivare quando il buffer viene modificato e acceso quando non lo è.

Ho letto la documentazione su "Change Hooks", ma desidero hl-line-modeattivare / disattivare quando annullo una modifica come l'asterisco della riga di modalità.


3
I ganci pertinenti sembrano essere after-change-functionse first-change-hook. Se, per qualche motivo, l'annullamento da un buffer modificato a uno non modificato non viene considerato come una "modifica" per questi hook, è possibile consigliare undodi eseguire l'interruttore.
Dan

Vedi anche la funzione buffer-modified-pper verificare se si è verificata una modifica. Sto usando after-save-hooke first-change-hookper attivare / disattivare un indicatore modificato sulla mia barra delle schede.
elenco delle leggi

3
se gli hook di modifica non funzionano perfettamente durante l'annullamento, il modo più sicuro è post-command-hookquello che controlla buffer-modified-p.
Malabarba,

Risposte:


5

Sulla base dei commenti, ecco due modi per ottenere ciò che stai cercando di fare. (Non ampiamente testato, quindi YMMV.)

Opzione 1: post-command-hook

Creare una funzione che verifica se il buffer viene modificato o meno e quindi collegarlo a post-command-hook:

(defun hl-line-mode-toggle-maybe ()
  "Turn on `hl-line-mode' when buffer is unmodified, turn it off
when it is modified."
  (hl-line-mode (if (buffer-modified-p) -1 1)))

(add-hook 'post-command-hook #'hl-line-mode-toggle-maybe)

Il vantaggio è che è piuttosto semplice. Lo svantaggio è che Emacs eseguirà questo test dopo ogni singolo comando , il che sembra eccessivo.

Opzione 2: first-change-hook, after-save-hook, eundo

Crea una funzione per hl-line-modedisattivarla e agganciarla first-change-hook. Crea una funzione per attivarla hl-line-modee agganciarla after-save-hook. Fornire afterconsigli in modo undotale che si attivi hl-line-modequando un annullamento ha riportato il buffer in uno stato non modificato:

(defun hl-line-mode-off ()
  "Turn off `hl-line-mode'."
  (hl-line-mode -1))

(defun hl-line-mode-on ()
  "Turn off `hl-line-mode'."
  (hl-line-mode 1))

(add-hook 'first-change-hook #'hl-line-mode-off)
(add-hook 'after-save-hook   #'hl-line-mode-on)

(defadvice undo (after hl-line-when-unmodified activate)
  (unless (buffer-modified-p)
    (hl-line-mode 1)))

Il vantaggio è che chiama queste funzioni raramente piuttosto che dopo ogni comando. Lo svantaggio è che hai dovuto approfondire i consigli e potrebbero esserci altri modi imprevisti per portare un buffer in uno stato non modificato che non attiva il passaggio "riaccendi hl-line-mode".


Ah, sì, grazie per averci dato una risposta. Ho finito per usare la seconda opzione per non usare a post-command-hook.
tata

revert-buffersembra un altro caso comune che metterebbe il buffer in uno stato non modificato. È possibile utilizzare il after-revert-hookper gestire questo.
glucas,

Avresti anche bisogno di un modo per attivare l'evidenziazione per i buffer appena aperti - forse il after-change-major-mode-hook?
Glucas,

1
Si noti che add-hookha un localparametro, quindi se si desidera solo ignorare il comportamento in determinate modalità o buffer principali, è possibile.
Wilfred Hughes,
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.