Автозагрузка
Средство автозагрузки позволяет зарегистрировать наличие функции или макроса, отложив загрузку файла, в котором они определены. При первом вызове функции автоматически загружается нужная библиотека, чтобы установить настоящее определение и другой связанный код, после чего выполняется настоящее определение так, как если бы оно было загружено с самого начала. Автозагрузка также может запускаться при просмотре документации функции или макроса (см. Основы документации) и при завершении ввода имён переменных и функций (см. раздел Автозагрузка по префиксу ниже).
Автозагружаемую функцию можно настроить двумя способами: вызвав autoload или добавив в исходный код перед настоящим определением «магический» комментарий. autoload — низкоуровневая примитивная функция для автозагрузки; любая программа на Lisp может вызвать autoload в любой момент. Магические комментарии — самый удобный способ настроить автозагрузку функции для пакетов, устанавливаемых вместе с Emacs. Сами по себе эти комментарии ничего не делают, но служат указанием для команды loaddefs-generate, которая формирует вызовы autoload и настраивает их выполнение при сборке Emacs.
- Функция: autoload function filename &optional docstring interactive type
-
Эта функция определяет функцию (или макрос) с именем function так, чтобы она автоматически загружалась из filename. Строка filename указывает файл, который нужно загрузить, чтобы получить настоящее определение function.
Если filename не содержит ни имени каталога, ни суффикса
.elили.elc, эта функция настаивает на добавлении одного из этих суффиксов и не загружает файл, имя которого совпадает с filename без добавленного суффикса. (Точная последовательность обязательных суффиксов задаётся переменнойload-suffixes.)Аргумент docstring — строка документации функции. Указание строки документации в вызове
autoloadпозволяет просматривать документацию, не загружая настоящее определение функции. Обычно эта строка должна совпадать со строкой документации в самом определении функции. Если строки различаются, после загрузки начинает действовать строка документации из определения функции.Если interactive не равен
nil, это означает, что function можно вызвать интерактивно. Благодаря этому работает автодополнение в M-x, даже если настоящее определение function ещё не загружено. Полная спецификация интерактивного вызова здесь не приводится: она не нужна, пока пользователь действительно не вызовет function, а в этот момент уже пора загрузить настоящее определение.Если interactive — список, он интерпретируется как список режимов, в которых применима эта команда.
Можно настроить автозагрузку макросов и карт клавиш, а также обычных функций. Укажите
macroв качестве type, если function на самом деле является макросом. Укажитеkeymapв качестве type, если function на самом деле является картой клавиш. Различным компонентам Emacs нужна эта информация, и получить её необходимо без загрузки настоящего определения.Автозагружаемая карта клавиш загружается автоматически при поиске клавиши, если привязкой клавиши-префикса служит символ function. При других способах обращения к карте клавиш автозагрузка не происходит. В частности, она не происходит, когда программа на Lisp получает карту клавиш из значения переменной и вызывает
keymap-set; даже если имя переменной совпадает с символом function.Если у function уже есть непустое определение функции, не являющееся объектом автозагрузки, эта функция ничего не делает и возвращает
nil. В противном случае она создаёт объект автозагрузки (см. Тип автозагрузки) и сохраняет его в качестве определения функции для function. Объект автозагрузки имеет следующий вид:(autoload filename docstring interactive type)
Например:
(symbol-function 'run-prolog) ⇒ (autoload "prolog" 169681 t nil)В этом случае
"prolog"— имя загружаемого файла, 169681 указывает на строку документации в файле emacs/etc/DOC (см. Основы документации),tозначает, что функция интерактивна, аnil— что она не является макросом или картой клавиш.
- Функция: autoloadp object
-
Эта функция возвращает значение, отличное от
nil, если object — объект автозагрузки. Например, чтобы проверить, определён лиrun-prologкак автозагружаемая функция, выполните(autoloadp (symbol-function 'run-prolog))
Автозагружаемый файл обычно содержит и другие определения, а также может требовать или предоставлять одну или несколько возможностей. Если файл загружен не полностью (из-за ошибки при вычислении его содержимого), все определения функций и вызовы provide, произошедшие во время загрузки, отменяются. Это гарантирует, что при следующей попытке вызвать функцию, автозагружаемую из этого файла, будет предпринята новая попытка загрузить файл. Иначе некоторые функции из файла могли бы быть определены при прерванной загрузке, но не работать должным образом из-за отсутствия подпрограмм, которые не удалось загрузить, поскольку они находились в файле позднее.
Если автозагружаемый файл не определяет нужную функцию или макрос Lisp, выдаётся ошибка с данными "Autoloading failed to
define function function-name".
Магический комментарий автозагрузки (часто называемый маркером автозагрузки) состоит из ‘;;;###autoload’ на отдельной строке непосредственно перед настоящим определением функции в её исходном файле, предназначенном для автозагрузки. Функция loaddefs-generate записывает соответствующий вызов autoload в loaddefs.el. (Строку, используемую в качестве маркера автозагрузки, и имя файла, создаваемого командой loaddefs-generate, можно изменить по сравнению со значениями по умолчанию; см. ниже.) При сборке Emacs загружается loaddefs.el, и поэтому вызывается autoload.
Тот же магический комментарий позволяет копировать в loaddefs.el формы любого типа. Форма, следующая за магическим комментарием, копируется без изменений, если только средство автозагрузки не обрабатывает её особым образом: напрямую преобразуя в вызов autoload или рекурсивно раскрывая макрос. Любой макрос может запросить раскрытие вызывающих его автозагрузок во время генерации; см. Раскрытие autoload-macro.
Особым образом обрабатываются следующие формы:
- Определения функций и объектов, подобных функциям:
-
defunиdefmacro; а такжеcl-defunиcl-defmacro(см. Списки аргументов в Расширениях Common Lisp) иdefine-overloadable-function(см. комментарий в mode-local.el). - Определения основных и второстепенных режимов:
-
define-minor-mode,define-globalized-minor-mode,define-generic-mode,define-derived-modeиdefine-compilation-mode. - Другие типы определений:
defcustom,defgroup,deftheme,defclass(см. EIEIO в EIEIO),define-skeleton(см. Автоматический ввод в Автоматическом вводе),transient-define-prefix,transient-define-suffix,transient-define-infix,transient-define-argumentиtransient-define-group(см. Transient в Руководстве пользователя и разработчика Transient).
Магический комментарий также можно использовать для выполнения формы во время сборки, не выполняя её при загрузке самого файла. Для этого запишите форму на той же строке, что и магический комментарий. Поскольку форма находится в комментарии, при загрузке исходного файла она ничего не делает; однако loaddefs-generate копирует её в loaddefs.el, где она выполняется во время сборки Emacs.
В следующем примере показано, как doctor подготавливается к автозагрузке с помощью магического комментария:
;;;###autoload (defun doctor () "Switch to *doctor* buffer and start giving psychotherapy." (interactive) (switch-to-buffer "*doctor*") (doctor-mode))
Вот что в результате появляется в loaddefs.el:
(autoload 'doctor "doctor" "\ Switch to *doctor* buffer and start giving psychotherapy. \(fn)" t nil)
Хотя файл loaddefs.el не предназначен для редактирования, мы стараемся сделать его достаточно удобным для чтения. Например, управляющие символы в значениях defvar экранируются, а сразу после кавычки, открывающей строку документации, вставляются обратная косая черта и символ новой строки, чтобы ограничить длину строки. ‘(fn)’ в части документации, описывающей использование, заменяется именем функции при отображении этой документации различными справочными функциями (см. Справочные функции).
Если для определения функции используется необычный макрос, не относящийся к известным и распознаваемым способам определения функций, обычный магический комментарий автозагрузки с вызовом макроса потребует загрузки самого определения макроса. При этом всё определение макроса копируется в файл автозагрузки. Если этого не требуется, вместо автозагрузки макроса можно использовать специальную форму объявления (autoload-macro expand) в его определении (см. Форма declare). Она указывает системе автозагрузки раскрывать вызовы вашего макроса, следующие за ‘;;;###autoload’, как это делается для перечисленных выше специальных функций. Например, макрос-обёртка для define-minor-mode может запросить раскрытие, чтобы для определяемой им функции были созданы правильные вызовы autoload.
Символ-ключевое слово :autoload-end можно использовать при раскрытии макроса, чтобы не включать в вывод автозагрузки ненужные формы. Его наличие приводит к тому, что все последующие элементы формы, в которой он встречается, без предупреждения пропускаются. Например, если во время генерации автозагрузки раскрытие макроса включает:
(progn (put my-mode 'visible-prop t) :autoload-end (put my-mode 'hidden-prop nil))
то заключительная форма ((put my-mode 'hidden-prop nil)) не будет скопирована в файл автозагрузки.
Обратите внимание: если во время генерации автозагрузки обнаружится, что символ в car автозагружаемой формы не определён, будет загружен сам файл, в котором находится соответствующий комментарий ‘;;;###autoload’, чтобы дать макросу возможность определиться. Поэтому пакеты, использующие специальные механизмы загрузки, включая загрузку собственного файла package-loaddefs.el, должны корректно обрабатывать ошибки загрузки, поскольку во время генерации автозагрузки эти файлы могут ещё не существовать. Это можно сделать, например, задав аргумент no-error функции require как значение, отличное от nil (см. Возможности).
Вместо раскрытия можно также поместить нужный вызов autoload в loaddefs.el, записав следующее:
;;;###autoload (autoload 'foo "myfile") (mydefunmacro foo ...)
Можно использовать строку, отличную от строки маркера автозагрузки по умолчанию, и записывать соответствующие вызовы автозагрузки в файл с именем, отличным от стандартного loaddefs.el. Для этого в Emacs предусмотрены две переменные:
- Переменная: lisp-mode-autoload-regexp
Значение этой константы — регулярное выражение, соответствующее маркерам автозагрузки.
loaddefs-generateкопирует следующую за маркером форму Lisp в создаваемый файл автозагрузки. Выражение соответствует таким комментариям, как ‘;;;###autoload’ и ‘;;;###calc-autoload’.
- Переменная: generated-autoload-file
Значение этой переменной задаёт файл Emacs Lisp, в который следует поместить вызовы автозагрузки. По умолчанию это loaddefs.el, но значение можно переопределить, например, в разделе локальных переменных файла .el (см. Локальные переменные файла). Предполагается, что в конце файла автозагрузки находится завершающая часть, начинающаяся с символа перевода страницы.
Следующую функцию можно использовать для явной загрузки библиотеки, указанной объектом автозагрузки:
- Функция: autoload-do-load autoload &optional name macro-only
Эта функция выполняет загрузку, заданную объектом autoload, который должен быть объектом автозагрузки. Необязательный аргумент name, если он не равен
nil, должен быть символом, значением функции которого является autoload; в этом случае функция возвращает новое значение функции этого символа. Если значение необязательного аргумента macro-only равноmacro, функция не загружает функцию, а загружает только макрос.
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/Autoload.html