ファイルではローカル変数の値を指定でき、Emacsはこれらを用いて、そのファイルを開いているバッファ内で当該変数のバッファローカルなバインディングを作成します。ファイルローカル変数に関する基本的な情報については、The GNU Emacs ManualのLocal Variables in Filesを参照してください。本節では、ファイルローカル変数の処理方法に影響を与える関数と変数について説明します。
ファイルローカル変数で、後で呼び出される任意の関数やLisp式を指定できるとしたら、ファイルを訪問するだけでEmacsを乗っ取られてしまう可能性があります。Emacsは、指定された値が安全であることが分かっているファイルローカル変数のみを自動的に設定することで、これを防いでいます。その他のファイルローカル変数は、ユーザーが同意した場合にのみ設定されます。
安全性をさらに高めるため、Emacsがファイルローカル変数を読み込む際、read-circleは一時的にnilにバインドされます(入力関数を参照)。これにより、Lispリーダーが循環構造や共有Lisp構造を認識するのを防ぎます(循環オブジェクトの読み込み構文を参照)。
この変数は、ファイルローカル変数を処理するかどうかを制御します。取り得る値は以下の通りです。
t(デフォルト)安全な変数を設定し、安全でない変数について(一度だけ)クエリを実行する。
:safe安全な変数のみを設定し、クエリは行わない。
:allすべての変数を設定し、クエリは行わない。
nil変数を設定しないでください。
すべての変数について(一度だけ)問い合わせる。
これは正規表現の一覧です。ファイルの名前がこの一覧の要素に一致する場合、そのファイルはいかなる形式のファイルローカル変数についてもスキャンされません。これを利用する理由の例については、Emacsがメジャーモードを選択する仕組みを参照してください。
一部のローカル変数設定は、enable-local-variables が nil であってもデフォルトで適用されます。デフォルトでは、これは lexical-binding
のローカル変数設定にのみ適用されますが、シンボルのリストであるこの変数を使用することで制御可能です。
これは、ローカル変数が常に有効になるディレクトリの一覧です。.dir-locals.el
の変数など、これらのディレクトリから読み込まれるディレクトリローカル変数は、リスクがある場合でも有効になります。この一覧に含まれるディレクトリは、完全展開された絶対ファイル名である必要があります。また、変数
enable-remote-dir-locals が nil 以外に設定されている場合は、リモートディレクトリであっても構いません。
この関数は、現在のバッファの内容で指定されたローカル変数を解析し、適宜バインドまたは評価します。ここでは変数 enable-local-variables が機能します。ただし、この関数は -*- 行の中でローカル変数 ‘mode:’ を探しません。それを行うのが set-auto-mode であり、enable-local-variables も考慮に入れます(Emacs がメジャーモードを選択する仕組み を参照してください)。
この関数はまた、.dir-locals.el
で指定されたディレクトリローカル変数を適用します。バッファがいかなるファイルも参照していない場合、適用されるディレクトリローカル変数は、default-directory 内のファイルに適用されるものとなります(ディレクトリローカル変数を参照)。
この関数は、file-local-variables-alist と dir-local-variables-alist
に格納されているalistを走査し、各ローカル変数を順に適用することで動作します。変数の適用前後で、それぞれ before-hack-local-variables-hook と hack-local-variables-hook を呼び出します。before-hook は file-local-variables-alist が nil でない場合にのみ呼び出され、もう一方のフックは常に呼び出されます。この関数は、‘mode’ 要素がバッファの現在のメジャーモードと同じものを指定している場合、それを無視します。
オプション引数 handle-mode が t
の場合、この関数が行うのは、‘-*-’
行またはローカル変数リストでメジャーモードが指定されていればそれを、そうでなければ nil
を指定するシンボルを返すことだけです。モードやその他のファイルローカル変数を設定することはありません。handle-mode が nil または t 以外の値を持つ場合、‘-*-’
行またはローカル変数リストにおける ‘mode’
の設定は無視され、その他の設定が適用されます。handle-mode が nil の場合、すべてのファイルローカル変数が設定されます。
このバッファローカル変数には、ファイルローカル変数の設定のalistが格納されています。alistの各要素は(var . value)という形式をしており、ここでvarはローカル変数のシンボル、valueはその値です。Emacsがファイルを読み込む際、まずすべてのファイルローカル変数をこのalistに収集し、その後hack-local-variables関数がそれらを一つずつ適用します。
Emacsは、file-local-variables-alistに格納されたファイルローカル変数を適用する直前に、このフックを呼び出します。
Emacsは、file-local-variables-alistに格納されたファイルローカル変数の適用を完了した直後に、このフックを呼び出します。
safe-local-variable
プロパティを指定することで、変数に安全な値を設定できます。このプロパティは1つの引数を取る関数である必要があり、その関数が指定された値に対して
nil 以外を返す場合、その値は安全とみなされます。一般的によく見られるファイル変数の多くは
safe-local-variable プロパティを持っており、これには fill-column、fill-prefix、indent-tabs-mode などが含まれます。安全なブール値の変数については、プロパティの値として
booleanp を使用してください。
ファイルの読み込み時に safe-local-variable
の値が参照されるため、この関数は効率的であるべきであり、理想的には安全性を判定するためのライブラリの読み込みを伴わないことが望ましい(例:オートロードされる関数であってはならない)。
C言語のソースコードで定義された変数に対して safe-local-variable
プロパティを定義したい場合は、それらの変数の名前とプロパティを files.el の「Safe
local variables」セクションのリストに追加してください。
defcustom を使用してユーザーオプションを定義する場合、引数 :safe function から defcustom を追加することで、その safe-local-variable プロパティを設定できます(カスタマイズ変数の定義 を参照)。ただし、:safe を使用して定義した安全性述語は、defcustom
を含むパッケージがロードされて初めて判明するため、それでは遅すぎることがよくあります。代替手段として、オートロードクッキー(オートロード
を参照)を使用して、次のようにオプションに安全性述語を割り当てることができます。
;;;###autoload (put 'var 'safe-local-variable 'pred)
autoload で指定された safe value
の定義は、パッケージのオートロードファイル(Emacs に同梱されているほとんどのパッケージでは loaddefs.el)にコピーされ、セッション開始時から Emacs に認識されます。
この変数は、一部の変数の値を安全としてマークするための別の手段を提供します。これはコンスセル (var . val) のリストであり、var は変数名、val はその変数にとって安全な値です。
Emacsがユーザーに一連のファイルローカル変数の指定に従うかどうかを尋ねた際、ユーザーはそれらを「安全」としてマークすることを選択できます。そうすることで、それらの変数と値のペアがsafe-local-variable-valuesに追加され、ユーザーのカスタムファイルに保存されます。
特定のローカル変数の値の中で、常に完全に無視したいものがある場合は、この変数を使用できます。その値は safe-local-variable-values
と同じ形式であり、リストに記載されている値に設定されたファイルローカル変数は、ファイルで指定されたローカル変数を処理する際に常に無視されます。この変数と同様に、Emacs
がファイルローカル変数に従うかどうかをユーザーに問い合わせた際、ユーザーは特定の値を恒久的に無視することを選択でき、これによりこの変数が変更され、ユーザーのカスタムファイルに保存されます。この変数に含まれる変数と値のペアは、safe-local-variable-values にある同一のペアよりも優先されます。
この関数は、上記の基準に基づき、sym に値 val
を与えても安全である場合に non-nil を返します。
一部の変数はリスクありとみなされます。変数がリスクありの場合、safe-local-variable-valuesに自動的に入力されることはありません。ユーザーがsafe-local-variable-valuesを直接カスタマイズして明示的に値を許可しない限り、Emacsはリスクのある変数を設定する前に必ず確認を行います。
名前に nil または risky-local-variable
以外のプロパティを持つ変数は、リスクがあるものとみなされます。defcustom
を使用してユーザーオプションを定義する場合、:risky value から defcustom
までの引数を追加することで、その risky-local-variable
プロパティを設定できます(カスタマイズ変数の定義 を参照)。さらに、名前が ‘-command’、‘-frame-alist’、‘-function’、‘-functions’、‘-hook’、‘-hooks’、‘-form’、‘-forms’、‘-map’、‘-map-alist’、‘-mode-alist’、‘-program’ または ‘-predicate’
のいずれかで終わる変数は、自動的にリスクがあるものとみなされます。また、‘font-lock-keywords’、数字が続く ‘font-lock-keywords’ 、および ‘font-lock-syntactic-keywords’ もリスクがあるものとみなされます。
この関数は、上記の基準に基づき、sym がリスクのある変数である場合に non-nil を返します。
この変数には、ファイルによってローカル値が割り当てられるべきではない変数のリストが格納されています。これらの変数のいずれかに指定された値は、完全に無視されます。
「Eval:」という「変数」も抜け穴となる可能性があるため、Emacsでは通常、処理を行う前に確認を求めます。
この変数は、‘-*-’ 行や参照中のファイル内のローカル変数リストにおける
‘Eval:’ の処理を制御します。値が t の場合は無条件に処理し、nil
の場合は無視し、それ以外の場合は各ファイルについてどう処理するかをユーザーに確認します。デフォルト値は maybe です。
この変数には、ファイルのローカル変数リスト内の「Eval:」という「変数」で見つかった際に、安全に評価できる式のリストが格納されています。
式が関数呼び出しであり、その関数が safe-local-eval-function
プロパティを持つ場合、そのプロパティの値によって式の評価が安全かどうかが決定されます。プロパティの値には、式をテストするために呼び出す述語、そのような述語のリスト(いずれか一つでも成立すれば安全)、または
t(引数が定数であれば常に安全)を指定できます。
テキストプロパティも、その値に呼び出す関数が含まれ得るため、抜け穴となる可能性があります。そのため、Emacsはファイルローカル変数に指定された文字列値から、すべてのテキストプロパティを削除します。