Je souhaite modifier un package, le tester et, espérons-le, soumettre une demande d'extraction par la suite. Comment le faire de manière sûre et efficace? La question peut sembler trop large, j'accepterai la réponse qui couvre les questions suivantes:
Je m'attends à installer une branche distincte d'un package et à pouvoir basculer entre celle-ci et une branche stable sur un coup de tête, avec une recompilation effectuée automatiquement lorsque cela est nécessaire, mais
package.el
ne semble pas offrir un moyen simple de le faire. Cette réponse sur emacs-SE nous informe que "Si plusieurs copies d'un paquet sont installées, alors la première sera chargée", donc je suppose que l'on pourrait jouer manuellementload-path
mais cela ne semble pas robuste. Quelle est la méthode standard pour sélectionner une version spécifique du package parmi celles installées?Même si je parviens à exposer plusieurs branches à Emacs, pour des ajustements importants, je dois m'assurer que la branche non corrigée est «déchargée» et ses effets secondaires isolés. Est-
unload-feature
ce que cela gère correctement ou peut-être qu'il a des particularités que tout testeur de packages multi-versions devrait connaître?Comment installer et tester la version locale? La réponse semble dépendre du fait que le package est simple (= un fichier) ou multifichier. EmacsWiki dit à propos des packages multifichiers : « MELPA crée des packages pour vous ». Je doute que je doive (ou devrais) parler à MELPA chaque fois que je change un
defun
formulaire dans un package multifichier, mais la question demeure. Au moins, je dois informer le gestionnaire de paquets de la version locale, et si oui, comment dois-je procéder?Quels noms dois-je attribuer aux versions locales des packages? Supposons que je veuille travailler sur plusieurs fonctionnalités ou bugs simultanément, ce qui signifie avoir plusieurs branches. Emacs ne permettra pas de nommer les versions de manière descriptive (dans le sens de
20170117.666-somebugorfeature
). Je suppose que je pourrais renommer le package lui-même, un suffixe par branche, mais encore une fois, comme jouer manuellement avecload-path
Q1, c'est un vilain hack, donc je ne vais pas l'essayer avec quelque chose que j'ai l'intention d'envoyer en amont, sauf si c'est une pratique largement acceptée .
Les questions sont probablement naïves, car je n'ai jamais écrit de correctif ni appliqué de correctif avec git ou un vcs similaire. Cependant, pour de nombreux utilisateurs d'Emacs, patcher un paquet Emacs pourrait être leur tout premier (ou peut-être le seul) effort de programmation sociale, c'est pourquoi, je pense, les réponses à cette question seraient toujours utiles.
la source
emacs -L
approche pour charger une version locale d'un package que j'ai également installé globalement à l'aide de Cask. Une chose qui m'a dérouté était que l'exécution<package>-version
renvoie toujours la version installée globalement, même lorsque j'exécutais réellement la version modifiée locale. Il s'avère que c'est parce que<package>-version
pour ce package obtient la versionpackages.el
.Bonne question! La réponse est que jusqu'à présent, il n'y avait pas de bonne réponse, car aucun des gestionnaires de packages existants n'a été conçu pour ce cas d'utilisation (à l'exception de Borg , mais Borg n'essaie pas de gérer d'autres opérations courantes de gestion de packages comme la gestion des dépendances) .
Mais maintenant, il existe
straight.el
un gestionnaire de packages de nouvelle génération pour Emacs qui résout ce problème de manière aussi complète que possible. Avertissement: j'ai écritstraight.el
!Après avoir inséré l' extrait de bootstrap , l'installation d'un package est aussi simple que
Cela clonera le référentiel Git pour Magit, construira le paquet en associant ses fichiers à un répertoire séparé, compilera des octets, générera et évaluera les chargements automatiques et configurera
load-path
correctement. Bien sûr, si le package est déjà cloné et construit, rien ne se passe et votre temps d'initialisation ne souffre pas.Comment apportez-vous des modifications à Magit? C'est trivial! Utilisez simplement
M-x find-function
ouM-x find-library
pour accéder au code source et pirater! Vous pouvez évaluer vos modifications pour les tester en direct, comme c'est la pratique générale pour le développement Emacs Lisp, et lorsque vous redémarrez Emacs, le package sera automatiquement reconstruit, recompilé, etc. C'est complètement automatique et infaillible.Lorsque vous êtes satisfait de vos modifications, il vous suffit de valider, de pousser et de faire une demande d'extraction. Vous avez un contrôle total sur vos packages locaux. Mais votre configuration peut toujours être reproductible à 100%, car vous pouvez demander
straight.el
de créer un fichier de verrouillage qui enregistre les révisions Git de tous vos packages, y comprisstraight.el
lui-même, MELPA, etc.straight.el
peut installer n'importe quel package à partir de MELPA, GNU ELPA ou EmacsMirror. Mais il a également une recette DSL très flexible qui vous permet d'installer de n'importe où, ainsi que de personnaliser la façon dont le package est construit. Voici un exemple qui montre certaines des options:straight.el
a une documentation ridiculement complète. Lisez tout sur GitHub .la source
Ce sont toutes de bonnes questions!
Emacs fonctionne sur un modèle d'image mémoire, où le chargement de nouveau code modifie l'image mémoire de l'instance en cours d'exécution. La définition de nouvelles fonctions et variables est facile à annuler, si vous en gardez une liste, mais il y a beaucoup d'effets secondaires qu'un module pourrait avoir que vous voudriez annuler. Il semble cependant que
unload-feature
cela soit plutôt bon.Je pense que ce que vous allez vouloir faire est une combinaison de codage en direct et de relance occasionnelle d'Emacs, en chargeant le module sur lequel vous travaillez à partir de votre branche plutôt qu'à partir de l'endroit où il est installé. Si vous vous retrouvez avec beaucoup de ces branches, vous voudrez peut-être un script shell qui lance emacs avec le bon
load-path
pour celui sur lequel vous travaillez en ce moment. En tout cas, je ne renommerais pas le package; Je pense que ce serait encore plus déroutant car emacs pourrait alors les charger tous les deux.Lorsque vous développez vos patchs, vous pouvez commencer par redéfinir simplement les fonctions que vous modifiez directement dans votre session Emacs en direct. Cela vous permet de tester les nouvelles définitions immédiatement, sans quitter Emacs. Plus précisément, lorsque vous modifiez un fichier elisp, vous pouvez utiliser
C-M-x
(eval-defun
) pour évaluer la fonction actuelle dans votre session Emacs actuelle. Vous pouvez ensuite l'appeler pour vous assurer que cela fonctionne. Si vous changez quelque chose qui se produit au démarrage d'Emacs, vous devrez probablement démarrer et arrêter Emacs pour le tester; vous pouvez le faire en démarrant et en arrêtant un processus Emacs distinct afin que votre session d'édition ne soit pas interrompue.la source
Je ne pense pas qu'il y ait encore une bonne réponse à cela (je m'attends à ce que vous puissiez obtenir une solution partielle avec Cask, mais je ne la connais pas suffisamment pour vous donner une bonne réponse en l'utilisant; j'espère que quelqu'un d'autre le fera), mais voici ce que je fais (j'utilise rarement un paquet Elisp sans y apporter de modifications locales, c'est donc vraiment ma façon "normale"):
cd ~/src; git clone ..../elpa.git
cd ~/src/elisp; git clone ....thepackage.git
cd ~/src/elpa/packages; ln -s ~/src/elisp/* .
cd ~/src/elpa; make
dans votre
~/.emacs
annonceDe cette façon, tous les packages sont installés "directement depuis Git", un simple
cd ~/src/elpa; make
recompilera ceux qui en ont besoin, etC-h o thepackage-function
passera à un fichier source qui est sous Git.Pour "basculer entre elle et une branche stable sur un coup de tête", vous devrez le faire
git checkout <branch>; cd ~/src/elpa; make
; et si vous voulez que cela affecte l'exécution des sessions Emacs, cela demandera plus de travail. Je recommande généralement de ne pas l'utiliserunload-feature
sauf dans des situations exceptionnelles (c'est une bonne fonctionnalité, mais ce n'est pas assez fiable actuellement).Il ne satisfait pas non plus à bon nombre de vos exigences. Et il a quelques inconvénients supplémentaires, principalement le fait que le clone Git de nombreux packages ne correspond pas tout à fait à la présentation et au contenu attendus par le makefile d'elpa.git, vous devrez donc commencer par peaufiner ces packages (généralement des choses qui ont à voir avec
<pkg>-pkg.el
, puisque le makefile d'elpa.git s'attend à construire ce fichier<pkg>.el
plutôt que de le fournir, mais plus problématique, la compilation est effectuée différemment, donc parfois vous devez jouer avec lerequire
s).Oh et bien sûr, cela signifie essentiellement que vous installez ces packages à la main, vous devez donc faire attention aux dépendances. Cette configuration interagit correctement avec les autres packages installés par
package-install
Tho, donc ce n'est pas si terrible.la source
Les autres réponses à cette question, y compris mon autre réponse , parlent de patcher un paquet Emacs en apportant des modifications à son code. Mais les gens qui trouvent cette question via Google pourraient penser à autre chose lorsqu'ils disent "patcher un paquet Emacs" - à savoir, remplacer son comportement sans avoir à modifier son code source.
Les mécanismes pour ce faire comprennent, par ordre croissant d'agressivité:
let
Malgré la puissance des deux premières options, je me suis retrouvé à prendre la troisième route assez souvent, car il n'y a parfois pas d'autre moyen. Mais alors la question est, et si la définition de fonction d'origine change? Vous n'auriez aucun moyen de savoir que vous deviez mettre à jour la version de cette définition que vous aviez copiée et collée dans votre fichier init!
Parce que je suis obsédé par les correctifs, j'ai écrit le package
el-patch
, qui résout ce problème de manière aussi complète que possible. L'idée est que vous définissez des différences basées sur l'expression s dans votre fichier init, qui décrivent à la fois la définition de la fonction d'origine et vos modifications. Cela rend vos correctifs beaucoup plus lisibles et permet égalementel-patch
de valider ultérieurement si la définition de fonction d'origine a été mise à jour depuis que vous avez créé votre correctif. (Si oui, il vous montrera les changements via Ediff!) Citant de la documentation:la source
Lorsque vous apportez beaucoup de changements, je pense que vous devriez utiliser
straight.el
, voir la réponse de Radon Rosborough .Si vous souhaitez simplement apporter une modification unique, supposons que pour un projet appelé
fork-mode
, procédez comme suit:mkdir ~/.emacs.d/lisp-gits
https://github.com/user/fork-mode
cd ~/.emacs.d/lisp-gits && git clone [email protected]:user/fork-mode.git
Écrivez le code suivant dans votre
.emacs
Vous pouvez maintenant utiliser le mode emacs, en utilisant
C-h f
pour trouver les fonctions que vous souhaitez modifier. Vous remarquerez que lorsque le package est installé dans lisp-gits, vous allez y accéder. Utilisez magit ou d'autres commandes git pour valider / pousser les modifications, puis utilisez github pour envoyer vos demandes d'extraction.Une fois vos demandes de tirage acceptées, vous pouvez simplement supprimer le projet
~/.emacs.d/lisp-gits
et laisser le gestionnaire de packages faire son travail.la source