Idéalement, j'aimerais pouvoir stocker l'intégralité du contenu de mon .emacs.d
répertoire et le faire "fonctionner" sur tous les Emacs dans lesquels je le charge, tout en profitant de toutes les fonctionnalités de l'environnement spécifique, telles que les systèmes de fenêtrage GUI.
Je ne cherche pas une encyclopédie de fonctionnalités incompatibles. Je voudrais juste savoir comment vérifier les fonctionnalités, le système d'exploitation, la version, les graphiques, etc., et comment en tirer parti sans casser le code des autres configurations.
Quelles techniques de base puis-je utiliser pour écrire Elisp qui fonctionne dans plusieurs versions d'Emacs courantes dans la nature (par exemple 22.x +) et sur plusieurs plates-formes sous-jacentes (par exemple OSX, Linux, Windows et autres * nix), tout en tirant parti de la plate-forme et des fonctionnalités spécifiques à la version, le cas échéant?
la source
window-system
, etc. peuvent être raisonnablement répondues ici.forward-char
et que vous souhaitez que la question soit modifiée à lascroll-up
place? Si l'OP veut la compatibilité Emacs 22+, laissez-le tranquille. Et non, la question posée ne concerne pas seulement OS X. Et oui, il y a encore beaucoup de gens qui utilisent d'anciennes versions d'Emacs (certaines même plus anciennes que 22, FWIW).Réponses:
Elisp est un langage interprété. Vous pouvez mettre du code spécifique à la version dans votre
.emacs
, mais le protéger en testant au moment du chargement qu'il fonctionne sur la bonne version.Ce code fonctionnera dans toutes les versions car il
(shiny-new-feature)
n'est évalué que lorsqu'il(is-new-feature-available)
renvoie true. Une grande partie de cette réponse est consacrée à la mise en œuvre(is-new-feature-available)
.Faire face à différents ensembles de fonctionnalités
Il vaut mieux tester si une fonctionnalité est disponible que de tester la version Emacs. Parfois, la fonctionnalité peut être disponible en tant que package facultatif. Si vous souhaitez exécuter du code dans XEmacs ou une autre variante d'Emacs, il se peut qu'il ait acquis les mêmes fonctionnalités dans différentes versions. Utilisez la fonction
boundp
pour tester si une variable est disponible etfboundp
pour tester si une fonction est disponible.Par exemple, l'extrait de code suivant lie une clé pour basculer
visual-line-mode
si elle est disponible, etlonglines-mode
sinon.Parfois, plutôt que de tester la fonctionnalité, il est plus facile d'exécuter un petit morceau de code et d' ignorer les erreurs dues à des fonctions non définies, des arguments invalides, etc. Ne faites pas cela pour de grandes quantités de code, car cela rendra votre code très difficile à déboguer.
Par exemple, je ne veux pas voir de barre d'outils. Les anciennes versions d'Emacs n'en avaient pas du tout. GNU Emacs et XEmacs ont ajouté cette fonctionnalité de différentes manières et en ont fait la valeur par défaut. Voici comment je les désactive. La
set-specifier
fonction est spécifique à XEmacs etdefault-toolbar-visible-p
est spécifique aux versions assez récentes d'Emacs; l'utilisationcondition-case
prend en charge les deux exigences. GNU Emacs fournit une fonction dédiée donc je teste simplement si cette fonction est disponible.Certains noms de visage changent au fil des versions. Utilisez
facep
pour tester la disponibilité d'un nom de visage.Parfois, vous souhaiterez peut-être charger un joli package s'il est présent et ne rien faire si le package n'est pas disponible.
require
a un argument facultatif pour cela.Cet argument a été introduit dans GNU Emacs 20.4 et n'est pas disponible dans XEmacs, donc si vous voulez remonter aussi loin, vous devrez soit l'enrouler
condition-case
soit l'utiliser à laload
place (ce qui ne vérifie pas les bibliothèques déjà chargées) .Limitez les dépendances de version aux fonctionnalités de niveau utilisateur. N'utilisez pas de nouvelles fonctionnalités de programmation qui ne sont pas disponibles dans toutes les versions que vous souhaitez prendre en charge: vous devrez fournir une version de compatibilité pour les anciennes versions, et il est plus facile de maintenir une seule version.
Parfois, vous avez besoin d'une fonctionnalité à de nombreux endroits, et elle est disponible sur toutes les implémentations qui vous intéressent, mais d'une manière différente. C'est surtout le cas si vous voulez prendre en charge à la fois XEmacs et GNU Emacs: ils avaient une tendance frustrante à se copier les fonctionnalités les uns des autres mais pas leur interface. Dans ce cas, la définition d'une fonction de compatibilité est plus pratique que le test au point d'utilisation.
Par exemple, le code suivant définit une fonction qui renvoie le système de fenêtres du cadre actuel, la méthode GNU moderne, la méthode XEmacs moderne et la méthode à l'ancienne lorsque vous ne pouviez pas combiner des cadres de terminal et d'interface graphique dans la même instance.
Dépendances de l'environnement
Il n'y a pas beaucoup de code qui doit dépendre de la plate-forme. La variable
system-type
indique le système d'exploitation. Je l'utilise exclusivement pour activer quelques hacks pourms-dos
(oui, mes fichiers sont aussi anciens) etwindows-nt
.Vous voudrez peut-être ajouter des répertoires à votre chemin de recherche exécutable (
PATH
), mais il est généralement préférable de le faire en dehors d'Emacs, dans votre.profile
système de type Unix et via le panneau de configuration de Windows. Pour tester si un programme externe est disponible, appelezexecutable-find
.Pour le code qui doit agir différemment selon le type d'interface graphique, le cas échéant, cochez
window-type
ou ses successeurs (voir ci-dessus).Fichiers d'initialisation
Pour une compatibilité maximale, insérez votre code
~/.emacs
. GNU Emacs a commencé à chercher dans la~/emacs.d
version 22. XEmacs a commencé à chercher~/.xemacs
dans la version 21.4. Une autre approche consiste à mettre du code de compatibilité~/.emacs
et à terminer en chargeant votre fichier principal. Mettez(setq load-home-init-file t)
quelque part pour éviter que les versions récentes¹ de XEmacs ne vous demandent si vous souhaitez déplacer votre.emacs
emplacement XEmacs uniquement.Différentes versions d'Emacs peuvent avoir une extension différente et incompatible pour certaines macros. Ne partagez donc pas vos fichiers compilés en octets entre les versions, compilez les fichiers sur chaque machine.
Parfois, une fonctionnalité est obsolète, mais vous souhaitez toujours l'utiliser car c'est tout ce qu'il y a dans une autre version que vous souhaitez prendre en charge. Les avertissements du compilateur d'octets proviennent de la
byte-obsolete-variable
propriété.¹ Relativement parlant, par rapport aux XEmac plus anciens.
la source
(Wiki de la communauté. Veuillez ajouter le vôtre!)
S'il existe une fonction, ajoutée dans une version plus récente d'Emacs, que vous souhaitez utiliser, vérifiez si elle est définie avec
fboundp
et définissez une fonction de compatibilité si elle n'est pas définie.Il est considéré comme une mauvaise idée de donner à la fonction de compatibilité le même nom que la fonction réelle, car d'autres codes Elisp peuvent utiliser la même
fboundp
astuce. Par conséquent, utilisez un préfixe pour la fonction de compatibilité et utilisezdefalias
le même nom s'il est défini. Par exemple:Si un élément de configuration ne s'applique qu'à un certain système d'exploitation, il existe plusieurs possibilités. Vous pouvez vérifier la
system-type
variable qui retournegnu/linux
,darwin
,windows-nt
et quelques autres (voir le docstring).Vous pouvez être tenté d'utiliser
window-system
, bien que sa docstring indique que «l'utilisation de cette variable en tant que booléen est déconseillée» et recommande de l'utiliser à ladisplay-graphic-p
place. Notez qu'Emacs est capable d'utiliser différents types d'affichages pour différentes images de nos jours (par exemple, une image sur un terminal et une autre dans une fenêtre "appropriée"), cela peut donc surprendre. Utilisezcurrent-frame-configuration
ouget-buffer-window-list
dans votre elisp pour faire le bon choix.Vous voudrez peut-être vérifier si vous utilisez la bonne version d'emacs. Utilisez featurep pour vérifier la variante. Par exemple:
Vous pouvez également l'utiliser pour vérifier que des modules spécifiques sont chargés. Par exemple, si vous n'utilisez qu'un petit et facile à définir par défaut de common-lisp, vous pouvez opter pour la définition au lieu d'exiger. Par exemple:
Évitez de stocker des fichiers .elc. Ceux-ci ne sont pas compatibles en amont ou en aval entre certaines versions d'Emacs.
la source
Si vous utilisez des fonctions de
cl-lib
mais ne souhaitez pas utiliser les versions obsolètes sans espace de noms, faites de la bibliothèque de compatibilité cl-lib une dépendance de votre projet. Cela vous permettra d'utiliser lescl-
fonctions d' espaces de noms tout en conservant la compatibilité descendante.la source
cl-lib
quand même? De quel avantage dispose-t-ilcl
, qui existe depuis au moins 20 ans?cl
est obsolète et sera probablement supprimé à terme. Son utilisation dans le code a provoqué des avertissements du compilateur d'octets pendant assez longtemps. Je pense que la raison en est qu'ils veulent réutiliser certains descl
noms (commedolist
) avec une sémantique différente.