Правильный способ включить второстепенный режим


24

У меня есть режим foo, и я бы включил для него бар-минорный режим . Так какой путь более распространен и предпочтителен?

A

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

В

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

С

(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)

D

• вариант C, но функция перенесена в восходящий поток

Е

• вариант C, но функция хранится в рецепте плагина


4
Привет @ Нецу, я заметил, что ты добавил цитату, которую я удалил из твоей лямбды. В общем, цитировать лямбды вредно, поэтому Стефан и я просто пытаемся мотивировать хорошие практики. :-)
— Малабарба

Ответы:


26

Это зависит от того, какую версию (версии) Emacs вы используете (или нацеливаетесь). Если вы используете исключительно Emacs 24+, вы можете смело использовать вариант 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.

Это из файла NEWS, но в соответствии с комментариями рекомендуется использовать кавычки функций для символов функций, например:

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

Если код может потребоваться запустить под Emacs 23 (или более ранней версии), я бы выбрал вариант C, так как лично мне не нравится видеть анонимные функции в переменных хуков. (Я не уверен, что понимаю, что вы подразумеваете под вариантами D & E, запомните).


3
Желательно использовать кавычки функций для второстепенного режима, чтобы байтовый компилятор мог предупредить вас, если режим не определен.
— lunaryorn

Спасибо. Но все же необходимо ли использовать функцию цитирования? Какие преимущества это дает? Также это необходимо для лямбд?
— Нетсу


7

Вот еще один способ сделать это, который имеет некоторые преимущества, предполагая, что вы редактируете свою собственную конфигурацию, а не пакет, который вы распространяете.

(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))

Преимущество состоит в том, что все хранится в одном хуке, поэтому чтобы отключить некоторые вещи, вам не нужно ничего делать remove-hook, а вместо этого комментировать некоторые вещи в custom-foo-hookи C-M-x.

Вы даже можете написать команду, которая переходит из любого режима в свой пользовательский хук.


1
Это (по сути) вариант C с другим именем, но я согласен, что стоит подчеркнуть. Это, безусловно, тот подход, который я использую, когда настраиваю поведение основного режима в своем собственном конфиге.
— Филс

1
Вариант C предполагает add-hookвключение нескольких операторов для каждого второстепенного режима. Я хотел подчеркнуть, что наличие только одного add-hookутверждения является преимуществом.
— abo-abo

Согласовано. В моей голове я в значительной степени перевел вариант C, чтобы «определить пользовательскую функцию, которая включает режим», а не «определить пользовательскую функцию, которая только включает режим», но, оглядываясь назад, последняя, ​​похоже, была намерением. Как вы говорите, это зависит от того, предназначен ли код для личного использования.
— Филс

7

Почему вы определяете новую команду, которая делает именно то, что bar-minor-modeделает?

Начиная с 24.1, все они полностью эквивалентны, поэтому просто используйте менее избыточный: вариант A

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

1
Это безопасное решение? Я имею в виду, если один из родительских режимов foo-mode-hook имеет тот же хук, что bar-minor-mode будет вызывать дважды, поэтому будет отключен. Неожиданное поведение.
— Нетсу

2
@ Нецу да, вызов функции второстепенного режима без аргументов ВКЛЮЧАЕТ безусловный режим.
— Малабарба

4
@Malabarba Только в Emacs 24. В более ранних версиях я действительно переключал режим.
— lunaryorn

1
@lunaryorn Да, поэтому ответ Филса лучше. :-) Я был слишком ленив, чтобы починить мой.
— Малабарба
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.