before-save-hook para modo cc

13

Quero personalizar cc-modepara executar uma função antes de salvar. Uma solução seria modificar o cc-modemapa de teclas para vincular C-x C-sa uma função que executa o trabalho de que preciso e, em seguida, o salva.

Minha pergunta é se existe um gancho que eu possa personalizar para isso? Os documentos do CC Hooks não mencionam um before-save-hookespecificamente para cc-mode. Como isso deve ser feito através de um gancho?

Como alternativa, como faço isso defadvice? Ao ler o manual, a única maneira que pude ver foi ativar o conselho antes de salvar e depois desabilitá-lo após o término do trabalho. Isso parece complicado. Qual seria a maneira idiomática de usar advices?

Pradhan
fonte
3
A função à qual você adiciona before-save-hookpode verificar o modo principal atual (por exemplo (eq major-mode ...)) e não fazer nada se não corresponder ao modo que você está personalizando.
Constantine
@Constantine Concordou. Eu queria verificar se há algo mais "embutido" para esse tipo de coisa. O IIRC haskell-modetem pelo menos um dos after/before-saveganchos e eu assumi que essa era uma prática padrão para os modos prog.
Pradhan
@ Constantine: você poderia converter seu comentário em uma resposta (expandindo um pouco, é claro)?
Dan
1
Veja este tópico para um exemplo de uso de after-save-hook; você pode usar o mesmo tipo de procedimento, mas substitua before-save-hook.
Dan

Respostas:

12

Uma maneira bastante comum de restringir a ação de um gancho a um modo principal específico é verificar o valor de major-mode.

Por exemplo, este gancho imprime uma mensagem antes de salvar 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 uma observação lateral: às vezes pode ser útil verificar se um modo principal é derivado do Modo CC; podemos fazer isso verificando se c-buffer-is-cc-modenão está 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.")))
Constantine
fonte
19

Como alternativa, use um gancho local:

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

Isso adiciona MY-HOOK-FUNCao buffer-local before-save-hook de cada buffer do modo C ++ ou a qualquer buffer em um modo derivado do modo C ++.

Acho isso mais elegante que a verificação explícita major-modee tem a vantagem de desabilitar before-save-hook localmente para cada buffer M-: (remove-hook 'before-save-hook MY-HOOK-FUNC 'local)sem afetar outros buffers.

lunaryorn
fonte
-1

Uma vez eu precisei de algo assim para compilar automaticamente meus arquivos elisp quando salvos, usei uma abordagem como esta (converti a abordagem para o modo cc):

(add-hook 'c-common-hook #'(lambda ()
                              (add-hook 'before-save-hook #'(lambda ()
                                                               (funcall #'YOUR-FUNC-HOOK)))))
user3672638
fonte
1
Primeiro, você quis dizer c-mode-common-hook? Segundo, parece que ela adicionará a função à before-save-hookprimeira vez que você inserir um Cidioma relacionado, mas essa função será chamada imediatamente antes de cada salvamento em cada buffer. O que o OP precisa fazer é executar a função condicional no buffer estar em um modo específico (consulte o comentário de @ Constantine para saber como).
Dan