Spec-Zone.ru › Elisp

Правила написания вспомогательных режимов

Существуют соглашения для написания вспомогательных режимов, так же как и для основных режимов (см. Основные режимы). Эти соглашения описаны ниже. Самый простой способ следовать им — использовать макрос define-minor-mode. См. Определение вспомогательных режимов.

  • Определите переменную, имя которой заканчивается на ‘-mode’. Мы называем её переменной режима. Команда вспомогательного режима должна установить эту переменную. Значение будет nil если режим отключён, и не-nil если режим включён. Переменная должна быть локальной для буфера, если вспомогательный режим локален для буфера.

    Эта переменная используется в сочетании с minor-mode-alist для отображения имени вспомогательного режима в строке режима. Она также определяет, активен ли набор клавиш вспомогательного режима, посредством minor-mode-map-alist (см. Управление активными наборами клавиш). Отдельные команды или хуки также могут проверять её значение.

  • Определите команду, называемую командой режима, имя которой совпадает с именем переменной режима. Её задача — установить значение переменной режима, плюс всё остальное, что необходимо для фактического включения или выключения функций режима.

    Команда режима должна принимать один необязательный аргумент. Если она вызывается интерактивно без префиксного аргумента, она должна переключать режим (т.е., включать, если он отключён, и отключать, если он включён). Если она вызывается интерактивно с префиксным аргументом, она должна включать режим, если аргумент положительный, и отключать в противном случае.

    Если команда режима вызывается из Lisp (т.е., не интерактивно), она должна включать режим, если аргумент опущен или nil; она должна переключать режим, если аргумент является символом toggle; в противном случае она должна обрабатывать аргумент так же, как для интерактивного вызова с числовым префиксным аргументом, как описано выше.

    Следующий пример показывает, как реализовать это поведение (он похож на код, сгенерированный макросом define-minor-mode):

    (interactive (list (or current-prefix-arg 'toggle)))
    (let ((enable
           (if (eq arg 'toggle)
               (not foo-mode) ; this is the mode’s mode variable
             (> (prefix-numeric-value arg) 0))))
      (if enable
          do-enable
        do-disable))
    

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

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

    Это работает правильно, вне зависимости от того, был ли foo-mode уже включён, поскольку команда режима foo-mode безусловно включает вспомогательный режим, когда она вызывается из Lisp без аргумента. Отключение вспомогательного режима в хуке режима немного сложнее:

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

    Однако, это не очень часто делается.

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

  • Добавьте элемент в minor-mode-alist для каждого вспомогательного режима (см. Определение minor-mode-alist), если вы хотите указать вспомогательный режим в строке режима. Этот элемент должен быть списком следующего формата:
    (mode-variable string)
    

    Здесь mode-variable — переменная, которая управляет включением вспомогательного режима, а string — короткая строка, начинающаяся с пробела, для представления режима в строке режима. Эти строки должны быть короткими, чтобы иметь место для нескольких из них одновременно.

    Когда вы добавляете элемент в minor-mode-alist, используйте assq для проверки наличия существующего элемента, чтобы избежать дублирования. Например:

    (unless (assq 'leif-mode minor-mode-alist)
      (push '(leif-mode " Leif") minor-mode-alist))
    

    или так, используя add-to-list (см. Переменные списков):

    (add-to-list 'minor-mode-alist '(leif-mode " Leif"))
    

Кроме того, несколько соглашений для основных режимов (см. Соглашения для основных режимов) также применяются к вспомогательным режимам: те, которые касаются имён глобальных символов, использования хука в конце функции инициализации, и использования наборов клавиш и других таблиц.

Вспомогательный режим, если возможно, должен поддерживать включение и выключение через Настройка (см. Настройка). Для этого переменная режима должна быть определена с defcustom, обычно с :type 'boolean. Если просто установления переменной недостаточно для включения режима, вы также должны указать метод :set, который включает режим, вызывая команду режима. В документации переменной укажите, что установка переменной, отличная от настройки через Настройку, может не сработать. Также отметьте определение меткой автозагрузки (см. метка автозагрузки), и укажите :require, чтобы при настройке переменной загружалась библиотека, которая определяет режим. Например:

;;;###autoload
(defcustom msb-mode nil
  "Toggle msb-mode.
Setting this variable directly does not take effect;
use either \\[customize] or the function `msb-mode'."
  :set 'custom-set-minor-mode
  :initialize 'custom-initialize-default
  :version "20.4"
  :type    'boolean
  :group   'msb
  :require 'msb)

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Minor-Mode-Conventions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API