ฉันสามารถหลีกเลี่ยงไฟล์ elisp ที่ล้าสมัยแล้วได้หรือไม่?


27

บางครั้งเมื่อฉันเริ่ม Emacs ฉันได้รับข้อความเช่น

ซอร์สไฟล์ `/home/USER/.emacs.d/elpa/....el 'ใหม่กว่าไฟล์ที่คอมไพล์ด้วยไบต์

นอกจากนี้บางครั้งฉันแก้ไขแพ็คเกจที่ฉันกำลังพัฒนาและลืมคอมไพล์ใหม่ เมื่อฉันพยายามโหลดไฟล์ใหม่ฉันต้องใช้เวลาสักครู่กว่าจะรู้ว่า Emacs ยังคงใช้ไฟล์ที่คอมไพล์เก่าอยู่

มีวิธีที่ฉันสามารถบอกให้ Emacs หลีกเลี่ยงไฟล์ที่คอมไพล์ด้วยไบต์ที่เก่ากว่าไฟล์ต้นฉบับที่เกี่ยวข้องหรือไม่?

คำตอบ:


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")แต่ควรเพียงพอตราบเท่าที่คุณใช้requireหรือโทรloadโดยไม่มีคำต่อท้ายซึ่งคุณควร

จากเอกสาร:

load-prefer-newer เป็นตัวแปรที่กำหนดไว้ใน lread.c
ค่าของมันคือศูนย์

เอกสารประกอบ:
Non-nil หมายถึงการโหลดที่ต้องการไฟล์เวอร์ชันใหม่ล่าสุด
สิ่งนี้ใช้เมื่อไม่ได้ระบุส่วนต่อท้ายของชื่อไฟล์อย่างชัดเจนและโหลดกำลังพยายามใช้คำต่อท้ายที่เป็นไปได้ต่างๆ (ดูที่ส่วนต่อท้ายของโหลดและโหลดของไฟล์ - ตัวแทนต่อท้าย) โดยปกติจะหยุดที่ไฟล์แรกที่มีอยู่เว้นแต่คุณจะระบุอย่างใดอย่างหนึ่งหรืออื่น ๆ หากตัวเลือกนี้ไม่ใช่ศูนย์จะตรวจสอบคำต่อท้ายทั้งหมดและใช้ไฟล์ใดก็ตามที่ใหม่ที่สุด
โปรดทราบว่าหากคุณกำหนดค่านี้จะไม่ส่งผลกระทบต่อไฟล์ที่โหลดก่อนการปรับแต่งของคุณ


1
ฉันอยากให้ผู้คนใช้auto-compileห้องสมุด(ยอดเยี่ยม!) ใน Emacs 24.4+ รวมถึงด้านล่าง มันเป็นโซลูชันการกำหนดค่าและลืมที่แท้จริง load-prefer-newerให้แน่ใจว่าคุณจะเรียกใช้รหัสที่ไม่ได้คอมไพล์ช้าหลังจากที่คอมไพล์โค้ดของคุณล้าสมัย
phils

1
@phils ทุกวันนี้โค้ดไบต์ไม่ได้เร็วกว่าซอร์สโค้ดธรรมดามากเท่าไหร่ขอบคุณการขยายมาโครที่กระตือรือร้น
Lunaryorn

การเปลี่ยนแปลงที่ฉันทำกับ org-Agenda-sorting-strategy (ใน org-Agenda.el) ไม่ได้ถูกสะท้อนหลังจากการรีสตาร์ท แต่การคอมไพล์ไฟล์. elc ใหม่ตามที่อธิบายในคำตอบช่วยแก้ปัญหาได้
earlio

17

หากคุณตั้งค่าไว้load-prefer-newer(หากมี) รหัสที่ถูกต้องจะถูกโหลด แต่อาจไม่ได้รับการคอมไพล์ด้วยไบต์ดังนั้นอาจมีการปรับประสิทธิภาพเล็กน้อย

คุณสามารถใช้ไลบรารีการรวบรวมอัตโนมัติที่ยอดเยี่ยมของ Jonas Bernoulli เพื่อช่วยให้แน่ใจว่าปัญหานี้จะไม่เกิดขึ้น โดยเฉพาะอย่างยิ่งauto-compile-on-load-modeจะคอมไพล์.elcไฟล์ที่ล้าสมัยก่อนที่จะโหลด


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

หากคุณทำงานกับFILEemacs-lisp-mode และคุณบันทึกไว้ - โค้ดด้านบนจะลบFILEcหากมีอยู่


0

นอกจากนี้บางครั้งฉันแก้ไขแพ็คเกจที่ฉันกำลังพัฒนาและลืมคอมไพล์ใหม่ เมื่อฉันพยายามโหลดไฟล์ใหม่ฉันต้องใช้เวลาสักครู่กว่าจะรู้ว่า Emacs ยังคงใช้ไฟล์ที่คอมไพล์เก่าอยู่

ฉันขอแนะนำให้เพิ่มตะขอในไฟล์ init ของคุณได้ไหม

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

หรือถ้าคุณต้องการใช้ hook เฉพาะกับไฟล์ el:

(add-hook 'emacs-lisp-mode-hook (lambda () (add-hook 'after-save-hook 'byte-compile-current-buffer nil t)))

9
อ๊ะนั่นจะพยายามรวบรวมไบต์แม้แต่บัฟเฟอร์ที่ไม่ใช่ elisp ไม่เหมาะ! วิธีที่แข็งแกร่งในการทำเช่นนี้คือด้วยแพ็คเกจการรวบรวมอัตโนมัติ
sanityinc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.