Posso evitar arquivos elisp desatualizados compilados por bytes?

27

Ocasionalmente, quando inicio o Emacs, recebo uma mensagem como.

Arquivo de origem `/home/USER/.emacs.d/elpa/....el 'mais recente que o arquivo compilado em bytes

Além disso, às vezes edito um pacote que estou desenvolvendo e esqueço de recompilá-lo. Quando tento carregar o novo arquivo, levo um tempo para perceber que o Emacs ainda está usando o antigo arquivo compilado.

Existe uma maneira de dizer ao Emacs para evitar completamente os arquivos compilados em bytes mais antigos que seus respectivos arquivos de origem?

Malabarba
fonte

Respostas:

35

Emacs 24.3 ou inferior

Não existe uma maneira integrada de impedir que esses arquivos antigos sejam carregados, mas existem maneiras fáceis de se livrar deles.

  • Você pode recompilar todo o diretório ELPA chamando:
    M-x byte-recompile-directory RET ~/.emacs.d/elpa/.
    Isso deve se livrar de arquivos desatualizados.
  • Você pode usar o pacote de compilação automática e ativar os auto-compile-on-load-modearquivos que podem compilar antes de serem carregados.

Emacs 24.4

Sim, e acaba sendo bastante simples. A load-prefer-newer variável serve exatamente a esse propósito.

(setq load-prefer-newer t)

Infelizmente, não funcionará quando algum código segmentar especificamente o .elcarquivo, como (load "server.elc"). Mas deve ser o suficiente, desde que você esteja usando requires ou chamando loadsem sufixo, o que você deveria.

Do documento:

load-prefer-newer é uma variável definida em lread.c.
Seu valor é nulo

Documentação:
Não nulo significa que o carregamento prefere a versão mais recente de um arquivo.
Isso se aplica quando um sufixo de nome de arquivo não é especificado explicitamente e o load está tentando vários sufixos possíveis (consulte load-sufixos e load-file-rep-sufixos). Normalmente, ele pára no primeiro arquivo que existe, a menos que você especifique explicitamente um ou outro. Se essa opção for diferente de zero, ele verifica todos os sufixos e usa o arquivo que for mais recente.
Observe que, se você personalizar isso, obviamente isso não afetará os arquivos carregados antes da leitura de suas personalizações!

Malabarba
fonte
11
Eu auto-compileinstaria as pessoas a usar a biblioteca (excelente!) No Emacs 24.4+, assim como abaixo. É uma verdadeira solução para configurar e esquecer. load-prefer-newersó garante que você continue executando o código descompilado lento depois que seu código compilado ficar desatualizado.
Phd #
11
Atualmente, o código de bytes não é muito mais rápido que o código-fonte simples, graças à grande expansão de macros.
lunaryorn
As alterações que fiz na estratégia de classificação da agenda organizacional (em org-agenda.el) não foram refletidas após uma reinicialização, mas a recompilação dos arquivos .elc, conforme descrito na resposta, resolveu o problema.
Inicio
17

Se você definir apenas load-prefer-newer(quando disponível), o código correto será carregado, mas pode não ter sido compilado por bytes, portanto, pode haver uma pequena penalidade no desempenho.

Você pode usar a excelente biblioteca de compilação automática de Jonas Bernoulli para garantir que esse problema não ocorra. Em particular, auto-compile-on-load-moderecompilará os .elcarquivos desatualizados antes de carregá-los.

sanityinc
fonte
3

Eu conheci isso na Internet há muito tempo:

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

se você trabalha FILEno modo emacs-lisp e o salva - o código acima será removido, FILEcse existir.

Adobe
fonte
0

Além disso, às vezes edito um pacote que estou desenvolvendo e esqueço de recompilá-lo. Quando tento carregar o novo arquivo, levo um tempo para perceber que o Emacs ainda está usando o antigo arquivo compilado.

Posso sugerir adicionar um gancho no seu arquivo init?

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

Ou, se você deseja aplicar o gancho apenas nos arquivos el:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))
Nsukami _
fonte
9
Whoah, isso tentaria compilar byte mesmo buffers não elisp. Não é ideal! A maneira robusta de fazer isso é com o pacote de compilação automática.
sanityinc 25/09/14