I want to enable show-trailing-whitespace for editable file and disable show-trailing-whitespace for read only files. I've tried

(defun my/read-only-whitespace ()
  (setq-local show-trailing-whitespace (not buffer-read-only)))

(setq-default show-trailing-whitespace t)
(add-hook 'read-only-mode-hook #'my/read-only-whitespace)

But this only only seems to work if I enable read-only-mode manually. When I open a buffer that becomes read-only automatically (e.g. a read-only file) then the hook is not run.

Is there a hook that runs for all read-only buffers?

2 Answers 2


If you want this to act in any buffer, not just a file-visiting buffer then find-file-hook is not appropriate. (You said "all buffers", but you also spoke of editable/non-editable "files".)

If you want it to work in all buffers then this is one solution:

(defun my-show-trailing-ws ()
  "Show trailing whitespace in the current buffer, unless it is read-only."
  (setq-local show-trailing-whitespace (not buffer-read-only)))

(add-hook 'post-command-hook 'my-show-trailing-ws)

You can wrap that in a minor mode command, if you like.

Another possibility is to use an idle timer, but post-command-hook seems fine for what you're looking for.

As far as I know, there is no hook that corresponds to a change in buffer-read-only. However, if you use Emacs 26 or later then you can use function add-variable-watcher to turn on/off showing trailing whitespace whenever variable buffer-read-only is changed.

(add-variable-watcher 'buffer-read-only 'foo) ; Add watcher `foo'

(defun foo (symbol newval operation where) ; 100% untested...
   "Show trailing whitespace in the current buffer, unless it is read-only."
   (when (and (eq symbol 'buffer-read-only)
              (memq operation '(set let))
              (eq where (current-buffer)))
     (setq-local show-trailing-whitespace (not newval))))
  • It seems a bit overkill to run this function after every command. Is their no simpler way?
    – Moyamo
    Jan 21, 2018 at 20:18
  • @Moyamo Try it, then decide if you think it makes emacs sluggish. My bet is that you won't notice any slowdown or increased cpu usage due to this code. If you're worried, make sure that my-show-trailing-ws is compiled. Jan 21, 2018 at 20:28
  • The variable watcher solution for Emacs 26 works well.
    – GDP2
    Jun 6, 2019 at 16:22

You could use find-file-hook and check the read only status of the buffer:

(defun my/read-only-whitespace ()
  (when buffer-read-only
    (setq-local show-trailing-whitespace (not buffer-read-only))))
(add-hook 'find-file-hook 'my/read-only-whitespace)
  • As @Drew said, this won't work for special buffers like org-agenda buffers.
    – Moyamo
    Jan 21, 2018 at 20:19
  • 1
    He's right about that. However, it wasn't clear to me that you wanted that generality. (Maybe it wasn't clear to you, either …) Jan 21, 2018 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.