Когда Emacs открывает файл, он автоматически выбирает основной режим для буфера на основе информации в имени файла или в самом файле. Он также обрабатывает локальные переменные, указанные в тексте файла.
Эта функция устанавливает подходящий основной режим и привязки буферно-локальных
переменных для текущего буфера. Она вызывает
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,
о синтаксисе раздела локальных переменных файла.
Если вы запускаете normal-mode интерактивно, аргумент
find-file обычно равен nil. В этом случае
normal-mode безусловно обрабатывает любые локальные переменные файла.
Функция вызывает set-auto-mode для выбора и установки основного
режима. Если это не задаёт режим, буфер остаётся в основном
режиме, определяемом значением по умолчанию major-mode
(см. ниже).
normal-mode использует condition-case вокруг вызова команды
основного режима, поэтому ошибки перехватываются и сообщаются как
‘Ошибка спецификации режима файла’, с последующим исходным сообщением
об ошибке.
Эта функция выбирает и устанавливает основной режим, который подходит
для текущего буфера. Она принимает решение (в порядке
приоритета) на основе строки ‘-*-’, любой локальной
переменной ‘mode:’ вблизи конца файла, строки ‘#!’ (используя
interpreter-mode-alist), текста в начале буфера
(используя magic-mode-alist) и, наконец, по имени посещаемого
файла (используя auto-mode-alist). См. Как
выбираются основные режимы в Руководстве GNU Emacs. Если
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, чтобы избежать уничтожения буферно-локальных переменных, которые мог
установить пользователь.
Эта функция устанавливает основной режим buffer в значение по умолчанию
major-mode; если оно равно nil, используется
основной режим текущего буфера (если он подходит). В виде исключения,
если имя buffer равно *scratch*, режим устанавливается в
initial-major-mode.
Низкоуровневые примитивы создания буферов не используют эту функцию,
но команды среднего уровня, такие как switch-to-buffer и
find-file-noselect, используют её при создании буферов.
Значение этой переменной определяет основной режим начального
буфера *scratch*. Значение должно быть символом, являющимся командой
основного режима. Значение по умолчанию — lisp-interaction-mode.
Эта переменная задаёт основные режимы для сценариев, указывающих
интерпретатор команд в строке ‘#!’. Её значение — это список ассоциаций
с элементами вида (regexp . mode); это означает
использовать режим mode, если файл указывает интерпретатор, который
соответствует \\`regexp\\'. Например, один из элементов
по умолчанию — ("python[0-9.]*" . python-mode).
Значение этой переменной — список ассоциаций с элементами вида
(regexp . function), где regexp — это
регулярное выражение, а function — функция или nil.
После посещения файла set-auto-mode вызывает function, если
текст в начале буфера соответствует regexp и
function не равен nil; если function равен nil,
auto-mode-alist определяет режим.
Работает как magic-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 ;; Имя файла (в каталоге) начинается с точки. '(( "/\\.[^/]*\\'" . fundamental-mode) ;; Имя файла не содержит точки. ( "/[^\\./]*\\'" . fundamental-mode) ;; Имя файла оканчивается на ‘.C’. ("\\.C\\'" . c++-mode)) auto-mode-alist))
Эта переменная содержит список ассоциаций, указывающий, какую функцию вызывать для активации данного основного режима. Это используется для форматов файлов, которые могут поддерживаться различными основными режимами, где эта переменная может использоваться для указания, какая альтернатива должна использоваться по умолчанию.
Например, сторонний пакет, предоставляющий значительно улучшенный
основной режим для Pascal, может использовать следующее, чтобы указать normal-mode
использовать spiffy-pascal-mode для всех файлов, для которых обычно используется pascal-mode:
(add-to-list 'major-mode-remap-defaults '(pascal-mode . spiffy-pascal-mode))
Эта переменная имеет тот же формат, что и major-mode-remap-alist.
Если оба списка соответствуют основному режиму, запись в
major-mode-remap-alist имеет преимущество.
Эта функция возвращает основной режим, который следует использовать вместо mode,
в соответствии с major-mode-remap-alist и
major-mode-remap-defaults. Она возвращает mode, если режим
не переназначается этими переменными.
Когда пакет хочет активировать основной режим для определённого формата
файла, он должен использовать эту функцию, передавая в качестве аргумента mode
канонический основной режим для этого формата файла, чтобы узнать, какой конкретный
основной режим активировать, учитывая предпочтения пользователя.