Im Idealfall möchte ich in der Lage sein, den gesamten Inhalt meines .emacs.d
Verzeichnisses zu speichern und es "nur auf allen Emacs funktionieren zu lassen, in die ich es lade", aber dennoch alle Funktionen der spezifischen Umgebung nutzen, wie z. B. GUI-Fenstersysteme.
Ich suche keine Enzyklopädie mit inkompatiblen Funktionen. Ich möchte nur wissen, wie man nach Funktionen, Betriebssystemen, Versionen, Grafiken usw. sucht und wie man diese nutzt, ohne den Code für andere Konfigurationen zu beschädigen.
Welche grundlegenden Techniken kann ich verwenden, um Elisp zu schreiben, das in mehreren Versionen von Emacs funktioniert, die in freier Wildbahn verbreitet sind (z. B. 22.x +) und auf mehreren zugrunde liegenden Plattformen (z. B. OSX, Linux, Windows und anderen * nix), während ich die Plattform nutze und gegebenenfalls versionenspezifische Funktionen?
quelle
window-system
usw. können hier angemessen beantwortet werden.forward-char
und Sie möchten, dass die Fragescroll-up
stattdessen geändert wird ? Wenn das OP die Kompatibilität mit Emacs 22+ wünscht, lassen Sie es in Ruhe. Und nein, die gestellte Frage betrifft nicht nur OS X. Und ja, es gibt immer noch viele Leute, die ältere Emacs-Versionen verwenden (einige sogar älter als 22, FWIW).Antworten:
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.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 umfboundp
zu testen, ob eine Funktion verfügbar ist.Das folgende Snippet bindet beispielsweise einen Schlüssel zum Umschalten,
visual-line-mode
falls verfügbar, undlonglines-mode
ansonsten.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 unddefault-toolbar-visible-p
spezifisch für ausreichend aktuelle Versionen von Emacs. usingcondition-case
kümmert sich um beide Anforderungen. GNU Emacs bietet eine spezielle Funktion, daher teste ich lediglich, ob diese Funktion verfügbar ist.Einige Gesichtsnamen ändern sich über Versionen. Verwenden Sie
facep
diese Option , um die Verfügbarkeit eines Gesichtsnamens zu testen.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.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
oderload
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.
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ürms-dos
(ja, meine Dateien sind so alt) und zu aktivierenwindows-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 aufexecutable-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.¹ Relativ gesehen im Vergleich zu älteren XEmacs.
quelle
(Community-Wiki. Bitte füge deins hinzu!)
Wenn es eine Funktion gibt, die in einer neueren Emacs-Version hinzugefügt wurde und die Sie verwenden möchten, überprüfen Sie, ob sie mit definiert ist
fboundp
, und definieren Sie eine Kompatibilitätsfunktion, wenn sie nicht definiert ist.Es wird als schlechte Idee angesehen, der Kompatibilitätsfunktion den gleichen Namen wie der eigentlichen Funktion zu geben, da andere Elisp-Codes möglicherweise denselben
fboundp
Trick verwenden. Verwenden Sie daher ein Präfix für die Kompatibilitätsfunktion und verwenden Sie esdefalias
für denselben Namen, wenn es definiert ist. Z.B:Wenn eine Konfiguration nur für ein bestimmtes Betriebssystem gelten soll, gibt es verschiedene Möglichkeiten. Sie können die
system-type
Kontrollvariable, die zurückkehrtgnu/linux
,darwin
,windows-nt
und ein paar andere (siehe docstring).Sie könnten versucht sein, zu verwenden
window-system
, obwohl in der Dokumentzeichenfolge angegeben ist, dass "die Verwendung dieser Variablen als Boolescher Wert veraltet ist", und stattdessen die Verwendung empfohlen wirddisplay-graphic-p
. Beachten Sie, dass Emacs heutzutage verschiedene Arten von Anzeigen für verschiedene Frames verwenden kann (z. B. einen Frame auf einem Terminal und einen anderen in einem "richtigen" Fenster), sodass dies zu Überraschungen führen kann. Verwenden Siecurrent-frame-configuration
oderget-buffer-window-list
in Ihrem Elisp, um die richtige Wahl zu treffen.Vielleicht möchten Sie überprüfen, ob Sie unter dem richtigen Geschmack von Emacs laufen. Verwenden Sie featurep, um die Variante zu überprüfen. Z.B:
Sie können damit auch überprüfen, ob bestimmte Module geladen sind. Wenn Sie beispielsweise nur eine kleine und einfach zu definierende Definition von Common-Lisp verwenden, können Sie sich für die Definition entscheiden, anstatt sie zu benötigen. Z.B:
Vermeiden Sie das Speichern von .elc-Dateien. Diese sind zwischen einigen Emacs-Versionen nicht vorwärts oder rückwärtskompatibel.
quelle
Wenn Sie Funktionen von verwenden,
cl-lib
aber die veralteten Versionen ohne Namespace nicht verwenden möchten, machen Sie die cl-lib-Kompatibilitätsbibliothek zu einer Abhängigkeit Ihres Projekts. Auf diese Weise können Sie die Namespace-cl-
Funktionen verwenden, aber die Abwärtskompatibilität beibehalten.quelle
cl-lib
? Welchen Vorteil hat es gegenüber demcl
, der es seit mindestens 20 Jahren gibt?cl
ist veraltet und wird wahrscheinlich irgendwann entfernt. Die Verwendung im Code hat lange Zeit zu Byte-Compiler-Warnungen geführt. Ich denke, der Grund ist, dass sie einige dercl
Namen (wiedolist
) mit unterschiedlicher Semantik wiederverwenden möchten .