Ich möchte ein Paket ändern, testen und anschließend hoffentlich eine Pull-Anfrage stellen. Wie mache ich das sicher und effizient? Die Frage könnte sich zu weit gefasst anfühlen, ich werde die Antwort akzeptieren, die die folgenden Themen abdeckt:
Ich würde erwarten, einen separaten Zweig eines Pakets zu installieren und in der Lage zu sein, nach Belieben zwischen diesem und dem stabilen Zweig zu wechseln, wobei die Neukompilierung automatisch durchgeführt wird, wenn dies erforderlich ist, aber
package.el
dies scheint keine einfache Möglichkeit zu bieten. Diese Antwort auf emacs-SE informiert uns darüber, dass "Wenn mehrere Kopien eines Pakets installiert sind, wird die erste geladen", sodass man sich zwar manuell damit herumschlagen kannload-path
, sich aber nicht robust anfühlt. Was ist die Standardmethode zum Auswählen einer bestimmten Paketversion unter den installierten?Selbst wenn ich es schaffe, Emacs mehrere Zweige auszusetzen, muss ich bei signifikanten Änderungen sicherstellen, dass der nicht gepatchte Zweig "entladen" und seine Nebenwirkungen isoliert sind. Wird
unload-feature
dies richtig gehandhabt oder weist es möglicherweise Besonderheiten auf, die jeder Tester von Paketen mit mehreren Versionen kennen sollte?Wie installiere und teste ich die lokale Version? Die Antwort scheint davon abhängig zu sein, ob das Paket einfach (= eine Datei) oder vielseitig ist. EmacsWiki sagt über Multifile-Pakete: " MELPA erstellt Pakete für Sie ". Ich bezweifle, dass ich jedes Mal mit MELPA sprechen muss (oder sollte), wenn ich ein
defun
Formular in einem Paket mit mehreren Dateien ändere , aber die Frage bleibt. Zumindest muss ich Package Manager über die lokale Version informieren, und wenn ja, wie mache ich das?Welche Namen sollte ich lokalen Versionen von Paketen zuweisen? Angenommen, ich möchte gleichzeitig an mehreren Features oder Bugs arbeiten, was bedeutet, dass mehrere Zweige vorhanden sind. Emacs erlaubt es nicht, Versionen in einer beschreibenden Weise zu benennen (in Anlehnung an
20170117.666-somebugorfeature
). Ich schätze, ich könnte das Paket selbst umbenennen, ein Suffix pro Zweig, aber wie beim manuellen Herumspielenload-path
in Q1 ist dies ein hässlicher Hack. Ich werde es also nicht mit etwas versuchen, das ich vorab senden möchte, es sei denn, es ist eine allgemein akzeptierte Praxis .
Die Fragen sind wahrscheinlich naiv, da ich nie einen Patch geschrieben habe, noch einen mit git oder einem ähnlichen vcs angewendet habe. Für viele Emacs-Benutzer ist das Patchen eines Emacs-Pakets jedoch möglicherweise das erste (oder vielleicht das einzige) Unternehmen, das sich mit sozialer Programmierung befasst. Aus diesem Grund sind Antworten auf diese Frage meines Erachtens immer noch wertvoll.
quelle
emacs -L
Ansatz, um eine lokale Version eines Pakets zu laden, das ich auch mit Cask global installiert habe. Eine Sache, die mich abschreckte, war, dass beim Ausführen<package>-version
immer die global installierte Version zurückgegeben wird, auch wenn ich tatsächlich die lokal geänderte Version ausgeführt habe. Es stellte sich heraus, dass dies daran lag, dass das<package>-version
für dieses Paket die Version von erhältpackages.el
.Gute Frage! Die Antwort ist, dass es bis jetzt keine gute Antwort gab, da keiner der vorhandenen Paketmanager für diesen Anwendungsfall entwickelt wurde (mit Ausnahme von Borg , aber Borg versucht nicht, andere gängige Paketverwaltungsvorgänge wie die Behandlung von Abhängigkeiten zu handhaben) .
Jetzt gibt es jedoch
straight.el
einen Paketmanager der nächsten Generation für Emacs, der dieses Problem so umfassend wie möglich behandelt. Haftungsausschluss: Ich habe geschriebenstraight.el
!Nach dem Einfügen des Bootstrap-Snippets ist die Installation eines Pakets so einfach wie
Dadurch wird das Git-Repository für Magit geklont, das Paket durch Verknüpfen der Dateien in einem separaten Verzeichnis erstellt, Byte-kompiliert, Autoloads generiert und ausgewertet und das Paket
load-path
korrekt konfiguriert . Wenn das Paket bereits geklont und erstellt ist, passiert natürlich nichts und Ihre Init-Zeit leidet nicht.Wie können Sie Änderungen an Magit vornehmen? Es ist trivial! Verwenden Sie
M-x find-function
oderM-x find-library
, um zum Quellcode zu springen, und hacken Sie los! Sie können Ihre Änderungen live testen, wie es für die Emacs Lisp-Entwicklung allgemein üblich ist. Wenn Sie Emacs neu starten, wird das Paket automatisch neu erstellt, neu kompiliert und so weiter. Es ist vollautomatisch und kinderleicht.Wenn Sie mit Ihren Änderungen zufrieden sind, schreiben Sie einfach eine Commit-, Push- und Pull-Anforderung. Sie haben die vollständige Kontrolle über Ihre lokalen Pakete. Ihre Konfiguration kann jedoch immer noch zu 100% reproduzierbar sein, da Sie
straight.el
nach einer Sperrdatei fragen können, in der die Git-Revisionen aller Ihrer Pakete, einschließlich sichstraight.el
selbst, MELPA usw., gespeichert werden.straight.el
kann jedes Paket von MELPA, GNU ELPA oder EmacsMirror installieren. Es verfügt jedoch auch über ein hochflexibles DSL-Rezept, mit dem Sie von jedem Ort aus installieren und den Aufbau des Pakets anpassen können. Hier ist ein Beispiel, das einige der Optionen zeigt:straight.el
hat lächerlich umfassende Dokumentation. Lesen Sie alles darüber auf GitHub .quelle
Das sind alles gute Fragen!
Emacs arbeitet mit einem Memory-Image-Modell, bei dem das Laden von neuem Code das Memory-Image der ausgeführten Instanz ändert. Das Definieren neuer Funktionen und Variablen ist einfach rückgängig zu machen, wenn Sie eine Liste von ihnen führen. Es gibt jedoch eine Reihe von Nebenwirkungen, die ein Modul möglicherweise rückgängig machen möchte. Es sieht
unload-feature
aber so aus, als würde es ziemlich gut ausgehen.Ich denke, was Sie tun wollen, ist eine Kombination aus Live-Codierung und gelegentlichem Neustart von Emacs, wobei Sie das Modul, an dem Sie arbeiten, aus Ihrem Zweig laden und nicht von dem Ort, an dem es installiert ist. Wenn Sie am Ende viele dieser Zweige haben, möchten Sie vielleicht ein Shell-Skript, das Emacs mit dem richtigen
load-path
für den startet, an dem Sie gerade arbeiten. In jedem Fall würde ich das Paket nicht umbenennen; Ich denke, das wäre noch verwirrender, da Emacs dann beide laden könnten.Während Sie Ihre Patches entwickeln, können Sie zunächst einfach die Funktionen neu definieren, die Sie direkt in Ihrer Live-Emacs-Sitzung ändern. Auf diese Weise können Sie die neuen Definitionen sofort testen, ohne Emacs zu verlassen. Insbesondere können Sie beim Bearbeiten einer elisp-Datei
C-M-x
(eval-defun
) verwenden, um die aktuelle Funktion in Ihrer aktuellen Emacs-Sitzung auszuwerten. Sie können es dann aufrufen, um sicherzustellen, dass es funktioniert. Wenn Sie etwas ändern, das beim Starten von Emacs passiert, müssen Sie Emacs wahrscheinlich starten und stoppen, um es zu testen. Sie können dies tun, indem Sie einen separaten Emacs-Prozess starten und stoppen, damit Ihre Editiersitzung nicht unterbrochen wird.quelle
Ich denke, es gibt noch keine gute Antwort darauf (ich gehe davon aus, dass Sie mit Cask eine Teillösung erhalten können, die ich jedoch nicht ausreichend kenne, um Ihnen eine gute Antwort zu geben; hoffentlich wird es jemand anderes tun), aber hier ist die Antwort Was ich mache (ich verwende selten ein Elisp-Paket, ohne lokale Änderungen daran vorzunehmen, also ist es wirklich mein "normaler" Weg):
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
in deinem
~/.emacs
addAuf diese Weise werden alle Pakete "direkt von Git" installiert. Ein einfacher
cd ~/src/elpa; make
Befehl kompiliert die benötigten Pakete neu undC-h o thepackage-function
springt zu einer Quelldatei, die sich unter Git befindet.Um "aus einer Laune heraus zwischen dem Zweig und dem stabilen Zweig zu wechseln", müssen Sie Folgendes tun
git checkout <branch>; cd ~/src/elpa; make
: und wenn Sie möchten, dass sich dies auf die Ausführung von Emacs-Sitzungen auswirkt, ist mehr Arbeit erforderlich. Ich empfehle generell, esunload-feature
nur in Ausnahmesituationen zu verwenden (es ist eine gute Funktion, aber momentan nicht zuverlässig genug).Es erfüllt auch nicht viele Ihrer Anforderungen. Und es hat einige zusätzliche Nachteile, vor allem die Tatsache, dass der Git-Klon vieler Pakete nicht ganz mit dem von elpa.git erwarteten Layout und Inhalt übereinstimmt
<pkg>-pkg.el
Da das Makefile von elpa.git erwartet, dass diese Datei erstellt wird,<pkg>.el
anstatt bereitgestellt zu werden, wird die Kompilierung jedoch problematischer anders ausgeführt, sodass Sie manchmal mitrequire
s) spielen müssen.Das bedeutet natürlich, dass Sie diese Pakete von Hand installieren, also müssen Sie auf Abhängigkeiten achten. Dieses Setup interagiert korrekt mit anderen Paketen, die von
package-install
, tho installiert wurden , so dass es nicht so schlimm ist.quelle
Die anderen Antworten auf diese Frage, einschließlich meiner anderen Antwort , beziehen sich auf das Patchen eines Emacs-Pakets, indem Änderungen am Code vorgenommen werden. Die Leute, die diese Frage über Google finden, denken möglicherweise an etwas anderes, wenn sie "Emacs-Paket patchen" sagen - nämlich das Überschreiben des Verhaltens, ohne den Quellcode ändern zu müssen.
Mechanismen dafür sind in zunehmender Reihenfolge der Aggressivität:
let
Trotz der Kraft der ersten beiden Optionen bin ich ziemlich oft auf die dritte Route gegangen, da es manchmal keinen anderen Weg gibt. Aber dann ist die Frage, was passiert, wenn sich die ursprüngliche Funktionsdefinition ändert? Sie könnten nicht wissen, dass Sie die Version dieser Definition aktualisieren müssen, die Sie kopiert und in Ihre Init-Datei eingefügt haben!
Da ich davon besessen bin, Dinge zu patchen, habe ich das Paket geschrieben
el-patch
, das dieses Problem so umfassend wie möglich löst. Die Idee ist, dass Sie s-expression-basierte Unterschiede in Ihrer init-Datei definieren, die sowohl die ursprüngliche Funktionsdefinition als auch Ihre Änderungen daran beschreiben. Dadurch werden Ihre Patches viel lesbarer und Sie könnenel-patch
später überprüfen, ob die ursprüngliche Funktionsdefinition aktualisiert wurde, seit Sie Ihren Patch erstellt haben. (In diesem Fall werden Ihnen die Änderungen über Ediff angezeigt!) Zitat aus der Dokumentation:quelle
Wenn Sie viele Änderungen vornehmen, sollten Sie, wie ich finde
straight.el
, die Antwort von Radon Rosborough verwenden .Wenn Sie nur eine einmalige Änderung vornehmen möchten, gehen wir von einem Projekt mit dem Namen aus
fork-mode
und führen die folgenden Schritte aus:mkdir ~/.emacs.d/lisp-gits
https://github.com/user/fork-mode
cd ~/.emacs.d/lisp-gits && git clone [email protected]:user/fork-mode.git
Schreiben Sie den folgenden Code in Ihr
.emacs
Jetzt können Sie den Emacs-Modus verwenden
C-h f
, um die Funktionen zu finden, die Sie ändern möchten. Sie werden feststellen, dass Sie, wenn das Paket in lisp-gits installiert ist, dorthin springen. Verwenden Sie magit oder andere git-Befehle, um Änderungen festzuschreiben / zu pushen, und verwenden Sie dann github, um Ihre Pull-Anforderungen zu senden.Sobald Ihre Pull-Anforderungen akzeptiert wurden, können Sie das Projekt einfach entfernen
~/.emacs.d/lisp-gits
und den Paketmanager seine Arbeit machen lassen.quelle