При байт-компиляции файла часто появляются предупреждения о функциях, о которых компилятор не знает (см. Ошибки компилятора). Иногда это указывает на реальную проблему, но обычно функции, о которых идет речь, определены в других файлах, которые будут загружены, если этот код будет выполнен. Например, байт-компиляция simple.el раньше выдавала предупреждение:
simple.el:8727:1:Warning: the function ‘shell-mode’ is not known to be
defined.
Фактически, shell-mode используется только в функции, которая выполняет
(require 'shell) перед вызовом shell-mode, поэтому
shell-mode будет правильно определена во время выполнения. Когда вы знаете,
что такое предупреждение не указывает на реальную проблему, полезно подавить это
предупреждение. Это делает новые предупреждения, которые могут означать реальные
проблемы, более заметными. Вы делаете это с помощью declare-function.
Вам нужно просто добавить оператор declare-function перед
первым использованием рассматриваемой функции:
(declare-function shell-mode "shell" ())
Это говорит о том, что shell-mode определена в shell.el
(можно опустить «.el»). Компилятор предполагает, что этот файл действительно
определяет функцию, и не проверяет это.
Необязательный третий аргумент указывает список аргументов shell-mode.
В данном случае он не принимает аргументов (nil отличается от
неуказания значения). В других случаях это может быть что-то вроде (file &optional overwrite).
Вам не нужно указывать список аргументов, но если вы это делаете, компилятор может
проверить, соответствуют ли вызовы объявлению.
Сообщает байт-компилятору предположить, что function определена в
файле file. Необязательный третий аргумент arglist
либо t, что означает, что список аргументов не указан, либо список
формальных параметров в том же стиле, что и defun (включая
скобки). Пропущенный arglist по умолчанию равен t, а не
nil; это нетипичное поведение для пропущенных аргументов, и это означает,
что, чтобы предоставить четвертый, но не третий аргумент, необходимо указать t
в качестве заполнителя третьего аргумента, а не обычное nil. Необязательный
четвертый аргумент fileonly не-nil означает проверку только
наличия file, а не того, что он действительно определяет function.
Чтобы убедиться, что эти функции действительно объявлены там, где
declare-function говорит, используйте check-declare-file
для проверки всех вызовов declare-function в одном исходном файле или
используйте check-declare-directory для проверки всех файлов в определенном
каталоге и подкаталогах.
Эти команды находят файл, который должен содержать определение функции, используя
locate-library; если он не находит файл, они расширяют имя файла
определения относительно каталога файла, содержащего вызов declare-function.
Вы также можете указать, что функция является примитивной, указав имя файла, оканчивающееся на «.c» или «.m». Это полезно только тогда, когда вы вызываете примитив, определенный только в определенных системах. Большинство примитивов всегда определены, поэтому они никогда не вызовут предупреждения.
Иногда файл может опционально использовать функции из внешнего пакета.
Если вы префиксерте имя файла в операторе declare-function
«ext:», то будет проверено, найден ли он, в противном случае он будет
пропущен без ошибки.
Существуют некоторые определения функций, которые check-declare не
понимает (например, defstruct и некоторые другие макросы). В таких
случаях вы можете передать не-nil аргумент fileonly в
declare-function, что означает проверку только наличия файла, а не того,
что он действительно определяет функцию. Обратите внимание, что, чтобы сделать это без
необходимости указывать список аргументов, вы должны установить аргумент arglist
в t (потому что nil означает пустой список аргументов, в
отличие от неуказанного).