zaczep przed zapisem dla trybu CC

13

Chcę dostosować, cc-modeaby wykonać funkcję przed zapisaniem. Jednym z rozwiązań byłoby zmodyfikowanie cc-modemapy klawiszy w celu powiązania C-x C-sz funkcją, która wykonuje pracę, której potrzebuję, a następnie zapisuje ją.

Moje pytanie brzmi, czy istnieje hak, który mogę dostosować do tego? Dokumenty CC Hooks nie wspominają o before-save-hookkonkretnym cc-mode. Jak to zrobić przez hak?

Alternatywnie, jak to zrobić defadvice? Z lektury instrukcji mogłem zobaczyć tylko włączenie porady przed zapisaniem, a następnie wyłączenie po zakończeniu pracy. Brzmi nieporęcznie. Jaki byłby idiomatyczny sposób używania advices?

Pradhan
źródło
3
Funkcja, do której dodajesz, before-save-hookmoże sprawdzić bieżący tryb główny (np. (eq major-mode ...)) I nic nie robić, jeśli nie pasuje do dostosowywanego trybu.
Constantine,
@ Constantine Agreed. Chciałem sprawdzić, czy istnieje coś bardziej „wbudowanego” do tego rodzaju rzeczy. IIRC haskell-modema co najmniej jeden after/before-savehaczyk i założyłem, że była to standardowa praktyka dla trybów progresywnych.
Pradhan
@Constantine: czy mógłbyś przekonwertować swój komentarz na odpowiedź (oczywiście trochę rozszerzając)?
Dan
1
Zobacz ten wątek na przykładowe użycie after-save-hook; możesz użyć tego samego rodzaju procedury, ale zastąpić before-save-hook.
Dan

Odpowiedzi:

12

Jednym z dość powszechnych sposobów ograniczania działania haka do określonego trybu głównego jest sprawdzenie wartości major-mode.

Na przykład ten hak drukuje komunikat przed zapisaniem buforów przy użyciu 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)

Na marginesie: czasami przydatne może być sprawdzenie, czy tryb główny pochodzi z trybu CC; możemy to zrobić, sprawdzając, czy c-buffer-is-cc-modenie 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.")))
Konstantyn
źródło
19

Alternatywnie użyj lokalnego haka:

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

To dodaje MY-HOOK-FUNCdo lokalnego before-save-hook bufora każdego bufora trybu C ++ lub dowolnego bufora w trybie pochodzącym z trybu C ++.

Uważam to za bardziej eleganckie niż jawne sprawdzanie major-modei ma tę zaletę, że możesz wyłączyć before-save-hook lokalnie dla każdego bufora M-: (remove-hook 'before-save-hook MY-HOOK-FUNC 'local)bez wpływu na inne bufory.

księżycowy
źródło
-1

Kiedyś potrzebowałem czegoś takiego do autokompilacji moich plików elisp po zapisaniu, użyłem takiego podejścia (przekonwertowałem podejście do trybu CC):

(add-hook 'c-common-hook #'(lambda ()
                              (add-hook 'before-save-hook #'(lambda ()
                                                               (funcall #'YOUR-FUNC-HOOK)))))
użytkownik3672638
źródło
1
Po pierwsze, miałeś na myśli c-mode-common-hook? Po drugie, wygląda na to, że doda funkcję do before-save-hookpierwszego wpisania Cjęzyka związanego z, ale wtedy ta funkcja będzie wywoływana tuż przed każdym zapisaniem w każdym buforze. To, co OP musi zrobić, to uruchomić funkcję pod warunkiem, że bufor będzie w określonym trybie (zobacz komentarz @ Constantine, jak to zrobić).
Dan