Основные правила оформления режимов
Код каждого основного режима должен соответствовать различным правилам оформления кода, включая правила для инициализации локальной карты управления клавишами и таблицы синтаксиса, названий функций и переменных, а также хуков.
Если вы используете макрос define-derived-mode, он автоматически позаботится о многих из этих правил. См. Производные режимы. Обратите также внимание, что основной режим Fundamental является исключением из многих из этих правил, поскольку он представляет собой состояние по умолчанию Emacs.
Следующий список правил неполный. Каждый основной режим должен стремиться к согласованности с другими основными режимами Emacs, так как это делает Emacs в целом более согласованным. Невозможно перечислить здесь все возможные точки, где эта проблема может возникнуть; если разработчики Emacs укажут область, где ваш основной режим отклоняется от обычных правил, пожалуйста, сделайте его совместимым.
- Определите команду режима-главного, имя которой оканчивается на ‘-mode’. При вызове без аргументов эта команда должна переключиться на новый режим в текущем буфере, настроив карту клавиш, таблицу синтаксиса и переменные локальные для буфера в существующем буфере. Она не должна изменять содержимое буфера.
- Напишите строку документации для этой команды, описывающую специальные команды, доступные в этом режиме. См. Справка по режиму.
Строка документации может включать специальные подстроки документации, ‘\[command]’, ‘\{keymap}’, и ‘\<keymap>’, которые позволяют отображению справки автоматически адаптироваться к собственным сочетаниям клавиш пользователя. См. Клавиши в документации.
- Команда режима-главного должна начать с вызова
kill-all-local-variables. Это запускает обычный хукchange-major-mode-hook, затем удаляет локальные переменные режима-главного, действовавшие ранее. См. Создание локальных для буфера. - Команда режима-главного должна установить переменную
major-modeв символ команды режима-главного. Таким образомdescribe-modeопределяет, какую документацию печатать. - Команда режима-главного должна установить переменную
mode-nameв «красивое» имя режима, обычно строку (но см. Данные строки режима для других возможных форм). Имя режима отображается в строке режима. - Вызов команды режима-главного дважды подряд не должен вызывать ошибку и должен делать то же самое, что и вызов команды один раз. Другими словами, команда режима-главного должна быть идемпотентной.
- Поскольку все глобальные имена находятся в одном пространстве имён, все глобальные переменные, константы и функции, которые являются частью режима, должны иметь имена, начинающиеся с имени режима-главного (или с сокращения от него, если имя длинное). См. Правила кодирования.
- В режиме-главном для редактирования какого-либо структурированного текста, такого как язык программирования, вероятно, будет полезно отступать текст в соответствии со структурой. Поэтому режим должен установить
indent-line-functionв подходящую функцию и, вероятно, настроить другие переменные для отступа. См. Автоотступ. - Режим-главный обычно имеет свою собственную карту клавиш, которая используется в качестве локальной карты клавиш во всех буферах в этом режиме. Команда режима-главного должна вызвать
use-local-mapдля установки этой локальной карты. См. Активные карты клавиш для получения дополнительной информации.Эта карта клавиш должна храниться постоянно в глобальной переменной с именем
modename-mode-map. Обычно библиотека, которая определяет режим, устанавливает эту переменную.См. Советы по определению для советов о том, как написать код для настройки переменной карты клавиш режима.
- Последовательности клавиш, привязанные в карте клавиш режима-главного, обычно должны начинаться с C-c, за которым следует управляющий символ, цифра или {, }, <, >, : или ;. Другие знаки препинания зарезервированы для второстепенных режимов, а обычные буквы — для пользователей.
Режим-главный также может переназначить клавиши M-n, M-p и M-s. Привязки для M-n и M-p обычно должны быть каким-либо видом передвижения вперёд и назад, но это необязательно означает движение курсора.
Допустимо, чтобы режим-главный переназначил стандартную последовательность клавиш, если он предоставляет команду, выполняющую ту же задачу более подходящим для текста способом, для которого используется этот режим. Например, режим-главный для редактирования языка программирования может переопределить C-M-a для перемещения к началу функции способом, который лучше подходит для этого языка. Рекомендуемый способ адаптации C-M-a к потребностям режима-главного — установить
beginning-of-defun-function(см. Список перемещений) для вызова функции, специфичной для режима.Также допустимо, чтобы режим-главный переназначил стандартную последовательность клавиш, чьё стандартное значение редко полезно в этом режиме. Например, режимы минибуфера переопределяют M-r, чьё стандартное значение редко полезно в минибуфере. Режимы-главные, такие как Dired или Rmail, которые не позволяют вставлять текст самостоятельно, могут разумно переназначить буквы и другие печатные символы в качестве специальных команд.
- Режимы-главные для редактирования текста не должны определять RET для выполнения чего-либо, кроме вставки новой строки. Однако специализированные режимы для текста, которым пользователи не редактируют напрямую, такие как режимы Dired и Info, могут переопределить RET для выполнения совершенно другого действия.
- Режимы-главные не должны изменять параметры, которые в первую очередь являются вопросом пользовательских предпочтений, например, включен ли режим автозаполнения. Пусть каждый пользователь сам решит это. Однако режим-главный должен настроить другие переменные, чтобы режим автозаполнения работал полезно, если пользователь решит его использовать.
- Режим может иметь свою собственную таблицу синтаксиса или может использовать одну с другими связанными режимами. Если у него есть своя собственная таблица синтаксиса, он должен хранить её в переменной с именем
modename-mode-syntax-table. См. Таблицы синтаксиса. - Если режим обрабатывает язык, у которого есть синтаксис для комментариев, он должен установить переменные, определяющие синтаксис комментариев. См. Параметры, управляющие комментариями в Справочнике по GNU Emacs.
- Режим может иметь свою собственную таблицу сокращений или использовать одну с другими связанными режимами. Если у него есть своя собственная таблица сокращений, он должен хранить её в переменной с именем
modename-mode-abbrev-table. Если команда режима-главного сама определяет какие-либо сокращения, она должна передатьtв качестве аргумента system-flag функцииdefine-abbrev. См. Определение сокращений. - Режим должен указать, как выполнять выделение для режима Font Lock, настроив локальное для буфера значение переменной
font-lock-defaults(см. Режим Font Lock). - Каждый шрифт, определенный режимом, должен, по возможности, наследоваться от существующего шрифта Emacs. См. Основные шрифты и Шрифты для Font Lock.
- Рассмотрите возможность добавления меню, специфичного для режима, в строку меню. Желательно, чтобы оно включало наиболее важные настройки и команды меню, которые позволят пользователям быстро и эффективно обнаружить основные функции.
- Рассмотрите возможность добавления контекстных меню, специфичных для режима, для режима, которые будут использоваться при и когда пользователи активируют
context-menu-mode(см. Нажатия мыши по меню в Справочнике по Emacs). Для этой цели определите функцию, специфичную для режима, которая строит одно или несколько меню в зависимости от расположения щелчка мышь-3 в буфере, и затем добавьте эту функцию в локальное для буфера значениеcontext-menu-functions. - Режим должен указать, как Imenu должен находить определения или разделы буфера, настроив локальное для буфера значение для переменной
imenu-generic-expression, для двух переменныхimenu-prev-index-position-functionиimenu-extract-index-name-function, или для переменнойimenu-create-index-function(см. Imenu). - Режим может указать режиму ElDoc, как извлекать различные типы документации для того, что находится в позиции, добавив одну или несколько локальных для буфера записей в специальный хук
eldoc-documentation-functions. - Режим может указать, как завершать различные ключевые слова, добавив одну или несколько локальных для буфера записей в специальный хук
completion-at-point-functions. См. Завершение в буферах. - Чтобы создать локальное для буфера привязывание для переменной настройки Emacs, используйте
make-local-variableв команде режима-главного, а неmake-variable-buffer-local. Последняя функция сделала бы переменную локальной для каждого буфера, в котором она впоследствии устанавливается, что повлияло бы на буферы, которые не используют этот режим. Нежелательно, чтобы режим имел такие глобальные последствия. См. Переменные, локальные для буфера.В редких исключениях единственный разумный способ использования
make-variable-buffer-localв пакете Lisp — это для переменной, используемой только внутри этого пакета. Использование её для переменной, используемой другими пакетами, повлияет на них. - Каждый режим-главный должен иметь нормальный хук режима с именем
modename-mode-hook. Последнее, что должна сделать команда режима-главного, — вызватьrun-mode-hooks. Это запускает обычный хукchange-major-mode-after-body-hook, хук режима, функциюhack-local-variables(когда буфер посещает файл), а затем обычный хукafter-change-major-mode-hook. См. Хук режима. - Команда режима-главного может начать с вызова другой команды режима-главного (называемой родительским режимом) и затем изменить некоторые её настройки. Режим, который делает это, называется производным режимом. Рекомендуемый способ определения такового — использование макроса
define-derived-mode, но это не обязательно. Такой режим должен вызвать команду родительского режима внутри формыdelay-mode-hooks. (Использованиеdefine-derived-modeделает это автоматически.) См. Производные режимы и Хук режима. - Если при переключении буфера из этого режима в любой другой режим-главный следует выполнить что-то особенное, этот режим может настроить локальное для буфера значение для
change-major-mode-hook(см. Создание локальных для буфера). - Если этот режим подходит только для специально подготовленного текста, созданного самим режимом (а не пользователем, печатающим с клавиатуры, или внешним файлом), то символ команды режима-главного должен иметь свойство с именем
mode-classи значениемspecial, установленное следующим образом:(put 'funny-mode 'mode-class 'special)
Это сообщает Emacs, что новые буферы, созданные во время того, как текущий буфер находится в режиме Funny, не должны быть помещены в режим Funny, даже несмотря на то, что значение по умолчанию
major-mode—nil. По умолчанию значениеnilдляmajor-modeозначает использование текущего режима-главного буфера при создании новых буферов (см. Автоматический режим-главный), но в такихspecialрежимах вместо этого используется режим Fundamental. Режимы, такие как Dired, Rmail и Список буферов, используют эту функцию.Функция
view-bufferне включает режим просмотра в буферах, класс режима которых является специальным, так как такие режимы обычно предоставляют свои собственные привязки, похожие на просмотр.Макрос
define-derived-modeавтоматически помечает производный режим как специальный, если родительский режим является специальным. Специальный режим является удобным родителем для таких режимов, от которых они могут наследоваться; См. Основные режимы-главные.
- Если вы хотите сделать новый режим по умолчанию для файлов с определенными узнаваемыми именами, добавьте элемент в
auto-mode-alistдля выбора режима для этих имен файлов (см. Автоматический основной режим). Если вы определяете команду режима для автоматической загрузки, вы должны добавить этот элемент в тот же файл, который вызываетautoload. Если вы используете файл-cookie для автоматической загрузки для команды режима, вы также можете использовать файл-cookie для формы, которая добавляет элемент (см. файл-cookie для автоматической загрузки). Если вы не загружаете команду режима автоматически, достаточно добавить элемент в файл, который содержит определение режима. - Формы верхнего уровня в файле, определяющем режим, должны быть написаны так, чтобы их можно было вычислять более одного раза без неблагоприятных последствий. Например, используйте
defvarилиdefcustomдля установки переменных, связанных с режимом, чтобы они не перезапускались, если уже имеют значение (см. Определение переменных).
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/Major-Mode-Conventions.html