Wie kann ich Emacs dazu bringen, den Fehler in meiner Init-Datei zu finden, ohne ihn neu zu starten?

7

Wenn in einer meiner Init-Dateien ein Fehler auftritt, wird beim Starten von Emacs eine vage Meldung wie diese angezeigt:

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

Es sagt mir nicht, welche meiner vielen Konfigurationsdateien den Fehler enthält oder welche Zeile. Das Durchsuchen meiner Dateien hilft nicht weiter, da die Funktion helm-find-files-actionsin keiner meiner Init-Dateien angezeigt wird. Um die fehlerhafte Codezeile aufzuspüren, muss ich tun $ emacs --debug-init.

Gibt es keine Möglichkeit, Emacs dazu zu bringen, mir automatisch zu sagen, wo sich die betreffende Leitung befindet, ohne dass ich beenden und laufen muss $ emacs --debug-init? Ich weiß, dass ich die Dateien manuell halbieren und auswerten kann, aber das ist noch langsamer. Es wäre viel besser, wenn Emacs bei einem Fehler in einer meiner Init-Dateien Folgendes tun könnte:

  1. Sag mir welche Init-Datei
  2. Sagen Sie mir die Zeilennummer, die den Fehler enthält
  3. Öffnen Sie im Idealfall diese Init-Datei und bringen Sie mich zur betreffenden Zeile

Ist das mit Emacs möglich oder lebe ich in einer Fantasiewelt?

Glühlampenmann
quelle
4
Wie wäre es, wenn Sie das Debuggen (ohne Neustart) aktivieren, indem Sie es auswerten (setq debug-on-error t)und dann erneut auswerten init.el- z. B. öffnen und eingeben M-x eval-buffer.
Lawlist
2
Dies scheint ein wiederkehrendes Problem bei Lisp-Implementierungen zu sein, mit der bemerkenswerten Ausnahme von Racket, das dafür gesorgt hat, dass die Unterstützung für Quellspeicherorte hinzugefügt wird. Ich habe einen kleinen Hack ausgeführt, um Zeilennummern in Backtraces anzuzeigen , vielleicht hilft das.
Wasamasa
1
Vielleicht eine separate Frage, aber ich frage mich, ob es eine Möglichkeit gibt, debug-initautomatisch für den nächsten Start zu aktivieren, wenn sich Ihre Init-Datei ändert ...
Glucas
2
@glucas In diesem Fall beginnen meine Emacs immer mit --debug-init:)
Kaushal Modi
Gibt es einen Grund, Emacs nicht immer --debug-initstandardmäßig mit zu starten ?
Glühlampen

Antworten:

3

Ich weiß, dass ich die Dateien manuell halbieren und auswerten kann, aber das ist noch langsamer.

Falsch! Daher werde ich den Teil Ihres Fragentitels " ohne Neustart " ignorieren .

Dies ist üblich und klassisch, ebenso wie die Lösung: binäre Suche . Wenn das Einschalten debug-on-errorund Verwenden der Option --debug-initnicht hilft, gehen Sie folgendermaßen vor:

Halbieren Sie Ihre Init-Datei rekursiv, um das winzige Stück davon zu finden, das für das Problem verantwortlich ist.

Das ist alles. Die binäre Suche ist sehr schnell, leistungsstark und einfach. Die Leute meiden es zu oft und denken, dass sie sich schneller durch das Problem denken können.

So rekursieren Sie Ihre Init-Datei rekursiv:

  1. Kommentiere die Hälfte davon aus. Sie können M-x comment-regionden Bereich des ausgewählten Textes auskommentieren. (Sie können die Region C-umit demselben Befehl auskommentieren . (Zur Vereinfachung können Sie eine Bindung comment-regionan einen Schlüssel vornehmen.)

  2. Starten Sie Emacs. Hast du das gleiche Problem gesehen? Wenn ja, wird das Problem nicht durch den Teil verursacht, den Sie auskommentiert haben. Wenn nein, dann ist es.

  3. Für den problematischen Teil: Kommentieren Sie den anderen Teil und die Hälfte des problematischen Teils aus.

Wiederholen Sie # 2 und # 3 immer und immer wieder. Es dauert nicht lange: 1/2, 3/4, 7/8, 15/16, 31/32, 63/64, 127/128, 255/256, 511/512, 1023/1024, ...

Es spielt keine Rolle, wie groß Ihre Init-Datei ist oder wie viel anderen Code sie lädt (wenn das Problem in einem anderen Code liegt, wiederholen Sie den gleichen Vorgang für diese Datei usw.).

Je größer der Codestapel ist, den Sie suchen, desto mehr binäre Suche hilft Ihnen.

Drew
quelle
Genau. Angenommen, die Suche nach 100 dauert 1 Minute. Bei der binären Suche sollten 100.000 Zeilen höchstens eine weitere Minute dauern. (Geben oder Nehmen)
PythonNut
2

Einfache Antwort: Öffnen Sie einfach Ihre init.el-Datei und führen Sie eine aus M-x eval-buffer. Ich mache das die ganze Zeit, um Init-Dateien zu debuggen

bpaul
quelle
Ich habe gerade den Kommentar von @ lawist oben gesehen. Das Aktivieren des Debuggens ist eine gute Idee
bpaul
1

Sie können einfach Ihre Init-Datei in einen Puffer und Cx Ce laden, um jeden S-Ausdruck auszuwerten und herauszufinden, welcher explodiert.

Ich weiß, dass das nicht ideal ist, aber wenn Sie gegen einen Neustart sind, würde ich das tun.

feoh
quelle