Puis-je éviter les fichiers elisp compilés en octets obsolètes?

27

Parfois, quand je démarre Emacs, je reçois un message comme.

Fichier source `/home/USER/.emacs.d/elpa/....el 'plus récent que le fichier compilé en octets

De plus, je modifie parfois un package que je développe et oublie de le recompiler. Lorsque j'essaie de charger le nouveau fichier, il me faut du temps pour réaliser qu'Emacs utilise toujours l'ancien fichier compilé.

Existe-t-il un moyen de dire à Emacs d'éviter complètement les fichiers compilés en octets qui sont plus anciens que leurs fichiers source respectifs?

Malabarba
la source

Réponses:

35

Emacs 24.3 ou inférieur

Il n'y a aucun moyen intégré d'empêcher le chargement de ces anciens fichiers, mais il existe des moyens faciles de s'en débarrasser.

  • Vous pouvez recompiler l'ensemble du répertoire ELPA en appelant:
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/.
    Cela devrait se débarrasser des fichiers obsolètes.
  • Vous pouvez utiliser le package de compilation automatique et activer auto-compile-on-load-modequi peut compiler les fichiers avant leur chargement.

Emacs 24.4

Oui, et cela s'avère assez simple. La load-prefer-newer variable sert précisément cet objectif.

(setq load-prefer-newer t)

Malheureusement, cela ne fonctionnera pas lorsqu'un code cible spécifiquement le .elcfichier, tel que (load "server.elc"). Mais cela devrait être suffisant tant que vous utilisez requires ou appelez loadsans suffixe, ce que vous devriez.

Du doc:

load-prefer-newer est une variable définie dans lread.c.
Sa valeur est nulle

Documentation:
Non nul signifie que load préfère la dernière version d'un fichier.
Cela s'applique lorsqu'un suffixe de nom de fichier n'est pas explicitement spécifié et que load essaie divers suffixes possibles (voir load-suffixes et load-file-rep-suffixes). Normalement, il s'arrête au premier fichier qui existe, sauf si vous spécifiez explicitement l'un ou l'autre. Si cette option n'est pas nulle, elle vérifie tous les suffixes et utilise le fichier le plus récent.
Notez que si vous personnalisez cela, cela n'affectera évidemment pas les fichiers qui sont chargés avant la lecture de vos personnalisations!

Malabarba
la source
1
J'exhorte les gens à utiliser la auto-compilebibliothèque (excellente!) Dans Emacs 24.4+, ainsi que ci-dessous. C'est une véritable solution de configuration et d'oubli. load-prefer-newergarantit que vous continuerez à exécuter du code non compilé lent une fois que votre code compilé sera obsolète.
phils
1
@phils De nos jours, le code d'octet n'est pas beaucoup plus rapide que le code source ordinaire, grâce à une expansion des macros.
lunaryorn
Les modifications que j'ai apportées à org-agenda-sorting-strategy (dans org-agenda.el) n'étaient pas reflétées après un redémarrage, mais la recompilation des fichiers .elc comme décrit dans la réponse a résolu le problème.
earlio
17

Si vous définissez uniquement load-prefer-newer(le cas échéant), le code correct sera chargé, mais il n'a peut-être pas été compilé en octets, il peut donc y avoir une légère baisse des performances.

Vous pouvez utiliser l'excellente bibliothèque de compilation automatique de Jonas Bernoulli pour vous assurer que ce problème ne se pose pas. En particulier, auto-compile-on-load-moderecompilera les .elcfichiers obsolètes avant de les charger.

sanityinc
la source
3

Je l'ai rencontré il y a longtemps sur Internet:

;; 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"))))))

si vous travaillez FILEen mode emacs-lisp et que vous l'enregistrez - le code ci-dessus supprime FILEcs'il existe.

Adobe
la source
0

De plus, je modifie parfois un package que je développe et oublie de le recompiler. Lorsque j'essaie de charger le nouveau fichier, il me faut du temps pour réaliser qu'Emacs utilise toujours l'ancien fichier compilé.

Puis-je suggérer d'ajouter un crochet dans votre fichier init?

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

Ou, si vous souhaitez appliquer le hook uniquement sur les fichiers el:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))
Nsukami _
la source
9
Whoah, cela essaierait de compiler des tampons, même non élisp. Pas idéal! La manière la plus robuste de le faire est d'utiliser le package de compilation automatique.
sanityinc