Elisp ist eine interpretierte Sprache. Sie können versionenspezifischen Code in Ihren Code einfügen .emacs
, ihn jedoch schützen, indem Sie beim Laden testen, ob er mit der richtigen Version ausgeführt wird.
(if (is-new-feature-available)
(shiny-new-feature)
(old-less-nifty-feature))
Dieser Code funktioniert in allen Versionen, da er (shiny-new-feature)
nur ausgewertet wird, wenn (is-new-feature-available)
true zurückgegeben wird. Ein Großteil dieser Antwort ist der Implementierung gewidmet (is-new-feature-available)
.
Umgang mit verschiedenen Funktionen
Es ist besser zu testen, ob eine Funktion verfügbar ist, als die Emacs-Version zu testen. Manchmal ist die Funktion als optionales Paket verfügbar. Wenn Sie Code in XEmacs oder einer anderen Emacs-Variante ausführen möchten, wurden möglicherweise dieselben Funktionen in verschiedenen Versionen erworben. Verwenden Sie die Funktion boundp
, um zu testen, ob eine Variable verfügbar ist, und um fboundp
zu testen, ob eine Funktion verfügbar ist.
Das folgende Snippet bindet beispielsweise einen Schlüssel zum Umschalten, visual-line-mode
falls verfügbar, und longlines-mode
ansonsten.
(global-set-key "\eml" (if (fboundp 'visual-line-mode)
'visual-line-mode
'longlines-mode))
Anstatt die Funktion zu testen, ist es manchmal einfacher, einen kleinen Code auszuführen und Fehler aufgrund undefinierter Funktionen, ungültiger Argumente usw. zu ignorieren . Tun Sie dies nicht für große Codemengen, da dies Ihren Code sehr stark macht schwer zu debuggen.
Zum Beispiel möchte ich keine Symbolleiste sehen. Ältere Versionen von Emacs hatten sie überhaupt nicht. GNU Emacs und XEmacs haben diese Funktion auf unterschiedliche Weise hinzugefügt und zur Standardeinstellung gemacht. So schalte ich sie aus. Die set-specifier
Funktion ist spezifisch für XEmacs und default-toolbar-visible-p
spezifisch für ausreichend aktuelle Versionen von Emacs. using condition-case
kümmert sich um beide Anforderungen. GNU Emacs bietet eine spezielle Funktion, daher teste ich lediglich, ob diese Funktion verfügbar ist.
;; 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))
Einige Gesichtsnamen ändern sich über Versionen. Verwenden Sie facep
diese Option , um die Verfügbarkeit eines Gesichtsnamens zu testen.
(let ((face (if (facep 'mode-line) 'mode-line 'modeline)))
(set-face-background face …))
Manchmal möchten Sie vielleicht ein schönes Paket laden, falls vorhanden, und nichts tun, wenn das Paket nicht verfügbar ist. require
hat ein optionales Argument dafür.
(require 'tex-site nil t) ;; Load AUCTeX if available
Dieses Argument wurde in GNU Emacs 20.4 eingeführt und ist in XEmacs nicht verfügbar. Wenn Sie also so weit zurückgehen möchten, müssen Sie es entweder einschließen condition-case
oder load
stattdessen verwenden (was nicht nach bereits geladenen Bibliotheken sucht). .
Beschränken Sie die Versionsabhängigkeiten auf Funktionen auf Benutzerebene. Verwenden Sie keine neueren Programmierfunktionen, die nicht in allen Versionen verfügbar sind, die Sie unterstützen möchten: Sie müssen eine Kompatibilitätsversion für ältere Versionen bereitstellen, und es ist einfacher, eine einzelne Version zu verwalten.
Manchmal benötigen Sie an vielen Stellen eine Funktion, die für alle Implementierungen verfügbar ist, die Sie interessieren, jedoch auf andere Weise. Dies ist meistens der Fall, wenn Sie sowohl XEmacs als auch GNU Emacs unterstützen möchten: Sie hatten die frustrierende Tendenz, die Funktionen des anderen zu kopieren, nicht jedoch die Benutzeroberfläche. In diesem Fall ist das Definieren einer Kompatibilitätsfunktion bequemer als das Testen am Verwendungsort.
Der folgende Code definiert beispielsweise eine Funktion, die das Fenstersystem des aktuellen Frames, die moderne GNU-Methode, die moderne XEmacs-Methode und die alte Methode zurückgibt, wenn Sie Terminal- und GUI-Frames nicht in derselben Instanz kombinieren konnten.
(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))))
Umgebungsabhängigkeiten
Es gibt nicht viel Code, der plattformabhängig sein muss. Die Variable system-type
gibt das Betriebssystem an. Ich benutze es ausschließlich, um ein paar Hacks für ms-dos
(ja, meine Dateien sind so alt) und zu aktivieren windows-nt
.
Möglicherweise möchten Sie Ihrem ausführbaren Suchpfad ( PATH
) Verzeichnisse hinzufügen. Dies geschieht jedoch normalerweise am besten außerhalb von Emacs, in Ihrem .profile
für Unix-ähnlichen System und über die Systemsteuerung in Windows. Um zu testen, ob ein externes Programm verfügbar ist, rufen Sie auf executable-find
.
Für Code, der je nach Art der GUI unterschiedlich handeln muss, überprüfen Sie window-type
oder dessen Nachfolger (siehe oben).
Initialisierungsdateien
Geben Sie Ihren Code für maximale Kompatibilität ein ~/.emacs
. GNU Emacs suchte ab ~/emacs.d
Version 22. XEmacs suchte ~/.xemacs
ab Version 21.4. Ein alternativer Ansatz besteht darin, Kompatibilitätscode einzugeben ~/.emacs
und zum Abschluss Ihre Hauptdatei zu laden. Setzen Sie (setq load-home-init-file t)
irgendwo zu vermeiden, dass recent¹ Versionen von XEmacs Sie fragen , ob Sie verschieben möchten , .emacs
um die XEmacs-only Lage.
Verschiedene Versionen von Emacs können für einige Makros unterschiedliche und inkompatible Erweiterungen aufweisen. Teilen Sie Ihre bytekompilierten Dateien also nicht zwischen Versionen, sondern kompilieren Sie die Dateien auf jedem Computer.
Manchmal ist eine Funktion veraltet, aber Sie möchten sie trotzdem verwenden, da dies alles ist, was in einer anderen Version vorhanden ist, die Sie unterstützen möchten. Die Byte-Compiler-Warnungen stammen aus der byte-obsolete-variable
Eigenschaft.
(cond
((not (boundp 'desktop-enable))
(defvaralias 'desktop-enable 'desktop-save-mode))
((get 'desktop-enable 'byte-obsolete-variable)
(put 'desktop-enable 'byte-obsolete-variable nil)))
¹ Relativ gesehen im Vergleich zu älteren XEmacs.
window-system
usw. können hier angemessen beantwortet werden.