Emacsには custom-set-variables
という関数がある。これはEmacsのカスタマイズ時に使われる。僕は長い間、この機構についてよく分かっていなかった。今もよく分かっているとは言い難いのだけれど、以前よりはマシになったので再考し、今の認識をメモとして残す事にした。
M-x customizeでカスタマイズした値はcustom-set-variablesで設定されるよう初期化ファイルに自動挿入される
Emacsは M-x customize
を実行すると、 defcustom
で定義された値をカスタマイズする事ができる。この機構を使ってEmacsをカスタマイズする事が多いだろう。ここで設定した値は、 custom-set-variables
を使って設定されるよう、 ~.emacs.d/init.el
に自動的に書き込まれる。
custom-set-variables
は、 defcustom
によって定義されたカスタマイズを前提として定義された変数を M-x customize
を用いて変更した際、その変更状態を記録し、次回起動時に、設定が反映されるようにするために用いられる。
M-x customize
を用いて変数を変更すると、変更した値を ~/.emacs.d/init.el
の末尾のあたりに自動的に挿入する。
自動挿入されるファイルを指定する
~/.emacs.d/init.el
は、Emacsが起動する時に読み込まれるファイルであり、通常は手動で記述していく。そのためGit等のバージョン管理システムで管理する事が多いだろう。その手動で作成し、バージョンを管理しているファイルを、自動で更新される事を好まない場合、 custom-file
変数を書き換える事で、自動で書き込まれるファイルを指定する事もできる。
(setq custom-file (expand-file-name "~/.emacs.d/custom.el"))
このように custom-file
変数を指定し、書き込まれるファイルを変更した場合、このファイルは起動時に自動的に読み込まれる事はない。そこで custom-file
を読み込むコードを ~/.emacs.d/init.el
に追加しておく必要がある。
(load-file custom-file)
custom-set-variable
は ~/.emacs.d/init.el
の最後の方に自動で挿入される事を考えると、 (load-file custom-file)
も最後の方に記述した方が良さそうだ。
また、これはとても乱暴な方法だけれど、この自動挿入機能を無効にする事もできる。
(setq-default enable-local-variables :all)
秘密の情報は扱わない方がいい
defcustom
で定義された変数は、 M-x customize
によって変更できる。ただしこれには注意が必要な点がある。例えばあるWebサービスのAPIキーを保持する foo-web-service-api-key
という変数があるとする。これは他人に知られてはいけない秘匿すべき情報だとする。
この前提では foo-web-service-api-key
は defcustom
で定義しない方が望ましい。仮に defcustom
で定義していた場合、 M-x customize
で設定変更したくなるだろう。しかし、それをしてしまうと秘匿すべきAPIキーは .emacs.d/init.el
に自動挿入される事になる。
defvar
で設定するか、もはや setq
で直接関係のないファイルで設定してしまった方がまだマシだ。このような値は、ライブラリ側は defvar
で定義しておくか、グローバルな変数としてシンボルに結び付けず、必要なタイミングで読み出す方が良さそうだ。
custom-set-variablesのコメントは長文に適さない
custom-set-variablesで値が指定されているという事は、その値はカスタマイズした値だ。カスタマイズするという事は、そこには必ず理由がある。設定によっては理由が自明であり、説明の余地はないかもしれない。しかし、多くの設定は、なぜその設定をしたのか、他にどのような選択肢があるのか、その設定についてイケてると思っているのか、それとも妥協して負けた気持ちになったのか等、さまざまなメモを残したくなる。
customize
にはコメント機能がある。小さいコメントであれば、それを残してもよいだろう。しかし、書きたい事は結構な分量ある。それこそ数段落と表ぐらい書きたい。そういった詳しい事を書き記していく事には、よほど適していない。
仮にインラインのコメントとして自動挿入された custom-set-variables
の中にメモを残したとしても、 custom-set-variables
の自動挿入によって消されてしまう。
カスタマイズで設定する値は、以下のような形式の方が都合が良いようにも思えるのだけれど、なぜあのような形式をしているのだろう。
(progn
(setq foo 1)
(setq bar 2)
(setq baz 3))
この形式であれば、1行だけを評価する事で値を反映する事ができる。 setq
はいつでも使うし、一見素人設定のようにも見えるかもしれないけれど、分かりやすさは抜群だろう。このあたりの事情がどうもよく分からない。
結局どう扱えばいいのか
どのようにEmacsを扱いたいかという要求は、人それぞれに異なる。僕の場合はインストールするパッケージは出来ればマシン間で同一であって欲しいためこの値は共有したい。一方で safe-local-variable-values
には .dir-local.el
で設定したシンボルと値がそのまま記録される。この値の中には隠しておきたいような値が含まれていることが多い。例えば秘密のプロジェクト名であったり、公開していないAPIエンドポイントなどだ。設定ファイルはGitHubのリポジトリとしてホスティングしている。そのため、このような値をバージョン管理システムに登録したくない。
僕は、秘匿したい情報はGnuPGを使って暗号化し、別の機構により読み込むようにしている。今はそのようにしているけれど、もっと良い方法や正しい方法があるのかもしれない。また機会を見つけて管理方法を見直していきたい。