before-save-hook для cc-mode

13

Я хочу настроить cc-modeвыполнение функции перед сохранением. Одним из решений было бы модифицировать cc-modeраскладку клавиш для привязки C-x C-sк функции, которая выполняет нужную мне работу, а затем сохраняет ее.

У меня вопрос, есть ли крючок, который я мог бы настроить для этого? Документы CC Hooks не упоминают before-save-hookспециально для cc-mode. Как это сделать через крючок?

В качестве альтернативы, как мне это сделать defadvice? Из прочтения руководства я мог только увидеть, как включить совет перед сохранением, а затем отключить после завершения работы. Это звучит громоздко. Каков был бы идиоматический способ использования advices?

Pradhan
источник
3
Функция, к которой вы добавляете, before-save-hookможет проверять текущий основной режим (например (eq major-mode ...)) и ничего не делать, если он не соответствует настраиваемому вами режиму.
Константин
@ Константин Согласен. Я хотел проверить, есть ли что-то более "встроенное" для такого рода вещей. У IIRC haskell-modeесть по крайней мере один из after/before-saveхуков, и я предположил, что это стандартная практика для прог-режимов.
Прадхан
@Constantine: не могли бы вы преобразовать свой комментарий в ответ (конечно, немного расширив)?
Дан
1
Посмотрите эту тему для примера использования after-save-hook; Вы можете использовать ту же процедуру, но заменить before-save-hook.
Дан

Ответы:

12

Одним из довольно распространенных способов ограничения действия ловушки для конкретного основного режима является проверка значения major-mode.

Например, эта ловушка печатает сообщение перед сохранением буферов, используя 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)

В качестве примечания: иногда бывает полезно проверить, является ли основной режим производным от режима CC; мы можем сделать это, проверив, если c-buffer-is-cc-modeнет 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.")))
Константин
источник
19

В качестве альтернативы используйте локальный хук:

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

Это добавляет MY-HOOK-FUNCк локальному before-save-hook буферу каждого буфера режима C ++ или любого буфера в режиме, производном от режима C ++.

Я нахожу это более элегантным, чем явная проверка major-mode, и у него есть то преимущество, что вы можете отключить before-save-hook локально для каждого буфера, M-: (remove-hook 'before-save-hook MY-HOOK-FUNC 'local)не затрагивая другие буферы.

lunaryorn
источник
-1

Когда-то мне нужно было что-то подобное для автоматической компиляции моих файлов elisp при сохранении, я использовал такой подход (преобразовал подход в cc-mode):

(add-hook 'c-common-hook #'(lambda ()
                              (add-hook 'before-save-hook #'(lambda ()
                                                               (funcall #'YOUR-FUNC-HOOK)))))
user3672638
источник
1
Во-первых, вы имели в виду c-mode-common-hook? Во-вторых, похоже, что она добавит функцию before-save-hookв первый раз, когда вы вводите Cсвязанный язык, но затем эта функция будет вызываться непосредственно перед каждым сохранением в каждом буфере. OP должен выполнить условную функцию для буфера, находящегося в определенном режиме (см. Комментарий @ Constantine).
Дан