before-save-hook para modo cc

13

Quiero personalizar cc-modepara ejecutar una función antes de guardar. Una solución sería modificar el cc-modemapa de teclas para vincularlo C-x C-sa una función que realiza el trabajo que necesito y luego lo guarda.

Mi pregunta es si hay un gancho que pueda personalizar para esto. Los documentos de CC Hooks no mencionan before-save-hookespecíficamente para cc-mode. ¿Cómo debe hacerse esto a través de un gancho?

Alternativamente, ¿cómo hago esto defadvice? Al leer el manual, la única forma en que pude ver fue habilitar el consejo antes de guardarlo y luego deshabilitarlo una vez que el trabajo está hecho. Esto suena engorroso. ¿Cuál sería la forma idiomática de usar advices?

Pradhan
fuente
3
La función a la que agrega before-save-hookpuede verificar el modo principal actual (por ejemplo (eq major-mode ...)) y no hacer nada si no coincide con el modo que está personalizando.
Constantine
@Constantine De acuerdo. Quería verificar si hay algo más "incorporado" para este tipo de cosas. IIRC haskell-modetiene al menos uno de los after/before-saveganchos y supuse que esta era una práctica estándar para los modos de programa.
Pradhan
@Constantine: ¿podría convertir su comentario en una respuesta (expandiéndose un poco, por supuesto)?
Dan
1
Vea este hilo para un ejemplo de uso de after-save-hook; puede usar el mismo tipo de procedimiento pero sustituto before-save-hook.
Dan

Respuestas:

12

Una forma bastante común de restringir la acción de un gancho a un modo principal particular es verificar el valor de major-mode.

Por ejemplo, este enlace imprime un mensaje antes de guardar buffers usando c++-mode:

(defun my-c++-mode-before-save-hook ()
  (when (eq major-mode 'c++-mode)
    (message "It's never too early to start saving (C++ code)!")))

(add-hook 'before-save-hook #'my-c++-mode-before-save-hook)

Como nota al margen: a veces puede ser útil verificar si un modo principal se deriva del modo CC; podemos hacer esto comprobando si c-buffer-is-cc-modeno es así nil:

(defun my-cc-mode-before-save-hook ()
  (when c-buffer-is-cc-mode
    (message "Saving a buffer with a major-mode derived from CC Mode.")))
Constantina
fuente
19

Alternativamente, use un gancho local:

(add-hook 'c++-mode-hook
          (lambda () (add-hook 'before-save-hook MY-HOOK-FUNC nil 'local)))

Esto se agrega MY-HOOK-FUNCal búfer local before-save-hook de cada búfer de modo C ++, o cualquier búfer en un modo derivado del modo C ++.

Esto me parece más elegante que la comprobación explícita major-mode, y tiene la ventaja de que puede deshabilitarlo before-save-hook localmente para cada búfer M-: (remove-hook 'before-save-hook MY-HOOK-FUNC 'local)sin afectar a ningún otro búfer.

Lunaryorn
fuente
-1

Una vez necesité algo así para autocompilar mis archivos elisp cuando los guardé, usé un enfoque como este (convertí el enfoque al modo cc):

(add-hook 'c-common-hook #'(lambda ()
                              (add-hook 'before-save-hook #'(lambda ()
                                                               (funcall #'YOUR-FUNC-HOOK)))))
usuario3672638
fuente
1
Primero, ¿quisiste decir c-mode-common-hook? En segundo lugar, parece que agregará la función a before-save-hookla primera vez que ingrese un Clenguaje relacionado, pero luego se llamará a esa función justo antes de cada guardado en cada búfer. Lo que OP necesita hacer es ejecutar la función condicional para que el búfer esté en un modo específico (vea el comentario de @ Constantine para saber cómo).
Dan