5

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?

4

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 (e.g. the pretest) then you can presumably use function add-variable-watcher to turn on/off showing trailing whitespace whenever variable buffer-read-only is changed. I haven't tried it.

(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 '18 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. – Harald Hanche-Olsen Jan 21 '18 at 20:28
1

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 '18 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 …) – Harald Hanche-Olsen Jan 21 '18 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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