Определение производных режимов
Рекомендуемый способ определения нового основного режима — наследовать его от существующего с помощью define-derived-mode. Если нет близкого по назначению режима, следует наследовать его от text-mode, special-mode или prog-mode. См. Основные основные режимы. Если ни один из них не подходит, можно наследовать режим от fundamental-mode (см. Основные режимы).
- Макрос: define-derived-mode variant parent name docstring keyword-args… body…
-
Этот макрос определяет variant как команду основного режима, используя name в качестве строкового представления имени режима. variant и parent должны быть символами без кавычек.
Новая команда variant определяется так, чтобы вызывать функцию parent, а затем переопределять некоторые аспекты родительского режима:
- У нового режима есть собственная разреженная карта клавиш с именем
variant-map.define-derived-modeделает карту клавиш родительского режима родительской для новой карты, если толькоvariant-mapуже не задана и не имеет собственного родителя. - У нового режима есть собственная таблица синтаксиса, хранящаяся в переменной
variant-syntax-table, если только вы не переопределите её с помощью ключевого слова:syntax-table(см. ниже).define-derived-modeделает таблицу синтаксиса родительского режима родительской дляvariant-syntax-table, если только последняя уже не задана и не имеет родителя, отличного от стандартной таблицы синтаксиса. - У нового режима есть собственная таблица сокращений, хранящаяся в переменной
variant-abbrev-table, если только вы не переопределите её с помощью ключевого слова:abbrev-table(см. ниже). - У нового режима есть собственная функция-хук режима —
variant-hook. Она запускает этот хук после запуска хуков режимов-предков, передаваяrun-mode-hooks, в последнюю очередь, кроме запуска любой формы:after-hook, которая может быть указана. См. Хуки режимов.
Кроме того, с помощью body можно указать, как переопределить другие аспекты parent. Команда variant вычисляет формы из body после установки всех обычных переопределений и непосредственно перед запуском хуков режима.
Если у parent есть свойство символа
mode-class, отличное отnil, тоdefine-derived-modeприсваивает свойствуmode-classрежима variant то же значение. Это, например, гарантирует, что если parent — специальный режим, то variant также будет специальным режимом (см. Соглашения об основных режимах).Для parent также можно указать
nil. В таком случае у нового режима не будет родителя. Тогдаdefine-derived-modeработает так, как описано выше, но, разумеется, пропускает все действия, связанные с parent. И наоборот, можно использоватьderived-mode-set-parentиderived-mode-add-parents, описанные ниже, чтобы явно задать родословную нового режима.Аргумент docstring задаёт строку документации для нового режима.
define-derived-modeдобавляет в конец этой строки общую информацию о хуке режима, а затем карту клавиш режима. Если опустить docstring,define-derived-modeсоздаёт строку документации.Аргументы keyword-args представляют собой пары ключевых слов и значений. Значения вычисляются, за исключением значения для
:after-hook. В настоящее время поддерживаются следующие ключевые слова::syntax-table-
Это ключевое слово можно использовать, чтобы явно задать таблицу синтаксиса для нового режима. Если указать значение
nil, новый режим будет использовать ту же таблицу синтаксиса, что и parent, либо стандартную таблицу синтаксиса, если parent —nil. (Обратите внимание: здесь не действует соглашение для аргументов, не являющихся ключевыми словами, согласно которому значениеnilэквивалентно отсутствию аргумента.) :abbrev-table-
Это ключевое слово можно использовать, чтобы явно задать таблицу сокращений для нового режима. Если указать значение
nil, новый режим будет использовать ту же таблицу сокращений, что и parent, либоfundamental-mode-abbrev-table, если parent —nil. (И здесь значениеnilне эквивалентно отсутствию этого ключевого слова.) :interactive-
По умолчанию режимы являются интерактивными командами. Если указать значение
nil, определённый здесь режим не будет интерактивным. Это полезно для режимов, которые пользователи не должны включать вручную, а которые предназначены только для использования в буфере со специальным форматированием. :group-
Если указано это ключевое слово, его значение должно быть группой настройки для данного режима. (Такая группа есть не у всех основных режимов.) Эту группу использует команда
customize-mode.define-derived-modeне определяет автоматически указанную группу настройки. :after-hookЭто необязательное ключевое слово задаёт единственную форму Lisp, которую следует вычислить в самом конце функции режима, после запуска хуков режима. Форму не следует заключать в кавычки. Поскольку она может быть вычислена уже после завершения функции режима, ей не следует обращаться к элементам локального состояния функции режима. Форма
:after-hookполезна для настройки аспектов режима, зависящих от пользовательских настроек, которые, в свою очередь, могли быть изменены в хуке режима.
Вот гипотетический пример:
(defvar-keymap hypertext-mode-map "<down-mouse-3>" #'do-hyper-link) (define-derived-mode hypertext-mode text-mode "Hypertext" "Major mode for hypertext." (setq-local case-fold-search nil))
Не указывайте спецификацию
interactiveв определении:define-derived-modeделает это автоматически. - У нового режима есть собственная разреженная карта клавиш с именем
- Функция: derived-mode-p modes
-
Эта функция возвращает значение, отличное от
nil, если текущий основной режим является производным от любого из основных режимов, указанных списком символов в modes. Вместо списка modes может быть и единственным символом режима.Кроме того, мы по-прежнему поддерживаем устаревший способ вызова, при котором modes передавались как отдельные аргументы.
При проверке родительских режимов текущего основного режима эта функция учитывает его родителей, заданных с помощью
define-derived-mode, а также дополнительных родителей, заданных с помощьюderived-mode-add-parents, как описано ниже.
- Функция: provided-mode-derived-p mode modes
-
Эта функция возвращает значение, отличное от
nil, если mode является производным от любого из основных режимов, указанных списком символов в modes. Как и в случае сderived-mode-p, modes может быть единственным символом; эта функция также поддерживает устаревший способ вызова, при котором modes передавались как отдельные аргументы-символы.При проверке родительских режимов mode эта функция учитывает его родителей, заданных с помощью
define-derived-mode, а также дополнительных родителей, заданных с помощьюderived-mode-add-parents, как описано ниже.
Граф родословной основного режима можно просматривать и изменять с помощью следующих низкоуровневых функций:
- Функция: derived-mode-set-parent mode parent
Эта функция объявляет, что mode наследует свойства от
parent. Функцияdefine-derived-modeвызывает её после определения mode, чтобы зарегистрировать факт, что mode был определён с повторным использованиемparent.
- Функция: derived-mode-add-parents mode extra-parents
Эта функция позволяет зарегистрировать дополнительных родителей помимо того, который использовался при определении mode. Её можно использовать, когда сходство между mode и режимами из extra-parents достаточно велико, чтобы считать mode дочерним по отношению к этим режимам для таких целей, как применение локальных переменных каталогов и других настроек, специфичных для режима. Дополнительные родительские режимы задаются списком символов в extra-parents.
derived-mode-pиprovided-mode-derived-pбудут учитывать эти дополнительные родительские режимы как родителей mode.
- Функция: derived-mode-all-parents mode
Эта функция возвращает список всех режимов в родословной mode, упорядоченный от наиболее специфичного к наименее специфичному и начинающийся с самого mode. В список входят дополнительные родительские режимы, если таковые есть, добавленные вызовом
derived-mode-add-parents.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Derived-Modes.html