Comment se connecter à l'état modifié du tampon?

8

Comme dans la variable intégrée mode-line-modifiedqui affiche un astérisque dans la ligne de mode si le tampon est modifié.

Plus précisément, je souhaite hl-line-modedésactiver lorsque le tampon est modifié et activé lorsqu'il ne l'est pas.

J'ai lu la documentation sur "Modifier les crochets", mais je souhaite hl-line-modebasculer lorsque j'annule une modification comme l'astérisque de la ligne de mode.

nounou
la source
3
Les crochets pertinents semblent être after-change-functionset first-change-hook. Si, pour une raison quelconque, l'annulation d'un tampon modifié à un tampon non modifié ne compte pas comme un "changement" pour ces hooks, vous pouvez conseiller undod'effectuer la bascule.
Dan
Voir aussi la fonction buffer-modified-ppour tester si une modification s'est produite. J'utilise les touches after-save-hooket first-change-hookpour basculer un indicateur modifié sur ma barre d'onglets.
lawlist
3
si les crochets de changement ne fonctionnent pas parfaitement lors de l'annulation, le moyen le plus sûr est post-command-hookcelui qui vérifie buffer-modified-p.
Malabarba

Réponses:

5

À partir des commentaires, voici deux façons de réaliser ce que vous essayez de faire. (Pas largement testé, donc YMMV.)

Option 1: post-command-hook

Créez une fonction qui teste si le tampon est modifié ou non, puis connectez-le à 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)

L'avantage est que c'est assez simple. L'inconvénient est qu'Emacs exécutera ce test après chaque commande , ce qui semble exagéré.

Option 2: first-change-hook, after-save-hooketundo

Créez une fonction pour la hl-line-modedésactiver et la raccorder first-change-hook. Créez une fonction pour l'activer hl-line-modeet la connecter after-save-hook. Fournissez des afterconseils sur la façon undodont elle s'allume hl-line-modelorsqu'une annulation a remis le tampon dans un état non modifié:

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

L'avantage est qu'il appelle ces fonctions rarement plutôt qu'après chaque commande. L'inconvénient est que vous avez dû vous plonger dans des conseils, et il peut y avoir d'autres façons imprévues de mettre un tampon dans un état non modifié qui ne déclenchent pas l' hl-line-modeétape de «réactivation».

Dan
la source
Ahh, oui, merci d'avoir mis cela dans une réponse. J'ai fini par utiliser la deuxième option pour ne pas utiliser a post-command-hook.
nounou
revert-buffersemble être un autre cas courant qui mettrait le tampon dans un état non modifié. Vous pouvez utiliser le after-revert-hookpour gérer celui-ci.
glucas
Vous auriez également besoin d'un moyen d'activer la mise en surbrillance pour les tampons nouvellement ouverts - peut-être le after-change-major-mode-hook?
glucas
1
Notez qu'il add-hooka un localparamètre, donc si vous voulez simplement remplacer le comportement dans certains modes ou tampons majeurs, vous pouvez.
Wilfred Hughes