Elispはインタープリター型言語です。バージョン固有のコードをに配置できます.emacs
が、正しいバージョンで動作していることをロード時にテストすることで保護できます。
(if (is-new-feature-available)
(shiny-new-feature)
(old-less-nifty-feature))
がtrueを返す場合に(shiny-new-feature)
のみ評価されるため、このコードはすべてのバージョンで機能し(is-new-feature-available)
ます。この回答の多くは、実装方法に当てられています(is-new-feature-available)
。
さまざまな機能セットへの対応
Emacsのバージョンをテストするよりも、機能が利用可能かどうかをテストすることをお勧めします。この機能はオプションパッケージとして利用できる場合があります。XEmacsまたは他のEmacsバリアントでコードを実行する場合、異なるバージョンで同じ機能を取得している可能性があります。関数boundp
を使用して、変数が使用可能fboundp
かどうかをテストし、関数が使用可能かどうかをテストします。
たとえば、次のスニペットはキーをバインドして、visual-line-mode
利用可能な場合とlonglines-mode
そうでない場合に切り替えます。
(global-set-key "\eml" (if (fboundp 'visual-line-mode)
'visual-line-mode
'longlines-mode))
場合によっては、機能をテストするよりも、小さなコードを実行して、未定義の関数や無効な引数などによるエラーを無視する方が簡単です。大量のコードに対してこれを行わないでください。これにより、コードが非常に複雑になります。デバッグが難しい。
たとえば、ツールバーを表示したくありません。古いバージョンのEmacsにはまったくありませんでした。GNU EmacsとXEmacsはさまざまな方法でその機能を追加し、それをデフォルトにしました。以下に、それらをオフにする方法を示します。このset-specifier
関数はXEmacsにdefault-toolbar-visible-p
固有であり、十分に新しいバージョンのEmacsに固有です。を使用condition-case
すると、両方の要件が処理されます。GNU Emacsは専用の関数を提供するので、その関数が利用可能かどうかをテストするだけです。
;; For XEmacs
(condition-case nil
(set-specifier default-toolbar-visible-p nil)
(error nil))
;; For GNU Emacs
(if (fboundp 'tool-bar-mode)
(tool-bar-mode 0))
一部の顔の名前はバージョンによって異なります。facep
顔の名前の可用性をテストするために使用します。
(let ((face (if (facep 'mode-line) 'mode-line 'modeline)))
(set-face-background face …))
素敵なパッケージが存在する場合はそれをロードし、そのパッケージが利用できない場合は何もしないこともあるでしょう。require
そのためのオプションの引数があります。
(require 'tex-site nil t) ;; Load AUCTeX if available
この引数はGNU Emacs 20.4で導入されたもので、XEmacsでは使用できません。そのため、これより前に戻りたい場合は、ラップするcondition-case
か、load
代わりに使用する必要があります(既にロードされているライブラリをチェックしません)。 。
バージョンの依存関係をユーザーレベルの機能に制限します。サポートするすべてのバージョンで利用できない新しいプログラミング機能を使用しないでください。古いバージョンには互換性のあるバージョンを提供する必要があり、単一のバージョンを維持する方が簡単です。
場合によっては、多くの場所で機能が必要になることがあります。その機能は、気になるすべての実装で利用できますが、方法は異なります。これは、XEmacsとGNU Emacsの両方をサポートする場合にほとんど当てはまります。それらには、お互いの機能をコピーするが、それらのインターフェースはコピーしないという苛立たしい傾向がありました。この場合、互換性関数を定義する方が、使用時にテストするよりも便利です。
たとえば、次のコードは、現在のフレームのウィンドウシステム、最新のGNUの方法、最新のXEmacsの方法、および同じインスタンスで端末フレームとGUIフレームを組み合わせることができなかった古いスタイルの方法を返す関数を定義しています。
(defalias 'compat-window-system
(cond
((fboundp 'window-system) #'window-system)
((fboundp 'device-type)
(lambda (&optional frame)
(device-type (frame-device frame))))
(t
(lambda (&optional frame) window-system))))
環境の依存関係
プラットフォームに依存する必要のあるコードはそれほど多くありません。変数system-type
はオペレーティングシステムを示します。私は排他的にいくつかのハックをアクティブ化するために使用しms-dos
ます(はい、私のファイルはその古いです)とwindows-nt
。
実行可能な検索パス(PATH
)にディレクトリを追加することもできますが、通常は、Emacsの外部.profile
、Unixライクなシステムの場合、Windowsのコントロールパネルを使用するのが最適です。外部プログラムが利用可能かどうかをテストするには、を呼び出しますexecutable-find
。
GUIの種類に応じて異なる動作をする必要があるコードについては、window-type
またはその後続(上記を参照)を確認してください。
初期化ファイル
互換性を最大限にするには、コードをに配置します~/.emacs
。GNU Emacs ~/emacs.d
はバージョン22で調べ始めました。XEmacs ~/.xemacs
はバージョン21.4で調べ始めました。別のアプローチは、互換性コードを~/.emacs
挿入して、メインファイルをロードすることによって終了することです。(setq load-home-init-file t)
XEmacsの最近のバージョンがXEmacs .emacs
のみの場所に移動するかどうかを尋ねるのを避けるためにどこかに置きます。
Emacsのバージョンが異なると、一部のマクロの展開が異なり、互換性がない場合があります。そのため、バージョン間でバイトコンパイルされたファイルを共有せず、各マシンでファイルをコンパイルしてください。
機能が非推奨になることもありますが、サポートしたい他のバージョンにはそれがすべてあるため、それを使用したい場合があります。バイトコンパイラの警告はbyte-obsolete-variable
プロパティから発生します。
(cond
((not (boundp 'desktop-enable))
(defvaralias 'desktop-enable 'desktop-save-mode))
((get 'desktop-enable 'byte-obsolete-variable)
(put 'desktop-enable 'byte-obsolete-variable nil)))
¹ 比較的古いのXEmacsと比べて、話します。
window-system
、エラーからの回復、テストなど)は、ここで合理的に回答できます。