Spec-Zone.ru › Elisp

Как Emacs выбирает основной режим

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

Команда: normal-mode &optional find-file

Эта функция задаёт подходящий основной режим и привязки буферно-локальных переменных для текущего буфера. Она вызывает set-auto-mode (см. ниже). Начиная с Emacs 26.1, она больше не запускает hack-local-variables; теперь это выполняется в run-mode-hooks при инициализации основных режимов (см. раздел Хуки режимов).

Если аргумент find-file для normal-mode отличен от nil, normal-mode предполагает, что её вызывает функция find-file. В этом случае она может обрабатывать локальные переменные в строке ‘-*-’ или в конце файла. За это отвечает переменная enable-local-variables. Синтаксис раздела локальных переменных файла см. в разделе Локальные переменные в файлах руководства GNU Emacs Manual.

При интерактивном запуске normal-mode аргумент find-file обычно равен nil. В этом случае normal-mode безусловно обрабатывает все локальные переменные файла.

Функция вызывает set-auto-mode, чтобы выбрать и установить основной режим. Если режим таким образом не задан, буфер остаётся в основном режиме, определяемом значением по умолчанию major-mode (см. ниже).

normal-mode использует condition-case вокруг вызова команды основного режима, поэтому ошибки перехватываются и сообщаются как ‘File mode specification error’, после чего выводится исходное сообщение об ошибке.

Функция: set-auto-mode &optional keep-mode-if-same

Эта функция выбирает и устанавливает основной режим, подходящий для текущего буфера. Она принимает решение (в порядке приоритета) на основе строки ‘-*-’, любой локальной переменной ‘mode:’ рядом с концом файла, строки ‘#!’ (с помощью interpreter-mode-alist), текста в начале буфера (с помощью magic-mode-alist) и, наконец, имени открытого файла (с помощью auto-mode-alist). См. раздел Как выбираются основные режимы руководства GNU Emacs Manual. Если enable-local-variables равно nil, set-auto-mode не проверяет строку ‘-*-’ или конец файла на наличие тегов режима.

Для некоторых типов файлов сканировать содержимое файла в поисках указания режима нецелесообразно. Например, архив tar может случайно содержать ближе к концу файл, в котором есть раздел локальных переменных с указанием режима для этого файла. Это указание не следует применять к содержащему его файлу tar. Аналогично, в файле изображения TIFF может случайно оказаться первая строка, соответствующая шаблону ‘-*-’. Поэтому оба этих расширения файлов включены в список inhibit-local-variables-regexps. Добавляйте в этот список шаблоны, чтобы Emacs не искал в таких файлах локальные переменные любого вида (а не только указания режима).

Если keep-mode-if-same отлично от nil, эта функция не вызывает команду режима, если буфер уже находится в подходящем основном режиме. Например, set-visited-file-name задаёт для этого параметра значение t, чтобы не уничтожать буферно-локальные переменные, установленные пользователем.

Функция: set-buffer-major-mode buffer

Эта функция устанавливает для buffer основной режим, равный значению по умолчанию major-mode; если оно равно nil, используется основной режим текущего буфера (если он подходит). Исключение: если имя buffer — *scratch*, функция устанавливает режим initial-major-mode.

Низкоуровневые примитивы для создания буферов не используют эту функцию, но команды среднего уровня, такие как switch-to-buffer и find-file-noselect, вызывают её при создании буферов.

Пользовательский параметр: initial-major-mode

Значение этой переменной определяет основной режим начального буфера *scratch*. Значением должен быть символ, соответствующий команде основного режима. Значение по умолчанию — lisp-interaction-mode.

Переменная: interpreter-mode-alist

Эта переменная задаёт основные режимы для скриптов, в строке ‘#!’ которых указан интерпретатор команд. Её значение — alist со значениями вида (regexp . mode); это означает, что следует использовать режим mode, если в файле указан интерпретатор, соответствующий \\`regexp\\'. Например, один из элементов по умолчанию — ("python[0-9.]*" . python-mode).

Переменная: magic-mode-alist

Значение этой переменной — alist со значениями вида (regexp . function), где regexp — регулярное выражение, а function — функция или nil. После открытия файла set-auto-mode вызывает function, если текст в начале буфера соответствует regexp, а function отлично от nil; если function равно nil, режим выбирает auto-mode-alist.

Переменная: magic-fallback-mode-alist

Работает так же, как magic-mode-alist, за исключением того, что используется только в том случае, если auto-mode-alist не задаёт режим для этого файла.

Переменная: auto-mode-alist

Эта переменная содержит ассоциативный список шаблонов имён файлов (регулярных выражений) и соответствующих команд основных режимов. Обычно шаблоны имён файлов проверяют суффиксы, такие как ‘.el’ и ‘.c’, но это необязательно. Обычный элемент списка выглядит так: (regexp . mode-function).

Например,

(("\\`/tmp/fol/" . text-mode)
 ("\\.texinfo\\'" . texinfo-mode)
 ("\\.texi\\'" . texinfo-mode)
 ("\\.el\\'" . emacs-lisp-mode)
 ("\\.c\\'" . c-mode)
 ("\\.h\\'" . c-mode)
 ...)

Когда вы открываете файл, полное имя которого (см. раздел Функции раскрытия имён файлов), после удаления номеров версий и суффиксов резервных копий с помощью file-name-sans-versions (см. раздел Компоненты имени файла), соответствует regexp, set-auto-mode вызывает соответствующую mode-function. Благодаря этому Emacs может выбирать подходящий основной режим для большинства файлов.

Если элемент auto-mode-alist имеет вид (regexp function t), после вызова function Emacs снова просматривает auto-mode-alist, проверяя часть имени файла, которая ранее не соответствовала шаблону. Эта возможность полезна для пакетов распаковки: запись вида ("\\.gz\\'" function t) может распаковать файл, а затем установить для распакованного файла подходящий режим на основе имени без ‘.gz’.

Если в auto-mode-alist есть несколько элементов, чьи regexp соответствуют имени файла, Emacs использует первое совпадение.

Ниже приведён пример добавления нескольких пар шаблонов в начало auto-mode-alist. (Такое выражение можно поместить в файл инициализации.)

(setq auto-mode-alist
  (append
   ;; File name (within directory) starts with a dot.
   '(("/\\.[^/]*\\'" . fundamental-mode)
     ;; File name has no dot.
     ("/[^\\./]*\\'" . fundamental-mode)
     ;; File name ends in ‘.C’.
     ("\\.C\\'" . c++-mode))
   auto-mode-alist))
Переменная: major-mode-remap-defaults

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

Например, сторонний пакет, предоставляющий значительно улучшенный основной режим Pascal, может использовать следующий код, чтобы сообщить normal-mode, что для всех файлов, которые обычно обрабатываются с помощью pascal-mode, следует использовать spiffy-pascal-mode:

(add-to-list 'major-mode-remap-defaults '(pascal-mode . spiffy-pascal-mode))

Эта переменная имеет тот же формат, что и major-mode-remap-alist. Если обе переменные содержат соответствие для основного режима, приоритет имеет запись в major-mode-remap-alist.

Функция: major-mode-remap mode

Эта функция возвращает основной режим, который следует использовать вместо mode согласно major-mode-remap-alist и major-mode-remap-defaults. Если эти переменные не переназначают режим, функция возвращает mode.

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

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/Auto-Major-Mode.html

Spec-Zone.ru

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