Existe um gancho que é executado para todos os buffers somente leitura

7

Desejo ativar o show-trailing-whitespacearquivo editável e desativar os show-trailing-whitespacearquivos somente leitura. eu tentei

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

Mas isso só parece funcionar se eu ativar read-only-modemanualmente. Quando abro um buffer que se torna somente leitura automaticamente (por exemplo, um arquivo somente leitura), o gancho não é executado.

Existe um gancho que é executado para todos os buffers somente leitura?

Moyamo
fonte

Respostas:

6

Se você deseja que ele atue em qualquer buffer, não apenas um buffer de visita a arquivos, find-file-hooknão é apropriado. (Você disse " todos os buffers ", mas também falou de " arquivos " editáveis ​​/ não editáveis .)

Se você deseja que ele funcione em todos os buffers, esta é uma solução:

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

Você pode agrupar isso em um comando no modo secundário, se desejar.

Outra possibilidade é usar um timer inativo, mas post-command-hookparece adequado para o que você está procurando.

Até onde eu sei, não há gancho que corresponda a uma alteração buffer-read-only. No entanto, se você usar o Emacs 26 ou posterior, poderá usar a função add-variable-watcherpara ativar / desativar a exibição de espaço em branco à direita sempre que a variável buffer-read-onlyfor alterada.

(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))))
Desenhou
fonte
Parece um pouco exagerado executar esta função após cada comando. Não é o caminho mais simples?
Moyamo 21/01
@Moyamo Experimente e decida se você acha que o emacs fica lento. Minha aposta é que você não notará nenhuma desaceleração ou aumento no uso da CPU devido a esse código. Se você estiver preocupado, verifique se my-show-trailing-wsestá compilado.
Harald Hanche-Olsen
A solução do observador variável para o Emacs 26 funciona bem.
GDP2 6/06/19
1

Você pode usar find-file-hooke verificar o status somente leitura do 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)
Harald Hanche-Olsen
fonte
Como @Drew disse, isso não funcionará para buffers especiais, como buffers de agenda organizacional.
Moyamo 21/01
11
Ele está certo sobre isso. No entanto, não estava claro para mim que você queria essa generalidade. (Talvez não tenha sido claro para você, ou ...)
Harald Hanche-Olsen