Làm cách nào để nhận Emacs xác định vị trí lỗi trong tệp init của tôi mà không khởi chạy lại?


7

Khi có lỗi trong một trong các tệp init của tôi, tôi nhận được một thông báo mơ hồ như thế này khi tôi khởi chạy Emacs:

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

Nó không cho tôi biết tập tin cấu hình nào trong số nhiều tệp cấu hình của tôi có lỗi hoặc dòng nào. Tìm kiếm các tệp của tôi không giúp được gì vì đoán xem, hàm helm-find-files-actionsnày thực sự không xuất hiện trong bất kỳ tệp init nào của tôi. Để theo dõi dòng mã vi phạm, tôi phải làm $ emacs --debug-init.

Có cách nào để Emacs tự động cho tôi biết đường dây vi phạm ở đâu mà không phải thoát ra và chạy $ emacs --debug-initkhông? Tôi biết tôi có thể chia đôi + eval các tệp theo cách thủ công nhưng thậm chí còn chậm hơn. Sẽ tốt hơn rất nhiều nếu, khi có lỗi trong một trong các tệp init của tôi, Emacs có thể:

  1. cho tôi biết tập tin init nào
  2. cho tôi biết số dòng có lỗi
  3. lý tưởng nhất là mở tập tin init đó và đưa tôi đến dòng vi phạm

Điều này có thể xảy ra với Emacs, hay tôi đang sống trong một thế giới giả tưởng?


4
Làm thế nào về việc kích hoạt gỡ lỗi (mà không khởi chạy lại) bằng cách đánh giá (setq debug-on-error t)và sau đó đánh giá init.ellại của bạn - ví dụ: mở nó lên và gõ M-x eval-buffer.
luật

2
Đây dường như là một vấn đề lặp đi lặp lại trong việc triển khai Lisp với ngoại lệ đáng chú ý là Vợt đã chăm sóc thêm hỗ trợ cho các vị trí nguồn. Tôi đã thực hiện một hack nhỏ để hiển thị số dòng trong backtraces , có lẽ điều đó có ích.
wasamasa

1
Có lẽ là một câu hỏi riêng biệt, nhưng tôi tự hỏi liệu có cách nào để debug-inittự động kích hoạt cho lần bắt đầu tiếp theo bất cứ khi nào tệp init của bạn thay đổi không ...
glucas

2
@glucas Trong trường hợp đó, emacs của tôi sẽ luôn bắt đầu với --debug-init:)
Kaushal Modi

Có một lý do để không luôn luôn khởi chạy Emacs --debug-inittheo mặc định?
sợi đốt

Câu trả lời:


3

Tôi biết tôi có thể chia đôi + eval các tệp theo cách thủ công nhưng thậm chí còn chậm hơn.

Sai lầm! Vì vậy, tôi sẽ bỏ qua phần " không khởi động lại " trong tiêu đề câu hỏi của bạn.

Điều này là phổ biến và cổ điển, như là giải pháp: tìm kiếm nhị phân . Nếu bật debug-on-errorvà sử dụng tùy chọn --debug-initkhông giúp ích, thì hãy làm điều này:

Khai thác tệp init của bạn một cách đệ quy, để xác định vị trí nhỏ của nó chịu trách nhiệm cho vấn đề.

Đó là tất cả. Tìm kiếm nhị phân rất nhanh chóng, mạnh mẽ và đơn giản. Mọi người thường tránh nó, nghĩ rằng họ có thể nghĩ cách giải quyết vấn đề nhanh hơn.

Để chia đôi tệp init của bạn một cách đệ quy:

  1. Nhận xét một nửa của nó. Bạn có thể sử dụng M-x comment-regionđể nhận xét khu vực của văn bản đã chọn. (Bạn có thể bỏ ghi chú khu vực bằng cách sử dụng C-ucùng một lệnh. (Để thuận tiện, bạn có thể liên kết comment-regionvới một khóa.)

  2. Bắt đầu Emacs. Bạn có thấy vấn đề tương tự không? Nếu có, thì vấn đề không phải do phần bạn nhận xét. Nếu không, thì nó là.

  3. Đối với phần có vấn đề: Nhận xét phần khác và một nửa phần có vấn đề.

Lặp lại # 2 và # 3, hơn và hơn. Sẽ không mất nhiều thời gian: 1/2, 3/4, 7/8, 15/16, 31/32, 63/64, 127/128, 255/256, 511/512, 1023/1024, ...

Không quan trọng tệp init của bạn lớn đến mức nào hoặc tải bao nhiêu mã khác (nếu sự cố nằm ở mã khác thì lặp lại quy trình tương tự trên tệp đó, v.v.).

Nếu thực tế, đống mã bạn đang cố gắng tìm kiếm càng lớn thì tìm kiếm nhị phân càng giúp bạn.


Chính xác. Nói tìm kiếm 100 mất 1 phút. Với tìm kiếm nhị phân, tối đa 100.000 dòng chỉ mất một phút. (Cho hoặc nhận)
PythonNut 16/07/2015

2

Câu trả lời đơn giản: Chỉ cần mở tệp init.el của bạn và làm một M-x eval-buffer. Tôi làm điều này tất cả thời gian để gỡ lỗi các tập tin init


Chỉ cần thấy bình luận của @ lawist ở trên. Cho phép gỡ lỗi trước khi thực hiện việc này là một ý tưởng hay
bpaul

1

Bạn chỉ có thể tải tệp init của mình lên trong bộ đệm và Cx Ce để đánh giá từng biểu thức s và tìm ra cái nào sẽ nổ tung.

Tôi biết điều đó không lý tưởng nhưng nếu bạn chết vì không khởi động lại thì đó là điều tôi sẽ làm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.