Skip to content

el-init の機能紹介

2013/01/01

前回は el-init の紹介を兼ねて簡単な使い方の説明だけでした。

今回は el-init の機能やオプションなどについて紹介したいと思います。

変数

まずは、主要な変数についてです。

el-init:load-file-regexp

el-init でロードの対象になるファイルの正規表現です。
デフォルトでは

"\\.elc?$"

になっていて、バイトコンパイルされたものを含む
emacs lisp ファイルにマッチするようになっています。

もし、el-init でロードする対象ファイルを絞りたいのであれば
この変数の値を変更すると良いでしょう。

el-init:load-directory-list

el-init でロード対象となるファイルを探索するディレクトリのリストです。
el-init:load でロードするディレクトリのサブディレクトリとして表現します。
リストの先頭にあるサブディレクトリにある設定ファイルから順にロードされます。

リストの要素はサブディレクトリ名の文字列です。
サブディレクトリ下も再帰的に探索したい場合は
先頭にサブディレクトリ名、
二番目の要素を t としたリストとして記述します。

例えば、

  • base
  • init
  • lang (再帰的に探索)

↑のサブディレクトリを指定したい場合は

("base" "init" ("lang" t))

とします。

実際には次のようなコードになるでしょう。

(setq el-init:load-directory-list '("base" "init" ("lang" t)))

el-init:load-function-compile

el-init でロードに使用する無名関数をバイトコンパイルするかどうかを制御します。
non-nil であればバイトコンパイルをし、それをロードに使用します。
バイトコンパイルする目的は無名関数の動作速度を向上させることのみです。

この無名関数は、
require のラップで説明するラッパー関数をひとまとまりにしたもので
el-init:load-function-list に多くの関数を指定している人は、
多少ロードにかかる時間が短縮されるかもしれません。

el-init:before-load-hook

el-init:load で設定ファイルがロードされる前に実行されるフックです。
あまり使われることはないかもしれません。

el-init:after-load-hook

el-init:load で設定ファイルをロードし終えた時に実行されるフックです。
ロードに失敗しても実行されます。
これもあまり使われることはないでしょう。

el-init:record

el-init でロード結果などの情報を格納する変数です。
現在は require 関数で指定するシンボルと、
そのファイルに関する情報を格納した plist との alist になっています。

言葉で示すより例を示したほうがわかりやすいかもしれないので、
例を示します。

((init-org-mode :error "Error Message"))

el-init のデフォルトではロード中にエラーがあった場合にのみ
エラーの内容が記録されるようになっているので、大抵は nil になっていると思います。

この変数へのアクセスには
今後のバージョンアップも考慮して専用の関数を用いると良いでしょう。

レコードの取得 el-init:get-record

レコードの取得には el-init:get-record を使用します。

(el-init:get-record SYMBOL &optional PROPERTY)
  • SYMBOL
    ファイル名のシンボルを指定します。
  • PROPERTY
    取得したい項目を指定します。
    オプショナル引数になっていて、何も指定がない場合は plist 全体が返されます。

例:

(el-init:get-record 'init-org-mode)
;; => (:error "Error Message")
(el-init:get-record 'init-org-mode :error)
;; => "Error Message"

ちなみに、el-init:get-record は setf 可能です。
setf を使いたい人はぜひどうぞ。

レコードの追加 el-init:add-record

レコードの追加には el-init:add-record を使用します。

(el-init:add-record SYMBOL PROPERTY VALUE)
  • SYMBOL
    ファイル名のシンボルを指定します。
  • PROPERTY
    追加する項目を示すシンボルを指定します。
  • VALUE
    項目の値を指定します。

例:

(el-init:add-record 'init-anything :loadtime 0.1)

el-init:load-function-list

el-init でロードに使用する require 関数のラッパー関数のリストです。
デフォルトではエラーを記録するための
el-init:require/record-error だけが設定されています。
詳しくは require のラップを参照してください。

require のラップ

el-init では、設定ファイルのロードに require 関数を使用すると言って来ましたが、
実は使用されるのは素の require 関数ではありません。
el-init:load-function-list に指定された複数のラッパー関数によってラップされた
require 関数がロードに使用されます。

ラッパー関数は around アドバイスや CLOS の around メソッドのようなものです。
el-init:load-function-list の先頭から順に呼び出されます。

ラッパー関数の定義

ラッパー関数を定義するには el-init:define-require マクロを使用します。

(el-init:define-require NAME &rest BODY)
  • NAME
    ラッパー関数の名前を指定します。
  • BODY
    ラッパー関数で行う処理を記述します。

el-init:define-require の BODY 部では、
暗に変数 feature, filename, noerror が導入されます。
これは require 関数の引数に対応するものです。

  • 実際は el-init:define-require マクロが defun 式に展開された時の引数です。
    気になる人は el-init:define-require の定義を見るか、macroexpand してみましょう。
    el-init:define-require は el-init-require.el に定義されています。

BODY 部の中で el-init:next 関数を呼ぶことによって
require 関数を含めた残りのラッパー関数を呼び出します。
従って、ラッパー関数内で直接 require 関数を呼ぶことはしません。

el-init:next 関数の引数は下記の通りです。
それぞれ require 関数の引数と対応しています。

(el-init:next &optional FEATURE FILENAME NOERROR)

引数を何も指定しなければ、呼び出し元のラッパー関数と同じ引数が使用されます。
CLOS の call-next-method とだいたい同じです。
引数の値を変えたい場合は、el-init:next 関数を引数付きで呼び出します。

;; noerror を t に
(el-init:next feature filename t)

せっかくなので、el-init:require/record-error の定義を見てみましょう。

el-init:require/record-error の目的は
ロード中に発生したエラーを el-init:record に記録することです。
副次的な効果として、ロード中にエラーが発生しても
他のファイルのロードは行われるようになります。

(el-init:define-require el-init:require/record-error
  (condition-case e
      (el-init:next)
    (error (el-init:add-record feature
                               :error
                               (error-message-string e)))))

condition-case でロード処理(el-init:next の呼び出し)を覆いエラーを捕まえています。
エラーが発生した場合は el-init:add-record を使って
レコードにエラーメッセージを記録します。
この時に、暗に導入された変数 feature を利用しています。

他のラッパー関数の紹介

el-init には el-init:require/record-error 以外にも
あらかじめ用意されたラッパー関数があります。
簡単にですが紹介したいと思います。
ラッパー関数は el-init-require-definitions.el に定義されているので、
気になる人はファイルを覗いてみると良いでしょう。

el-init:require/benchmark

各ファイルのロードにかかった時間、GCの回数、GCにかかった時間を記録します。
設定ファイルから設定ファイルをロードするケースは未対応なので、
現状では重複してカウントされてしまいます。

el-init:require/ignore-errors

その名の通り ignore-errors でラップします。
ロード中のエラーを無視します。
記録も何もしません。

el-init:require/system-case

init-loader の emacs の種類によってロードする設定ファイルを切替える機能の el-init 版です。
emacs の種類以外に、OS ごとの分岐も可能です。
el-init:next をわざと呼び出さないようにしてロードする設定ファイルを選んでいます。

el-init:load

el-init:load 関数の引数についても一応紹介しておきます。

(el-init:load DIRECTORY &key DIRECTORY-LIST FUNCTION-LIST COMPILE OVERRIDE)
  • DIRECTORY
    読み込み対象のディレクトリ
  • DIRECTORY-LIST, FUNCTION-LIST, COMPILE
    それぞれ指定がなければ
    el-init:load-directory-list, el-init:load-function-list, el-init:load-function-compile
    の値が使用されます。
    主にテストなどを書く場合を想定して用意したもので、
    init.el などで使うことはおすすめしません。
  • OVERRIDE
    non-nil な場合、require 関数を el-init のロードで使用する関数で一時的に置き換えます。
    ライブラリのロードなどにもラッパー関数を通したい時に使用します。
    ほとんど使うことはないかもしれません。

最後に

これで el-init の機能紹介は終わりです。
なんとなくわかってもらえたでしょうか。
el-init は、なるべくユーザが自由に機能をいじれるよう
意識して作りました(ラッパー関数のあたりなど)。
アイデアが浮かんだなら、ぜひラッパー関数を自作してみてください。
個人的には、古い elc ファイルを避けてロードしたり、
バイトコンパイルを試みるようなラッパー関数があってもいいかなと思っています。

el-init:load-function-list の tips として、
ラッパー関数の性質上、
el-init:require/system-case のような
ロードするかどうかを決めるものはリストの先頭の方に、
el-init:require/record-error のような
エラー抑制系のものはリストの末尾の方に置くといいと思います。

では。

広告

From → Emacs

コメントする

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。