« ^ »

custom-set-variablesを上手く扱うにはどうすれば良いんだろう?

所要時間: 約 5分

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-keydefcustom で定義しない方が望ましい。仮に 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を使って暗号化し、別の機構により読み込むようにしている。今はそのようにしているけれど、もっと良い方法や正しい方法があるのかもしれない。また機会を見つけて管理方法を見直していきたい。