Kann ich veraltete bytekompilierte Elisp-Dateien vermeiden?

27

Wenn ich Emacs starte, erhalte ich gelegentlich eine Nachricht wie.

Quelldatei `/home/USER/.emacs.d/elpa/....el 'neuer als bytegekompilierte Datei

Außerdem bearbeite ich manchmal ein Paket, das ich entwickle, und vergesse, es erneut zu kompilieren. Wenn ich versuche, die neue Datei zu laden, brauche ich eine Weile, um festzustellen, dass Emacs die alte kompilierte Datei noch verwendet.

Gibt es eine Möglichkeit, Emacs anzuweisen, Byte-kompilierte Dateien, die älter sind als ihre jeweiligen Quelldateien, vollständig zu vermeiden?

Malabarba
quelle

Antworten:

35

Emacs 24.3 oder niedriger

Es gibt keine integrierte Möglichkeit, das Laden dieser alten Dateien zu verhindern, aber es gibt einfache Möglichkeiten, sie zu entfernen.

  • Sie können die gesamte elpa Verzeichnis neu kompiliert durch den Aufruf:
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/.
    Dies sollte veraltete Dateien loswerden.
  • Sie können das Auto-Compile- Paket verwenden und aktivieren, auto-compile-on-load-modewelche Dateien kompiliert werden können, bevor sie geladen werden.

Emacs 24.4

Ja, und es stellt sich als ziemlich einfach heraus. Die load-prefer-newer Variable dient genau diesem Zweck.

(setq load-prefer-newer t)

Leider funktioniert es nicht, wenn Code speziell auf die .elcDatei abzielt, z (load "server.elc"). Aber es sollte ausreichen, solange Sie requires verwenden oder loadohne Suffix telefonieren, was Sie sollten.

Aus dem Dokument:

load-prefer-newer ist eine Variable, die in lread.c definiert ist.
Sein Wert ist Null

Dokumentation:
Nicht-Null bedeutet, dass beim Laden die neueste Version einer Datei bevorzugt wird.
Dies gilt, wenn ein Dateinamensuffix nicht explizit angegeben ist und load verschiedene mögliche Suffixe versucht (siehe load-suffixes und load-file-rep-suffixes). Normalerweise stoppt es bei der ersten vorhandenen Datei, es sei denn, Sie geben ausdrücklich die eine oder die andere an. Wenn diese Option nicht null ist, werden alle Suffixe überprüft und die jeweils neueste Datei verwendet.
Beachten Sie, dass dies beim Anpassen offensichtlich keine Auswirkungen auf Dateien hat, die geladen werden, bevor Ihre Anpassungen gelesen werden!

Malabarba
quelle
1
Ich möchte die Leute dringend bitten, die (ausgezeichnete!) auto-compileBibliothek in Emacs 24.4+ und höher zu verwenden. Es ist eine echte Lösung zum Konfigurieren und Vergessen. Stelltload-prefer-newer nur sicher, dass Sie weiterhin langsamen, nicht kompilierten Code ausführen, nachdem der kompilierte Code veraltet ist.
Phils
1
@phils Heutzutage ist Byte-Code dank eifriger Makro-Erweiterung nicht viel schneller als einfacher Quellcode.
Lunaryorn
Änderungen, die ich an der org-agenda-sorting-strategy (in org-agenda.el) vorgenommen habe, wurden nach einem Neustart nicht berücksichtigt, aber das erneute Kompilieren der .elc-Dateien, wie in der Antwort beschrieben, löste das Problem.
Earlio
17

Wenn Sie nur festlegen load-prefer-newer(wo verfügbar), wird der richtige Code geladen, der jedoch möglicherweise nicht bytemäßig kompiliert wurde. Dies kann zu einer leichten Beeinträchtigung der Leistung führen.

Sie können Jonas Bernoullis exzellente Autokompilierungsbibliothek verwenden, um sicherzustellen, dass dieses Problem nicht auftritt. Insbesondere auto-compile-on-load-modewerden veraltete .elcDateien vor dem Laden neu kompiliert .

sanityinc
quelle
3

Das habe ich im Internet schon vor langer Zeit kennengelernt:

;; If you're saving an elisp file, likely the .elc is no longer valid:
(add-hook 'emacs-lisp-mode-hook 'esk-remove-elc-on-save)
(defun esk-remove-elc-on-save ()
  "If you're saving an elisp file, likely the .elc is no longer valid."
  (make-local-variable 'after-save-hook)
  (add-hook 'after-save-hook
            (lambda ()
              (if (file-exists-p (concat buffer-file-name "c"))
                  (delete-file (concat buffer-file-name "c"))))))

Wenn Sie FILEim Emacs-Lisp-Modus arbeiten und ihn speichern, wird der obige Code entfernt, FILEcfalls er existiert.

Adobe
quelle
0

Außerdem bearbeite ich manchmal ein Paket, das ich entwickle, und vergesse, es erneut zu kompilieren. Wenn ich versuche, die neue Datei zu laden, brauche ich eine Weile, um festzustellen, dass Emacs die alte kompilierte Datei noch verwendet.

Darf ich vorschlagen, einen Haken in Ihre Init-Datei einzufügen?

(add-hook 'after-save-hook 'byte-compile-current-buffer)

Oder, wenn Sie den Hook nur auf el-Dateien anwenden möchten:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))
Nsukami _
quelle
9
Whoah, das würde versuchen, auch nicht-elisp-Puffer zu kompilieren. Nicht ideal! Der robuste Weg, dies zu tun, ist mit dem Auto-Compile-Paket.
Sanityinc