Building off of the comments, here are two ways to achieve what you're trying to do. (Not extensively tested, so YMMV.)
Option 1: post-command-hook
Create a function that tests whether or not the buffer is modified, and then hook it into 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)
The advantage is that it's pretty simple. The disadvantage is that Emacs will run this test after every single command, which seems like overkill.
Option 2: first-change-hook
, after-save-hook
, and undo
Create a function to turn hl-line-mode
off and hook it into first-change-hook
. Create a function to turn hl-line-mode
on and hook it into after-save-hook
. Provide after
advice on undo
such that it turns hl-line-mode
on when an undo had returned the buffer to an unmodified state:
(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)))
The advantage is that it calls these functions infrequently rather than after every command. The disadvantage is that you've had to delve into advice, and there may be other, unanticipated ways to get a buffer to an unmodified state that don't trigger the "turn hl-line-mode
back on" step.
after-change-functions
andfirst-change-hook
. If, for some reason, undoing from a modified buffer to an unmodified one doesn't count as a "change" for these hooks, you could adviseundo
to perform the toggle.buffer-modified-p
to test for whether a modification has occurred. I am using theafter-save-hook
andfirst-change-hook
to toggle a modified indicator on my tabbar.post-command-hook
that checksbuffer-modified-p
.