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

27

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

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

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

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

Malabarba
источник

Ответы:

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-суффиксы). Обычно он останавливается на первом существующем файле, если вы явно не укажете один или другой. Если этот параметр не ноль, он проверяет все суффиксы и использует тот файл, который является самым новым.
Обратите внимание, что если вы настроите это, очевидно, что это не повлияет на файлы, которые загружаются до прочтения ваших настроек!

Malabarba
источник
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файлы перед их загрузкой.

sanityinc
источник
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