Debian Linux 上で GNU Emacs 27.2.50を使っています。 現状の emacs-init-time
は、0.6秒前後で何ら不満はないのですが、さらなる起動時間の短縮にこだわって日々試行錯誤しているEmacs馬鹿です。
設定ファイルを leaf
に移行し、且つafter-init-hook
を多用することでかなり短縮できました。で、最後にたどり着いたのが設定ファイルの全てを自動バイトコンパイルさせるという課題です。
auto-async-byte-compile.el を試す
Web検索でよく見つかるTipsは、下記のパッケージを使ったものが多かったので私も試してみました。
(require 'auto-async-byte-compile)
(setq auto-async-byte-compile-exclude-files-regexp "/junk/")
(add-hook 'emacs-lisp-mode-hook 'enable-auto-async-byte-compile-mode)
確かに便利なのですがいくつかの問題に遭遇しました。
一つは、設定ファイルの実行には特に支障のない警告レベルのコンパイルエラーでも Warningバッファーが表示されてコンパイルの実行が中止されてしまうことです。もちろん致命的な syntaxエラーは修正が必要ですが、警告レベルのバグを全て潰すのはきりがないので無視してほしいです。
下記Tipsにあるコマンドラインからも試しましたが、同様に警告がでて実行できませんでした。
leaf.el
で書いた私の設定ファイルが不完全なのかも知れないのですが、なんとか警告レベルは無視してくれる方法はないかと模索しました。
標準コマンドで対応できた
思考錯誤の結果、標準コマンドの byte-recompile-directory
が思い通りの仕事をしてくれることが確認できたました。最終的に下記を init.el
に書くことで静かに快適に対応してくれるようになりました。
(defun auto-compile-inits ()
"Byte-compile Lisp files modified in the directory."
(interactive)
(byte-recompile-directory (expand-file-name "~/.emacs.d/elisp") 0)
(byte-recompile-directory (expand-file-name "~/.emacs.d/inits") 0))
(add-hook 'kill-emacs-hook 'auto-compile-inits)
~/.emacs.d/elisp
は、自作スクリプトを置いているデレクトリ、~/.emacs.d/inits
は、init-loader.el
で読み込むための設定ファイル群を置いているデレクトリです。
設定ファイルを削除やリネームしたときの注意と対策
.el ファイルをリネームしても古い名前の .elcファイルは残ったままです。同様に、.el ファイルを削除しても .elc ファイルは残ったままなので、うっかり放置すればそれらのファイルも読み込まれて混乱します。
これを避けるには、recompile する前に全ての .elc を削除するような設定に変えればいいのですが、その分 Emacsの終了や再起動に毎回時間がかかりストレスなので私は採用していません。
(defun auto-compile-inits ()
"Byte-compile Lisp files modified in the directory."
(interactive)
(compile "rm ~/.emacs.d/elisp/*.elc")
(compile "rm ~/.emacs.d/inits/*.elc")
(byte-recompile-directory (expand-file-name "~/.emacs.d/elisp") 0)
(byte-recompile-directory (expand-file-name "~/.emacs.d/inits") 0))
(add-hook 'kill-emacs-hook 'auto-compile-inits)
emacs設定ファイルを複数端末で共有しているときの注意
設定ファイル群を dotfiles として Git管理し、GitHub のリポジトリに置いて複数端末で共有している場合は、ちょっと注意が必要です。
通常 .elc ファイルは Gitの管理下にはおかず .el のみというパターンが多いかと思うので、最新の設定ファイルをサブ機などへ pull しても、古いバージョンの .elc が残っているとそちらが優先的に読み込まれるからです。
その対策として私は early-init.el
に下記の設定を追加しています。
;; Always load newest byte code
(setq load-prefer-newer t)
この設定を追加しておけば、.elc よりも .el のほうが新しいときは、.el のほうを読み込みます。
そののち Emacsを再起動すれば、自動的に新しい .elc が自動生成されます。
起動時間短縮を追求することの意義
私の環境では、Emacs設定ファイル群をバイトコンパイルすることで emacs-init-time
は、0.1secondsくらい短くなりました。たかだかコンマ何秒というごくわずかの起動時間短縮を図るのに何の意義があるのか?と問われたら苦笑するしかありません。たんなる自己満足です。
Emacs28/29の native-compile も試してみましたが、少なくとも起動時間の短縮にはつながらないようなので、もうしばらくEmacs27を使い続けます。