¿Cómo conectar al estado modificado del búfer?

8

Tal como en la variable incorporada mode-line-modifiedque muestra un asterisco en la línea de modo si se modifica el búfer.

Específicamente, quiero hl-line-modeapagar cuando el búfer se modifica y encender cuando no lo está.

He leído la documentación sobre "Cambiar ganchos", pero quiero hl-line-modealternar cuando deshago un cambio como el asterisco de línea de modo.

niñera
fuente
3
Los ganchos relevantes parecen ser after-change-functionsy first-change-hook. Si, por alguna razón, deshacer de un búfer modificado a uno no modificado no cuenta como un "cambio" para estos ganchos, puede aconsejar undoque realice el cambio.
Dan
Consulte también la función buffer-modified-ppara comprobar si se ha producido una modificación. Estoy usando after-save-hooky first-change-hookpara alternar un indicador modificado en mi barra de pestañas.
leyes
3
Si los ganchos de cambio no funcionan perfectamente al deshacer, la forma más segura es post-command-hookque se compruebe buffer-modified-p.
Malabarba

Respuestas:

5

A partir de los comentarios, aquí hay dos formas de lograr lo que está tratando de hacer. (No ampliamente probado, por lo que YMMV).

Opción 1: post-command-hook

Cree una función que pruebe si se modifica o no el búfer y luego conéctelo a 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)

La ventaja es que es bastante simple. La desventaja es que Emacs ejecutará esta prueba después de cada comando , lo que parece excesivo.

Opción 2: first-change-hook, after-save-hookyundo

Cree una función para hl-line-modeapagar y conectarla first-change-hook. Cree una función para encender hl-line-modey engancharla after-save-hook. Proporcione afterconsejos para undoque se active hl-line-modecuando un deshacer haya devuelto el búfer a un estado no modificado:

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

La ventaja es que llama a estas funciones con poca frecuencia en lugar de después de cada comando. La desventaja es que ha tenido que profundizar en los consejos, y puede haber otras formas imprevistas de llevar un búfer a un estado no modificado que no active el paso " hl-line-modevolver a encender ".

Dan
fuente
Ahh, sí, gracias por responder eso. Terminé usando la segunda opción para no usar a post-command-hook.
niñera
revert-bufferParece otro caso común que pondría el búfer en un estado no modificado. Podrías usar el after-revert-hookpara manejar este.
glucas
También necesitaría alguna forma de activar el resaltado para los buffers recién abiertos, ¿tal vez after-change-major-mode-hook?
glucas
1
Tenga en cuenta que add-hooktiene un localparámetro, por lo que si solo desea anular el comportamiento en ciertos modos principales o búferes, puede hacerlo.
Wilfred Hughes