como fazer com que o Emacs localize o erro no meu arquivo init sem reiniciar?

7

Quando há um erro em um dos meus arquivos de inicialização, recebo uma mensagem vaga assim quando inicio o Emacs:

Warning (initialization): An error occurred while loading /Users/im/.emacs.d/init.elc:
(wrong-type-argument listp helm-find-files-actions)

Ele não me diz qual dos meus muitos arquivos de configuração contém o erro ou qual linha. Pesquisando meus arquivos não ajuda, porque, adivinhe, a função helm-find-files-actionsnão aparece em nenhum dos meus arquivos init. Para rastrear a linha de código incorreta, eu tenho que fazer $ emacs --debug-init.

Não há como o Emacs me dizer automaticamente onde está a linha ofensiva sem ter que sair e correr $ emacs --debug-init? Eu sei que posso dividir + avaliar manualmente os arquivos, mas isso é ainda mais lento. Seria muito melhor se, quando houver um erro em um dos meus arquivos de inicialização, o Emacs pudesse:

  1. diga-me qual arquivo init
  2. diga-me o número da linha que contém o erro
  3. idealmente, abra esse arquivo init e me leve para a linha ofensiva

Isso é possível com o Emacs, ou estou vivendo em um mundo de fantasia?

homem incandescente
fonte
4
Que tal ativar a depuração (sem reiniciar) avaliando (setq debug-on-error t)e depois avaliando init.elnovamente - por exemplo, abra-a e digite M-x eval-buffer.
lawlist
2
Esse parece ser um problema recorrente nas implementações do Lisp, com a notável exceção do Racket, que se encarregou de adicionar suporte aos locais de origem. Eu fiz um pequeno hack para exibir os números de linha nos backtraces , talvez isso ajude.
wasamasa
11
Talvez uma questão separada, mas gostaria de saber se há uma maneira de permitir debug-initautomaticamente para a próxima partida, sempre que as alterações de arquivo de inicialização ...
glucas
2
@glucas Nesse caso, meus emacs vai sempre começar com --debug-init:)
Kaushal Modi
Existe um motivo para nem sempre iniciar o Emacs --debug-initpor padrão?
incandescentman

Respostas:

3

Eu sei que posso dividir + avaliar manualmente os arquivos, mas isso é ainda mais lento.

Errado! Por isso, ignorarei a parte " sem relançar " do título da sua pergunta.

Isso é comum e clássico, assim como a solução: pesquisa binária . Se ativar debug-on-errore usar a opção --debug-initnão ajudar, faça o seguinte:

Divida o arquivo init de forma recursiva, para localizar um pouquinho dele que é responsável pelo problema.

Isso é tudo. A pesquisa binária é muito rápida, poderosa e simples. As pessoas muitas vezes evitam isso, pensando que podem pensar rapidamente no problema.

Para dividir seu arquivo init recursivamente:

  1. Comente metade disso. Você pode usar M-x comment-regionpara comentar a região do texto selecionado. (Você pode descomentar a região usando C-uo mesmo comando. (Por conveniência, você pode vincular comment-regiona uma chave.)

  2. Inicie o Emacs. Você viu o mesmo problema? Se sim, o problema não é causado pela parte que você comentou. Se não, então é.

  3. Para a parte problemática: comente a outra parte e metade da parte problemática.

Repita # 2 e # 3, repetidamente. Não demora muito: 1/2, 3/4, 7/8, 15/16, 31/32, 63/64, 127/128, 255/256, 511/512, 1023/1024, ...

Não importa o tamanho do seu arquivo init ou quanto outro código ele carrega (se o problema estiver em outro código, repita o mesmo processo nesse arquivo, etc.).

De fato, quanto maior a pilha de código que você está tentando pesquisar, mais a pesquisa binária ajuda.

Desenhou
fonte
Exatamente. Digamos que pesquisar 100 leva 1 minuto. Com a pesquisa binária, 100.000 linhas devem levar no máximo mais um minuto. (
Python
2

Resposta simples: basta abrir o arquivo init.el e executar um M-x eval-buffer. Eu faço isso o tempo todo para depurar arquivos init

bpaul
fonte
Acabei de ver o comentário do @ lawist acima. Permitindo a depuração antes de fazer isso é uma boa idéia
bpaul
1

Você pode simplesmente carregar seu arquivo init em um buffer e Cx Ce para avaliar cada expressão s e descobrir qual deles explode.

Eu sei que isso não é o ideal, mas se você estiver decidido a não reiniciar, é o que eu faria.

feoh
fonte