オートロード機能を使用すると、関数やマクロの存在を登録しつつ、それを定義するファイルの読み込みを後回しにすることができます。関数が最初に呼び出されると、適切なライブラリが自動的に読み込まれて実際の定義やその他の関連コードが組み込まれ、その後、あたかも最初から読み込まれていたかのように実際の定義が実行されます。また、関数やマクロのドキュメントを参照した場合(ドキュメントの基本を参照)や、変数名・関数名の補完が行われた場合(後述のプレフィックスによるオートロードを参照)にも、オートロードがトリガーされることがあります。
オートロード関数を設定する方法は2通りあります。autoloadを呼び出す方法と、実際の定義の前にソース内に「マジック」コメントを記述する方法です。autoloadはオートロード用の低レベルプリミティブであり、あらゆるLispプログラムがいつでもautoloadを呼び出すことができます。Emacsと共にインストールされるパッケージの場合、マジックコメントは関数をオートロードさせる最も便利な方法です。これらのコメント自体は何も行いませんが、autoloadへの呼び出しを構築し、Emacsのビルド時に実行されるよう手配するコマンドloaddefs-generateのガイドとして機能します。
この関数は、filenameから自動的に読み込まれるよう、functionという名前の関数(またはマクロ)を定義します。文字列filenameは、functionの実際の定義を取得するために読み込むファイルを指定します。
filename にディレクトリ名、あるいは接尾辞 .el または .elc
のいずれも含まれていない場合、この関数は必ずこれらの接尾辞のいずれかを追加し、接尾辞が付加されていない単なる filename という名前のファイルからは読み込みを行いません。(変数 load-suffixes で、厳密に必要となる接尾辞を指定します。)
引数 docstring は関数のドキュメント文字列です。autoload
の呼び出し時にドキュメント文字列を指定することで、関数の実際の定義をロードすることなくドキュメントを参照できるようになります。通常、これは関数定義自体のドキュメント文字列と同一である必要があります。一致しない場合は、関数定義のドキュメント文字列がロード時に適用されます。
interactive が nil
でない場合、function をインタラクティブに呼び出せることを意味します。これにより、function の実際の定義を読み込むことなく、M-x
での補完が機能します。完全なインタラクティブ仕様はここに記載されていません。ユーザーが実際に function を呼び出さない限り必要はなく、そのタイミングで実際の定義を読み込むことになります。
interactive がリストの場合、このコマンドが適用可能なモードのリストとして解釈されます。
通常の関数だけでなく、マクロやキーマップもオートロードできます。function
が実際にはマクロである場合は、type を macro
として指定してください。function が実際にはキーマップである場合は、type を keymap として指定してください。Emacs
のさまざまな箇所では、実際の定義をロードすることなくこの情報を知る必要があります。
オートロードされるキーマップは、プレフィックスキーのバインドがシンボル function
である場合、キールックアップ時に自動的にロードされます。その他の方法でキーマップにアクセスした場合には、オートロードは行われません。特に、Lispプログラムが変数の値からキーマップを取得して
keymap-set を呼び出した場合には発生せず、たとえ変数名が同じシンボル function であっても同様です。
function
に、すでにオートロードオブジェクトではない非void関数定義が存在する場合、この関数は何も行わず、nil を返します。そうでない場合は、オートロードオブジェクト(オートロード型を参照)を生成し、それを function の関数定義として格納します。オートロードオブジェクトは以下の形式となります:
(autoload filename docstring interactive type)
例えば、
(symbol-function 'run-prolog)
⇒ (autoload "prolog" 169681 t nil)
この場合、"prolog"は読み込むファイル名、169681はemacs/etc/DOCファイル内のドキュメント文字列(ドキュメントの基本を参照)を指し、tは関数がインタラクティブであることを、nilはマクロやキーマップではないことをそれぞれ示しています。
この関数は、object がオートロードオブジェクトである場合に non-nil を返します。例えば、run-prolog
がオートロード関数として定義されているかを確認するには、以下を評価します。
(autoloadp (symbol-function 'run-prolog))
オートロードされるファイルには通常、他の定義が含まれており、1つ以上の機能を必要としたり、あるいは提供したりすることがあります。ファイルが完全にロードされなかった場合(内容の評価時にエラーが発生した場合など)、ロード中に発生した関数定義や
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 expand
を参照してください。
以下のフォームは特別に処理されます:
defun と defmacro、また
cl-defun と cl-defmacro(Common Lisp
Extensions の 引数リスト
を参照)、および 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(AutotypingのAutotypingを参照)、transient-define-prefix, transient-define-suffix, transient-define-infix, transient-define-argument, および transient-define-group(Transient User
and Developer Manualの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
の値に含まれる制御文字はエスケープ処理され、行長を抑えるために doc string
のダブルクォートの直後にバックスラッシュと改行を挿入しています。ドキュメント文字列の usage 部分にある ‘(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
ファイルのロードを含む特殊なロード機構を使用するパッケージは、オートロード生成時にこれらのファイルがまだ存在しない可能性があるため、ロードエラーを適切に処理する必要があります。これは、例えば
require の no-error 引数を
non-nil に設定することで実現できます(Features を参照)。
あるいは、展開の代わりに、次のように記述することで、目的の autoload 呼び出しを loaddefs.el に組み込むこともできます。
;;;###autoload (autoload 'foo "myfile") (mydefunmacro foo ...)
デフォルト以外の文字列をオートロードクッキーとして使用し、対応するオートロード呼び出しを、デフォルトの loaddefs.el とは異なる名前のファイルに書き込むことができます。Emacsでは、これを制御するための2つの変数が用意されています:
この定数の値は、オートロードクッキーにマッチする正規表現です。loaddefs-generate
は、クッキーに続く Lisp フォームを、生成されるオートロードファイルにコピーします。これにより、‘;;;###autoload’ や ‘;;;###calc-autoload’ といったコメントにマッチします。
この変数の値は、autoload の呼び出しを記述する Emacs Lisp ファイルを指定します。デフォルト値は loaddefs.el ですが、例えば .el ファイルのローカル変数セクションなどでこれを上書きできます(ファイルローカル変数 を参照)。autoload ファイルには、フォームフィード文字で始まるトレーラーが含まれているものとみなされます。
以下の関数を使用すると、オートロードオブジェクトで指定されたライブラリを明示的にロードできます。
この関数は、オートロードオブジェクトであるはずの autoload
で指定されたロードを実行します。オプション引数 name が nil でない場合、その関数値が autoload
であるシンボルである必要があります。その場合、この関数の戻り値はそのシンボルの新しい関数値となります。オプション引数 macro-only の値が macro
である場合、この関数は関数のロードを行わず、マクロのみをロードします。