Могу ли я избежать устаревших байтовых файлов elisp?


27

Иногда, когда я запускаю Emacs, я получаю сообщение вроде

Исходный файл `/home/USER/.emacs.d/elpa/....el 'новее, чем файл, скомпилированный байтами

Кроме того, я иногда редактирую разрабатываемый пакет и забываю перекомпилировать его. Когда я пытаюсь загрузить новый файл, мне требуется время, чтобы понять, что Emacs все еще использует старый скомпилированный файл.

Есть ли способ, которым я могу сказать Emacs полностью избегать байтово скомпилированных файлов, которые старше их соответствующих исходных файлов?

Ответы:


35

Emacs 24.3 или ниже

Не существует встроенного способа предотвращения загрузки этих старых файлов, но есть простые способы избавиться от них.

  • Вы можете перекомпилировать весь каталог Elpa по телефону:
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/.
    Это должно избавиться от устаревших файлов.
  • Вы можете использовать пакет автоматической компиляции и активировать, auto-compile-on-load-modeкоторый может компилировать файлы перед их загрузкой.

Emacs 24.4

Да и получается довольно просто. load-prefer-newer Переменная служит именно этой цели.

(setq load-prefer-newer t)

К сожалению, это не будет работать, если какой-то код специально нацелен на .elcфайл, например (load "server.elc"). Но этого должно быть достаточно, если вы используете requires или звоните loadбез суффикса, что и должно быть.

Из документа:

load -fer-newer - это переменная, определенная в lread.c.
Его значение равно нулю

Документация:
Не ноль означает, что загрузка предпочитает самую новую версию файла.
Это применимо, когда суффикс имени файла не указан явно, а load пытается использовать различные возможные суффиксы (см. Load-суффиксы и load-file-rep-суффиксы). Обычно он останавливается на первом существующем файле, если вы явно не укажете один или другой. Если этот параметр не ноль, он проверяет все суффиксы и использует тот файл, который является самым новым.
Обратите внимание, что если вы настроите это, очевидно, что это не повлияет на файлы, которые загружаются до прочтения ваших настроек!


1
Я призываю людей использовать (превосходную!) auto-compileБиблиотеку в Emacs 24.4+, а также ниже. Это реальное решение «сконфигурируй и забудь». load-prefer-newerтолько гарантирует, что вы продолжите выполнять медленный не скомпилированный код после того, как ваш скомпилированный код устареет.
Филс

1
@phils В настоящее время байт-код не намного быстрее, чем простой исходный код, благодаря стремительному расширению макросов.
lunaryorn

Изменения, которые я внес в стратегию сортировки по повестке дня (в org -nda.el), не были отражены после перезапуска, но перекомпиляция файлов .elc, как описано в ответе, решила проблему.
Earlio

17

Если вы установите только load-prefer-newer(где доступно), будет загружен правильный код, но он может быть не скомпилирован байтовым, поэтому может быть небольшое снижение производительности.

Вы можете использовать превосходную библиотеку автокомпиляции Джонаса Бернулли, чтобы убедиться, что эта проблема не возникает. В частности, auto-compile-on-load-modeбудут перекомпилированы устаревшие .elcфайлы перед их загрузкой.


3

Я встретил это в Интернете давно:

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

если вы работаете FILEв emacs-lisp-mode и сохраняете его - приведенный выше код удаляет, FILEcесли он существует.


0

Кроме того, я иногда редактирую разрабатываемый пакет и забываю перекомпилировать его. Когда я пытаюсь загрузить новый файл, мне требуется время, чтобы понять, что Emacs все еще использует старый скомпилированный файл.

Могу ли я предложить добавить хук в вашем файле инициализации?

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

Или, если вы хотите применить ловушку только к файлам el:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))

9
Ого, это попыталось бы скомпилировать байты даже не-elisp-буферов. Не идеально! Надежный способ сделать это с помощью пакета автоматической компиляции.
sanityinc
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.