Właściwy sposób włączenia trybu pomocniczego

24

Mam foo-mode i pozwoliłoby bar-moll-mode dla niego. Który sposób jest bardziej powszechny i ​​preferowany?

ZA

(add-hook 'foo-mode-hook 'bar-minor-mode)

b

(add-hook 'foo-mode-hook (lambda ()
                           "Turn on `bar-minor-mode' mode."
                           (bar-minor-mode 1)))

do

(defun bar-minor-mode-on ()
  "Turn on `bar-minor-mode' mode."
  (interactive)
  (bar-minor-mode 1))

(add-hook 'foo-mode-hook 'bar-minor-mode-on)

re

• wariant C, ale funkcja przesunięta do góry

mi

• wariant C, ale funkcja zapisana w recepturze wtyczki

Netsu
źródło
4
Cześć @Netsu, zauważyłem, że dodałeś z powrotem cytat, który usunąłem z twojej lambda. Ogólnie rzecz biorąc, cytowanie lambdas jest szkodliwe, więc Stefan i ja próbujemy motywować dobre praktyki. :-)
Malabarba

Odpowiedzi:

26

To zależy od tego, której wersji Emacsa używasz (lub kierujesz reklamy). Jeśli używasz wyłącznie Emacsa 24+, możesz bezpiecznie używać wariantu A:

* Incompatible Lisp Changes in Emacs 24.1

** Passing a nil argument to a minor mode function call now ENABLES
the minor mode unconditionally.  This is so that you can write e.g.

 (add-hook 'text-mode-hook 'foo-mode)

to enable foo-mode in Text mode buffers, removing the need for
`turn-on-foo-mode' style functions.  This affects all mode commands
defined by `define-minor-mode'.  If called interactively, the mode
command still toggles the minor mode.

Pochodzi z pliku NEWS, ale zgodnie z komentarzami dobrą praktyką jest stosowanie cytowania funkcji dla symboli funkcji, na przykład:

 (add-hook 'text-mode-hook #'foo-mode)

Jeśli kod może wymagać uruchomienia pod Emacsem 23 (lub wcześniejszym), wybrałbym wariant C, ponieważ osobiście nie lubię widzieć anonimowych funkcji w zmiennych hook. (Nie jestem pewien, czy rozumiem, co masz na myśli przez warianty D i E, umysł).

phils
źródło
3
Najlepiej powinieneś używać cudzysłowów funkcji dla trybu pomocniczego, aby kompilator bajtów mógł cię ostrzec, jeśli tryb jest niezdefiniowany.
lunaryorn
Dzięki. Ale czy nadal konieczne jest cytowanie funkcji? Jakie zalety daje? Czy jest to również konieczne w przypadku jagniąt?
Netsu,
7

Oto jeszcze jeden sposób na zrobienie tego, który ma pewne zalety, zakładając, że edytujesz własną konfigurację, a nie pakiet, który dystrybuujesz.

(add-hook 'foo-mode-hook
          #'custom-foo-hook)

(defun custom-foo-hook ()
  (bar-minor-mode 1)
  (baz-minor-mode 1)
  ;; ...
  (define-key foo-mode-map "C-c C-b" #'foobar))

Zaletą jest to, że wszystko jest przechowywane w jednym haku, więc aby wyłączyć niektóre rzeczy, nie musisz tego robić remove-hook, ale zamiast tego komentować niektóre rzeczy w custom-foo-hooki C-M-x.

Możesz nawet napisać polecenie, które przeskakuje z dowolnego trybu do niestandardowego zaczepu.

abo-abo
źródło
1
Jest to (zasadniczo) wariant C o innej nazwie, ale zgadzam się, że warto podkreślić. Z pewnością takie podejście mam, kiedy dostosowuję zachowania trybu głównego w mojej własnej konfiguracji.
phils
1
Wariant C zakłada add-hookwłączenie wielu instrukcji dla każdego trybu podrzędnego. Chciałem podkreślić, że posiadanie tylko jednego add-hookoświadczenia jest zaletą.
abo-abo
Zgoda. W głowie mam dość dużo tłumaczone Wariant C do „zdefiniować funkcję niestandardową, która umożliwia tryb” zamiast „zdefiniować funkcję niestandardową, która tylko włącza tryb”, ale z perspektywy czasu ten ostatni wydaje się być intencją. Jak mówisz, zależy to od tego, czy kod jest do użytku osobistego.
phils
7

Dlaczego miałbyś zdefiniować nowe polecenie, które robi dokładnie to, co bar-minor-moderobi?

Począwszy od 24.1, wszystkie są całkowicie równoważne, więc po prostu użyj mniej zbędnego: opcja A.

(add-hook 'foo-mode-hook #'bar-minor-mode)
Malabarba
źródło
1
Czy to bezpieczne rozwiązanie? Mam na myśli to, że jeśli jeden z trybów nadrzędnych przechwytujących tryb foo ma taki sam przechwyt, niż tryb wywoływania bar-moll zadzwoni dwukrotnie, więc zostanie wyłączony. Nieoczekiwane zachowanie.
Netsu
2
@Netsu tak, wywołanie funkcji trybu podrzędnego bez argumentów WŁĄCZA tryb podrzędny bezwarunkowo.
Malabarba
4
@Malabarba Tylko od Emacsa 24. We wcześniejszych wersjach tak naprawdę przełączałbym ten tryb.
lunaryorn
1
@lunaryorn Tak, dlatego odpowiedź Filipa jest lepsza. :-) Byłem zbyt leniwy, aby naprawić mój.
Malabarba